using httr POST in R to authenticate towards API REST - html

I am trying to make an autentication from R into a demo account that is using API REST and json.
Based on input from user, I have now digged into the httr and POST details and my code looks like this. When I look into the details it seems that the webclient test i perform is identical but the identfier and password is being sent in with " ". I have checked the documentation for httr, POST and body, but do not find that "" can be used where I need it. Any suggestions?.
POST (
url = "https://demo-api.ig.com/gateway/deal/session",
add_headers(
"X-IG-API-KEY" = "xxx",
"VERSION" = "2",
"X-SECURITY-TOKEN" = "xxx",
"CST" = "xxx",
"Content-Type" = "application/json; charset=UTF-8",
"Accept" = "application/json; charset=UTF-8"),
body = "{identifier: xxx, password: xxx}",
verbose())

Helping you read documentation is out of the scope of SO questions. You made a number of API call mistakes according to the docs and your POST was not formatted properly as well. I'm not really posting this as an answer, per-se, but it's impossible to show a code snippet this large in a comment.
You should also study up on and practice httr calls before attempting something like this in the future.
POST(url="https://demo-api.ig.com/gateway/deal/session",
encode="json",
accept_json(),
add_headers(`X-IG-API-KEY`="[xxx]",
`VERSION`="2",
`X-SECURITY-TOKEN`="[xxx]"),
body=list(identifier="[xxx]",
password="[xxx]")

Related

Not able to capture previous API response and append the response in URL of Post Request API

I am trying to POST API request where I am getting API response as
"d": {
"__metadata": {
"uri": "http://ev-qa02.zs.local/IncentiveManager/0002i1/wcf/v5.svc/InDataRequestCreators('9f31c6da-ec56-4360-8589-d21b6320f99b')",
"type": "ZSAssociates.Javelin.ETL.Rest.v5.InDataRequestCreator"
},
"ScenarioId": "9f31c6da-ec56-4360-8589-d21b6320f99b",
"CallbackUrl": "",
"DataExpiresOnUtc": "/Date(4103913600000)/",
"CreateScenarioIfMissing": false,
"AdapterId": "0fcbd8d2-f5cb-4e2a-bda8-bb37037b022d",
"InDataRequestIdOut": "eb36f8a9-5b7d-4835-88f6-4af67830c1e9",
"InDataRequestUrlOut": "/InDataRequests('eb36f8a9-5b7d-4835-88f6-4af67830c1e9')"
}
}
Now I am trying to hit another API request where my URL would be kind of
http://ev-qa02.zs.local/IncentiveManager/0002i1/WCF/V5.svc/InDataRequests('eb36f8a9-5b7d-4835-88f6-4af67830c1e9')/FileCreator
*InDataRequests('eb36f8a9-5b7d-4835-88f6-4af67830c1e9') This random number is generated from above response value "InDataRequestIdOut"
How can I append the URL taking previous API response and adding in my 2nd POST request.
I am not able to capture my response and used it in other API POST request? i would realy appreciate if you can help me here,been stuck in this issue since couple of days,I went through doc and examples too but couldn't resolve this.I have attached screenshot too.PostUrlFailureScreenshot
My main problem is line number 26 and 27 from eclipe screenshot
Scenario: Verify that JIM Idr request ofr Post
Given header Content-Type = 'Application/JSON'
And header Accept = 'Application/JSON'
And header Authorization = 'Basic
UUEwMl9JbmNlbnRpdmVNYW5hZ2VyXzAwMDJpMTpZWkxaRjlGclR1eWhlcVNJbXlkTlBR'
Given path 'InDataRequestCreators'
* def user =
"""
{
"ScenarioId":"9f31c6da-ec56-4360-8589-d21b6320f99b",
"AdapterId":"0fcbd8d2-f5cb-4e2a-bda8-bb37037b022d",
"DataExpiresOnUtc":"2100-01-18T00:00:00",
"CreateScenarioIfMissing":"false"
}
"""
And request user
When method post
Then status 201
* print 'the value of response is:', response
And def app = response
And path 'app.InDataRequestIdOut' + '/FileCreators'
* def body =
"""
{
"InDataRequestId": "1d6326a2-d25f-41d2-9303-8a6e6101efcc",
"ProcedureName": "",
"SourceWorkspacePath": ""
}
"""
And request body
When method post
Then status 201
First, it looks to me you are using the wrong Eclipse plugin for Cucumber, please refer to this issue and make sure: https://github.com/intuit/karate/issues/90
There are so many things you are doing wrong. For example it should be application/json (lowercase). There are many places you are mixing upper case and lower case in your above description, please take care.
And there is no way to understand how the URL is being set up, without this - I can't provide proper help.
You have a fundamental misunderstanding of how to use Karate expressions, for example this is just concatenating two strings:
And path 'app.InDataRequestIdOut' + '/FileCreators'
This may give you some hints, instead of the above:
When url baseUrl
And path "InDataRequests('" + response.InDataRequestIdOut + "')/FileCreator"
And is it FileCreator or FileCreators. You seem to be quite careless :(

JSON encoding error publishing SNS message with Boto 3

I am trying to send a simple JSON message to an Amazon SNS topic in Boto 3. However, I keep getting a _jsonparsefailure in the tag of the message and I only receive the default value. Here is my code:
mess = {'default': 'default', 'this': 'that'}
jmess = json.JSONEncoder().encode(mess)
response = self.boto_client.publish(
TopicArn = self.TopicArn,
MessageStructure = 'json',
Message = jmess
)
I have also tried json.dumps(), which produces the same result.
mess = {'default': 'default', 'this': 'that'}
jmess = json.dumps(mess)
response = self.boto_client.publish(
TopicArn = self.TopicArn,
MessageStructure = 'json',
Message = jmess
)
I seem to be following all of the guidelines set by the documentation, and I'm not getting an exception when I run the script. There are SQS queues that subscribe to the topic, and I am pulling the result data straight from the console.
This is how I fixed it:
message = {"record_id": "my_id", "name": "value"}
json_message = json.dumps({"default":json.dumps(message)})
sns_client.publish("topic_arn", Subject="test", MessageStructure="json", Message=json_message)
SNS expects "default" as the key which contains the message to be published.
It turns out the message needs to look like this:
json.dumps({"default": "my default", "sqs": json.dumps({"this": "that"})})
Amazon has horrible documentation in this regard.
You can also remove the MessageStructure='json'and send just json.dumps({'this':'that'}) if you set the SQS queue to receive just the raw message. This is simply done through the console.
In Boto 3 (I'm using v1.4.7) this is the format:
sns.publish(TopicArn="topic_arn", Message=json.dumps({"this": "that"},ensure_ascii=False))
There isn't any need for the protocol definition, i.e. "default" unless you are delivering different structures per protocol, i.e., JSON for Lambda and HTML for email.

Google Apps Script UrlFetchApp isn't encoding a JSON array correctly

I've looked everywhere and can't find this issue. I've come over from PeopleSoft to .NET and have only recently began learning JavaScript and I'm attempting to use Google Apps Script to send email notification messages to Slack.
It appears to me that GAS's UrlFetchApp isn't handling an array correctly. Below I didn't include all the Slack API options for clarity. Here how I constructed the payload, where 'attachments' contains the array in question:
var payload =
{
// ...
"username": "Test webhook Bot",
"attachments": [
{
"pretext": "pre-hello1",
"text": "text-world1"
},
{
"pretext": "pre-hello2",
"text": "text-world2"
}
]
// ...
};
var options =
{
"method" : "post",
"payload" : payload,
"contentType":"application/json"
};
var response = UrlFetchApp.fetch(requestURL, options);
When testing I found that the post was occuring but Slack was ignoring the attachments portion of the message. I used the following to examine the outgoing POST:
var response = UrlFetchApp.getRequest(requestURL, options);
And what I found looking at the execution transcript I find that the JSON array in my payload isn't being encoded the way I expected. Before execution, I clearly see the properly formatted array.
[16-01-26 07:26:39:050 MST] UrlFetchApp.getRequest([https://slack.com/api/chat.postMessage?, {method=post, payload={attachments=[{pretext=pre-hello1, text=text-world1}, {pretext=pre-hello2, text=text-world2}], username=Test webhook Bot}, contentType=application/json}]) [0 seconds]
But what is actually sent, in place of the attachments array is: %5BLjava.lang.Object;#37f01fb3
[16-01-26 07:26:39:051 MST] Logger.log([Test:https://slack.com/api/chat.postMessage?attachments=%5BLjava.lang.Object;#37f01fb3&username=Test+webhook+Bot, []]) [0 seconds]
I tried searching this out as much as I could before asking for help, but I'm not sure if I'm either loss. Does anyone know where I may look to find out what I'm missing? Thanks.
To the extent that this information is helpful almost 4 years out, I've been running into the same problem and here's the solution I came up with:
- I will be including all relevant information encoded in the URL JSON structure
- The "options" portion of the UrlFetchApp is then just specifying the method and contentType
An example would look like this:
var url = "https://slack.com/api/chat.postMessage?token=the-token-here&channel=channel_id_here&text=hello%20world";
var options = {
"method": "post",
"contentType": "application/json",
};
return UrlFetchApp.fetch(url,options);
}
I also got some more helpful information at this Stack Overflow thread.
I think this is the Slack API documentation that helps explain the constraints:
JSON-encoded bodies
For these write methods, you may alternatively send your HTTP POST
data as Content-type: application/json.
There are some ground rules:
You must explicitly set the Content-type HTTP header to
application/json. We won't interpret your POST body as such without
it. You must transmit your token as a bearer token in the
Authorization HTTP header. You cannot send your token as part of the
query string or as an attribute in your posted JSON. Do not mix
arguments between query string, URL-encoded POST body, and JSON
attributes. Choose one approach per request. Providing an explicitly
null value for an attribute will result in whichever default behavior
is assigned to it.
Based on a comment I received from a Google Drive Help Forum discussion , I wanted to pass on more information on what I found regarding the use of JSON.stringify() in creating my Slack request. I modified my options JSON
var options = {
'method': 'post',
'payload': JSON.stringify(payload)
};
Google then interprets the 'attachments' array correctly when constructing the request and I no longer see the java.lang.Object error.
Additional lessons learned: prior to using JSON.stringify() Slack would let me post using my personal developer token as part of the payload. Once I began using JSON.stringify() Slack would not accept my personal token nor could I pass a channel parameter. This resulted in me creating a Slack Incoming Webhook direct to the channel I wanted. I haven't tracked down why that would be the case. It may be in Slack's documentation somewhere, I just haven't had time to look yet.

Pivotal Tracker API Labels

I am trying to use the Pivotal Tracker API to post a story using python. I am able to do so using the python requests module. The following is a sample code that I can use to create a new story:
payload = {"name":"Create story w/create label"}
requests.post('https://www.pivotaltracker.com/services/v5/projects/xxxxxx/stories', data=payload4, headers={'X-TrackerToken':token}).json()
for which the output is
{u'created_at': u'2015-03-04T18:47:28Z',
u'current_state': u'unscheduled',
u'id': xxxxxx,
u'kind': u'story',
u'labels': [],
u'name': u'Create story w/create label',
u'owner_ids': [],
u'project_id': xxxxxx,
u'requested_by_id': xxxxxx,
u'story_type': u'feature',
u'updated_at': u'2015-03-04T18:47:28Z',
u'url': u'https://www.pivotaltracker.com/story/show/xxxxxx'}
Great. Now, I want to create a story and add a label to it. According to the POST /projects/{project_id}/stories API on https://www.pivotaltracker.com/help/api/rest/v5, I should be able to format my json as follows and run a POST request:
payload = {"name":"Create story w/create label","labels":[{"name":"orbit"}]}
requests.post('https://www.pivotaltracker.com/services/v5/projects/xxxxxx/stories', data=payload, headers={'X-TrackerToken':token}).json()
however, I get the following 400 response:
{u'code': u'invalid_parameter',
u'error': u'One or more request parameters was missing or invalid.',
u'general_problem': u"'labels' must be an array of label values",
u'kind': u'error'}
From what I understand, the way I formatted the payload json is correct and the label resource json is formatted properly. I'm not sure if the error is on my end or if it is something else. If someone with knowledge of the API could provide some help, it would be much appreciated.
Thanks
Solved it, there' s a JSON encoding issue. We never told pivotal tracker that we were sending JSON. This code snippet works:
data = {
"labels": ["major request"],
"name": "some cool feature",
"description": "solve world hunger",
"comments": ["requested by not the 1%"]
}
headers = {'X-TrackerToken': TRACKER_TOKEN,
'Content-type': 'application/json',
'Accept': 'application/json'
}
return requests.post(url, headers=headers, data=json.dumps(data))
Need to tell the API that we are sending JSON and accepting JSON.

How do you cancel a PayPal subscription through their api?

On this page:
https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ECRecurringPayments
it says that it's possible to cancel a PayPal subscription using their API. Knowing the SubscriptionId can anyone give me some code example how to do this?
Many thanks.
Did you manage to find an easy solution ? I'm looking for this as well. Thanks!
Update : After searching, the "ManageRecurringPaymentsProfileStatus" is very easy to use through a simple POST request.
Make sure that your user, password or signature are not visible (in other words, do this on your server and NOT on your client via javascript or html posts).
Below a simple working example in Python. It works and I'm now using it daily.
import urllib
from google.appengine.api import urlfetch
form_fields = {
"METHOD": "ManageRecurringPaymentsProfileStatus",
"PROFILEID": "xxx", # put your subscription ID here
"ACTION": "cancel",
"USER": "xxx", # Get USER, PWD, and SIGNATURE from your Paypal's account preferences
"PWD": "xxx",
"SIGNATURE": "xxx",
"VERSION": "54.0"
}
api_url = 'https://api-3t.sandbox.paypal.com/nvp' # remove the sandbox part for production
form_data = urllib.urlencode(form_fields)
result = urlfetch.fetch(url=api_url,
payload=form_data,
method=urlfetch.POST,
headers={'Content-Type': 'application/x-www-form-urlencoded'})
The response is a string that looks like this:
TIMESTAMP=2011%2d01%2d28T14%3a47%3a45Z&CORRELATIONID=148ebe1d25566&ACK=Failure&VERSION=54%2e0&BUILD=1704252&L_ERRORCODE0=11552&L_SHORTMESSAGE0=Invalid%20profile%20ID&L_LONGMESSAGE0=The%20profile%20ID%20is%20invalid&L_SEVERITYCODE0=Error
The 'ACK' field indicates 'Failure' or 'Success'.
In answer to comments below, note that it DOES enable me to cancel the subscriptions that have been created through a dynamically created link such as :
Subscribe
Note that I do not use the flag 'modify' at all.