I need to send a request with the following data
"order": {
"server_callback_url": "http://site.id/callback",
"currency": "UAH",
"amount": "1400",
"order_type": "settlement",
"response_url": "http://site.id/test/responsepage/",
"order_id": "test1234561467462099.19",
"operation_id": "test1234561467462099.19",
"order_desc": "test order",
"merchant_id": 700001,
"receiver": [
{
"requisites": {
"amount": 100,
"merchant_id": 500001
},
"type": "merchant"
},{
"requisites": {
"amount": 200,
"merchant_id": 600001
},
"type": "merchant"
},
]
}
I need to send them to https://api.fondy.eu/api/settlement
But I never did that. I am not familiar with DRF at all. Tell me how to implement it, please.
If we visit the endpoint, it says that only POST methods are allowed. We can make a POST request for example with the requests package.
import requests
data = {
"order": {
"server_callback_url": "http://site.id/callback",
"currency": "UAH",
"amount": "1400",
"order_type": "settlement",
"response_url": "http://site.id/test/responsepage/",
"order_id": "test1234561467462099.19",
"operation_id": "test1234561467462099.19",
"order_desc": "test order",
"merchant_id": 700001,
"receiver": [
{
"requisites": {
"amount": 100,
"merchant_id": 500001
},
"type": "merchant"
},{
"requisites": {
"amount": 200,
"merchant_id": 600001
},
"type": "merchant"
},
]
}
}
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
response = requests.post('https://api.fondy.eu/api/settlement', data=data, headers=headers)
The header can be important, since it tells you in what format you make your reqest, and some APIs do not work if you do not set the Content-type properly.
The response is here a Response object, and you can parse the response to a Python dictionary with:
response.json()
locally this gives me:
{'response': {'error_code': 1002,
'error_message': 'Application error',
'request_id': 'iUxQzJfyBuxdI'}}
The status code is 200, so that probably means that the callback you specified was not valid (or some other items in your request).
You could use DRF as the documentation :
https://www.django-rest-framework.org/tutorial/2-requests-and-responses/
Or without DRF :
# importing the requests library
import requests
# api-endpoint
URL = "https://api.fondy.eu/api/settlement"
# defining a params dict for the parameters to be sent to the API
data =
"order": {
"server_callback_url": "http://site.id/callback",
"currency": "UAH",
"amount": "1400",
"order_type": "settlement",
"response_url": "http://site.id/test/responsepage/",
"order_id": "test1234561467462099.19",
"operation_id": "test1234561467462099.19",
"order_desc": "test order",
"merchant_id": 700001,
"receiver": [
{
"requisites": {
"amount": 100,
"merchant_id": 500001
},
"type": "merchant"
},{
"requisites": {
"amount": 200,
"merchant_id": 600001
},
"type": "merchant"
},
]
}
# sending get request and saving the response as response object
r = requests.POST(url = URL, data= data)
# extracting data in json format
data = r.json()
Maybe you would like to try the API before writing code, there is tool like postman to do this quickly :)
Related
The problem is I can't perform PUT or POST with Postman app. But DELETE is possible. And yes I enabled all actions for public users.
Here is GET request result:
{
"data": [
{
"id": 2,
"attributes": {
"title": "23123",
"game": "1231",
"players": "2312313",
"createdAt": "2022-02-19T16:36:34.221Z",
"updatedAt": "2022-02-19T16:36:34.971Z"
}
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 1
}
}
}
And here is my entries for POST request:
finally after requesting POST here is result:
{
"data": null,
"error": {
"status": 400,
"name": "ValidationError",
"message": "Missing \"data\" payload in the request body",
"details": {}
}
}
What is the problem?
I finally found the solution. u need to put Body in raw and set it as Json! default is Text.
and POST example is :
{
"data": {
"title": "Hello",
"relation": 2,
"relations": [2, 4]
}
}
I'm developing a google action which is configured for account linking using Linking Type: "OAuth" / "Authorization code". The OAuth2 authorization server functions are hosted in the same place as the linked business application server, so I have full visibility of the traffic in both regards.
The initial linking process works perfectly every time; however, a problem arises when the original access token expires, and a new one is requested grant_type=refresh_token. Included below are the sanitized log contents from our server's execution logic generated by invocation of the google action using Actions Console "Test" simulator, after the original access token has expired. As expected, the google action first requests a new access token by calling the Token Url with grant_type=refresh_token. Our server then returns content to the caller
shown below under SmartAssistOAuthToken: result= as
{"expires_in":600,"token_type":"Bearer","access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.5XRFvkrBr7PCfyyqSMW1nNJBI0EceQgFrMA-6I04sQA"}
Having received the new token, the Google action proceeds to the main intent / webhook handler which contains a REST request back to the same server to retrieve some information about the current user's account.
This is shown below as: >****> 2021/07/15 12:16:18 (-05:00) - /cgi-bin/w2w.dll/sa_anon?cmd=login...
>********> 2021/07/15 12:16:15 (-05:00) - /cgi-bin/w2w.dll/AoG_token?
----------------------------------------------------------------------------------------------------
SmartAssistOAuthToken: contentfields=
grant_type=refresh_token
refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.65URfGpCL4s9nZiUc2pvYRZydK6jKanI5DZAZm04BtM
client_id=xxxx
client_secret=xxxx
----------------------------------------------------------------------------------------------------
SmartAssistOAuthToken: result= (...using 600 to speed things up a bit)
{"expires_in":600,"token_type":"Bearer","access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.5XRFvkrBr7PCfyyqSMW1nNJBI0EceQgFrMA-6I04sQA"}
----------------------------------------------------------------------------------------------------
>********> 2021/07/15 12:16:18 (-05:00) - /cgi-bin/w2w.dll/sa_anon?cmd=login&access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.FfUGlS71IaIU3LdkiJtUKfBBZwjSaN5D0s1ECpzxop4
----------------------------------------------------------------------------------------------------
SmartAssistLogin: QueryFields=
cmd=login
access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.FfUGlS71IaIU3LdkiJtUKfBBZwjSaN5D0s1ECpzxop4
----------------------------------------------------------------------------------------------------
ValidAccessTokenInfo: AccessToken's JWT has expired.
----------------------------------------------------------------------------------------------------
SmartAssistError: Error={"error_uri":"https:xxxx","error_description":"Invalid authorization credential.","error":"invalid_request"}
At the end of the "login" REST request is the access token which I read from conv.session.params.bearerToken, and then add to the url.
/cgi-bin/w2w.dll/sa_anon?cmd=login&access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.FfUGlS71IaIU3LdkiJtUKfBBZwjSaN5D0s1ECpzxop4
However, the value provided by conv.session.params.bearerToken (eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.FfUGlS71IaIU3LdkiJtUKfBBZwjSaN5D0s1ECpzxop4) is not the new one returned to the refresh token request (eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.5XRFvkrBr7PCfyyqSMW1nNJBI0EceQgFrMA-6I04sQA). As such, my server returns an error for the request because the original token is no longer valid / expired.
The entire (sanitized) incoming conv object is as follows, wherein all references to bearerToken are the same recently expired token:
{
"overwrite": false,
"digested": false,
"request": {
"handler": {
"name": "main"
},
"intent": {
"name": "actions.intent.MAIN",
"params": {},
"query": "Talk to work assistant"
},
"scene": {
"name": "Main",
"slotFillingStatus": "UNSPECIFIED",
"slots": {}
},
"session": {
"id": "ABwppHFsSDza7b0R74-kOOBCudqHWhrjIMma8mnaLjTDFg55O68MIjBIPRgaSEyAH31RPOJGG9VhrIl283LWY6xXZsw",
"params": {},
"typeOverrides": [],
"languageCode": ""
},
"user": {
"locale": "en-US",
"params": {
"AccountLinkingSlot": "LINKED",
"bearerToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.FfUGlS71IaIU3LdkiJtUKfBBZwjSaN5D0s1ECpzxop4",
},
"accountLinkingStatus": "LINKED",
"verificationStatus": "VERIFIED",
"packageEntitlements": [],
"gaiamint": "",
"permissions": [],
"lastSeenTime": "2021-07-15T16:15:48Z"
},
"home": {
"params": {}
},
"device": {
"capabilities": ["SPEECH", "RICH_RESPONSE", "LONG_FORM_AUDIO"],
"timeZone": {
"id": "America/Chicago",
"version": ""
}
}
},
"headers": {
"host": "us-central1-work-assistant-b9910.cloudfunctions.net",
"user-agent": "Google-ActionsOnGoogle/1.0",
"transfer-encoding": "chunked",
"accept-encoding": "gzip, deflate, br",
"content-type": "application/json;charset=UTF-8",
"forwarded": "for=\"66.249.83.57\";proto=https",
"function-execution-id": "zn46t5q3mkfr",
"google-actions-api-version": "3",
"google-assistant-signature": "xxxx",
"traceparent": "00-6b5c4d0aa670f39009910ec1f7e908ee-2abd7ee7886b286d-00",
"x-appengine-country": "ZZ",
"x-appengine-default-version-hostname": "d1c092144ed53556ap-tp.appspot.com",
"x-appengine-https": "on",
"x-appengine-request-log-id": "60f06d6200ff0c6741e353b4fb0001737e6431633039323134346564353335353661702d7470000133343061346661353033613135323331626363326539303833646463386639313a310001010c",
"x-appengine-timeout-ms": "599998",
"x-appengine-user-ip": "66.249.83.57",
"x-cloud-trace-context": "6b5c4d0aa670f39009910ec1f7e908ee/3079757253082556525",
"x-forwarded-for": "66.249.83.57",
"x-forwarded-proto": "https",
"connection": "close"
},
"handler": {
"name": "main"
},
"intent": {
"name": "actions.intent.MAIN",
"query": "Talk to work assistant",
"params": {}
},
"scene": {
"name": "Main",
"slotFillingStatus": "UNSPECIFIED",
"slots": {},
"next": {}
},
"session": {
"id": "ABwppHFsSDza7b0R74-kOOBCudqHWhrjIMma8mnaLjTDFg55O68MIjBIPRgaSEyAH31RPOJGG9VhrIl283LWY6xXZsw",
"params": {
"AccountLinkingSlot": "LINKED",
"bearerToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.FfUGlS71IaIU3LdkiJtUKfBBZwjSaN5D0s1ECpzxop4",
},
"typeOverrides": [],
"languageCode": ""
},
"user": {
"locale": "en-US",
"params": {
"AccountLinkingSlot": "LINKED",
"bearerToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.FfUGlS71IaIU3LdkiJtUKfBBZwjSaN5D0s1ECpzxop4",
},
"accountLinkingStatus": "LINKED",
"verificationStatus": "VERIFIED",
"packageEntitlements": [],
"gaiamint": "",
"permissions": [],
"lastSeenTime": "2021-07-15T16:15:48Z"
},
"device": {
"capabilities": ["SPEECH", "RICH_RESPONSE", "LONG_FORM_AUDIO"],
"currentLocation": {},
"timeZone": {
"id": "America/Chicago",
"version": ""
}
},
"home": {
"params": {}
},
"expected": {},
"context": {},
"prompt": {
"override": false
},
"_internal": {
"promptSet": false,
"orig": {
"scene": {
"name": "Main",
"slotFillingStatus": "UNSPECIFIED",
"slots": {},
"next": {}
},
"session": {
"id": "ABwppHFsSDza7b0R74-kOOBCudqHWhrjIMma8mnaLjTDFg55O68MIjBIPRgaSEyAH31RPOJGG9VhrIl283LWY6xXZsw",
"params": {},
"typeOverrides": [],
"languageCode": ""
},
"user": {
"locale": "en-US",
"params": {
"AccountLinkingSlot": "LINKED",
"bearerToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.FfUGlS71IaIU3LdkiJtUKfBBZwjSaN5D0s1ECpzxop4",
},
"accountLinkingStatus": "LINKED",
"verificationStatus": "VERIFIED",
"packageEntitlements": [],
"gaiamint": "",
"permissions": [],
"lastSeenTime": "2021-07-15T16:15:48Z"
},
"home": {
"params": {}
}
}
}
}
The relevant google action webhook code looks something like this:
const {conversation,
Suggestion,
Simple,
Card,
Image
} = require('#assistant/conversation');
const functions = require('firebase-functions');
const app = conversation();
...
const getAccessToken = (conv) => {
return conv.session.params.bearerToken;
};
...
app.handle('main', async conv => {
...
console.log("main: >>>>>>>>>>>>>> conv=",JSON.stringify(conv));
...
if (conv.user.verificationStatus !== 'VERIFIED') {
conv.add('Sorry, your account is not verified yet so you cannot be here.');
return;
}
...
await getRemoteData(`${getFullredirectpath()}sa_anon?cmd=login&access_token=${getAccessToken(conv)}`)
.then((response) => {
(success handling...)
})
.catch((err) => {
(Error handling...)
return;
});
...
}
This problem doesn't happen every time a token is refreshed, but it does happen frequently, and seemingly more so, the longer the time between sessions. I can almost always count on it to happen overnight.
I'm trying to send mail using Django and Mailgun through the Anymail package and with an OVH server.
I'm currently receiving the 552 sorry, your envelope sender domain must exist (#5.7.1) error.
In this question/answer, it is suggested that I would need a "from" header, but the response I'm getting seems to show that the header is already included :
"headers": {
"to": "evenements#mydomain-longversion.org",
"message-id": "20160915065953.15168.46300.4ABD80EB#mailgun.mydomain.fr",
"from": "covoiturage#mydomain.fr",
"subject": "Mail test !"
},
Here is the full response, for reference :
{
"severity": "permanent",
"tags": [],
"storage": {
"url": "https://si.api.mailgun.net/v3/domains/mailgun.mydomain.fr/messages/eyJwIjpmYWxzZSwiayI6ImI5OGIyN2QzLTM2MmEtNGJjNi05ZWViLTRlMTA0NTVmYTIxMiIsInMiOiJlNmY5NzZhZTYwIiwiYyI6InNiaWFkIn0=",
"key": "eyJwIjpmYWxzZSwiayI6ImI5OGIyN2QzLTM2MmEtNGJjNi05ZWViLTRlMTA0NTVmYTIxMiIsInMiOiJlNmY5NzZhZTYwIiwiYyI6InNiaWFkIn0="
},
"delivery-status": {
"tls": false,
"mx-host": "redirect.ovh.net",
"attempt-no": 1,
"description": null,
"session-seconds": 0.9216420650482178,
"code": 552,
"message": "552 sorry, your envelope sender domain must exist (#5.7.1)",
"certificate-verified": false
},
"recipient-domain": "mydomain-longversion.org",
"event": "failed",
"campaigns": [],
"reason": "generic",
"user-variables": {},
"flags": {
"is-routed": null,
"is-authenticated": true,
"is-system-test": false,
"is-test-mode": false
},
"log-level": "error",
"timestamp": 1473922798.282194,
"envelope": {
"transport": "smtp",
"sender": "postmaster#mailgun.mydomain.fr",
"sending-ip": "209.61.151.224",
"targets": "evenements#mydomain-longversion.org"
},
"message": {
"headers": {
"to": "evenements#mydomain-longversion.org",
"message-id": "20160915065953.15168.46300.4ABD80EB#mailgun.mydomain.fr",
"from": "covoiturage#mydomain.fr",
"subject": "Mail test !"
},
"attachments": [],
"recipients": [
"evenements#mydomain-longversion.org"
],
"size": 643
},
"recipient": "evenements#mydomain-longversion.org",
"id": "TfJKwpoZQq6bM-MW5sm6nA"
}
And here is my Django code :
def SendTestEmail(request):
if request.user.is_staff and settings.DEBUG == True :
send_mail(
subject='Mail test !',
message='''Bonjour {}, votre email a bien été envoyé.'''.format(request.user.get_full_name()),
recipient_list=['evenements#mydomain-longversion.org',],
from_email=settings.DEFAULT_FROM_EMAIL,
fail_silently=False,
)
messages.success(request, 'Email correctement envoyé !')
return redirect('rideshare_event_list')
Try using covoiturage#mailgun.mydomain.fr as your from address instead of covoiturage#mydomain.fr.
I'm afraid I'm not sure whether it's possible to use covoiturage#mydomain.fr as the from address.
I've implemented functionality to Like a non-FB URL in a cross-platform mobile app (Phonegap) I'm developing, and part of functionality is that I need to find out if a user has liked a URL before, hence a GET on the og.likes object. In the result of this request there's a field in the og.likes data that I'm unsure about.
My request:
GET me/og.likes?access_token={AccessToken}&object={EncodedExternalURL}
The response:
{
"data": [
{
"id": "_____",
"from": {
"id": "______",
"name": "______"
},
"start_time": "2015-01-12T06:17:24+0000",
"end_time": "2015-01-12T06:17:24+0000",
"publish_time": "2015-01-12T06:17:24+0000",
"application": {
"name": "______",
"namespace": "______",
"id": "______"
},
"data": {
"object": {
"id": "____",
"url": "____",
"type": "website",
"title": "____"
}
},
"type": "og.likes",
"no_feed_story": false,
"likes": { // <-- this guy here and its properties
"count": 0,
"can_like": true,
"user_likes": false
},
"comments": {
"count": 0,
"can_comment": true,
"comment_order": "chronological"
}
}
],
"paging": {
"next": "____"
}
}
What is the likes field? And the sub properties of count, can_like, user_likes? Is it that other users can like this Like?
likes field is for manage the likes that this like has. Users can like or comment a like.
My backed is giving me some information about the reply in a meta field. For example, when going to #/phoneNumbers/phonelocations/index a request to /api/phonelocations is sent, and this is the data received:
{
"meta": {
"api_action": "find_all",
"api_id": "phonelocations",
"content_type": "application/json",
"error_code": 200,
"errors": [
{
"admin_message": "",
"code": 200,
"message": ""
}
],
"message": "Successfully read phonelocations",
"success": true
},
"phonelocations": [
{
"_id": "0",
"city": "Berlin",
"count": 10,
"country": "DE",
"country_name": "Germany",
"loctype": "GEO",
"loctype_human": "Geographical number",
"subtype": "49GEO",
"subtype_human": "German geographical number",
"type": "phonelocation-faketype"
},
...
]
}
This is present in all replies coming from the backend. I would like to use the message in _reply_meta.message to display it to the user. Is there a standard way in Ember to access the meta information of the replies?
Just use store.metadataFor(type), in your case:
var meta = this.store.metadataFor('phonelocation');
// all metadata is in meta object
meta.message // => "Successfully read phonelocations"
See this in action http://jsfiddle.net/marciojunior/3vfQD/