How does pass_thread_control work in Facebook Handover Protocol? - json

I'm trying to test the pass_thread_control function on Facebook Messenger, to have my Dialogflow bot direct ongoing conversation to a human operator. So far I'm stuck at even trying to get a "success" code in Graph API Explorer. I have reviewed Facebook's documentation ( https://developers.facebook.com/docs/messenger-platform/reference/handover-protocol/pass-thread-control/ ), carefully looked through different threads here or elsewhere. I have:
Subscribed my Facebook Page to receive messaging_handovers.
Set the Dialogflow chatbot app as the Primary Receiver.
Set the Page Inbox as Secondary Receiver.
...And I keep on getting various errors. For example, I try this request in Graph API explorer:
POST to https://graph.facebook.com/v5.0/me/pass_thread_control
with params:
{
"recipient": {
"id": "myPageID"
},
"target_app_id": "263902037430900"
}
{
"error": {
"message": "Unsupported post request. Object with ID 'me' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api",
"type": "GraphMethodException",
"code": 100,
"error_subcode": 33,
"fbtrace_id": "AipGijCLKQOwOl6L792ZEgG"
}
}
Maybe the issue is the recipient PSID? This is the only parameter I have no idea where to get. What is the page scoped app-id? How do I get it?
Or maybe I missed some permissions...?
Any help getting me unstuck much appreciated...

Okay, I actually managed to figure it out.
First and foremost - I discovered the Page I was trying to pass the thread control to wasn't linked to my Facebook Business account and the chatbot app was. I added the page in Facebook Business Manager so that it's linked to the same business account as the chatbot app. NOTE: I am not sure that this is a prereq for everyone, so take caution. It might not be required in all scenarios.
To retrieve the Page PSID, which can then be used in the 'recipient' param of the POST request to pass_thread_control, Sent a GET request using Graph API Explorer as shown here: https://developers.facebook.com/docs/facebook-login/connecting-accounts#examples
Even though the example request does not contain the appsecret_proof param, I used it and haven't tested the request without it. A very simple way of generating appsecret_proof using PHP is shown here: https://developers.facebook.com/docs/graph-api/securing-requests#generate-proof
Then when providing the PSID obtained using method shown in point 2., I got "success:true" while testing the pass_thread_control, which did pass the thread control to Secondary Receiver = Page Inbox. Yaaay! 😊
All of the above is described also in this thread, which helped me figure it out, so credit to Sunil: Is Facebook Messenger PSID PageScope constant for User

Related

Which permissions are needed to upload files with mediawiki api?

I am using the mediawiki api to upload a file. I am sending a mutlipart POST request to
https://commons.wikimedia.org/w/api.php?format=json&action=upload&filename=xxx
In the header I include my Autherzation: Bearer accessToken123 and in the body I include my CSRF token, as well as my multipart file, all as per documentation.
However, the response I get from the server is the following:
{
"error": {
"code": "permissiondenied",
"info": "The action you have requested is limited to users in one of the groups: *, [[Commons:Users|Users]].",
"*": "See https://commons.wikimedia.org/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/postorius/lists/mediawiki-api-announce.lists.wikimedia.org/> for notice of API deprecations and breaking changes."
},
"servedby": "mw1448"
}
This would be quite self-explainatory by itself, however when I check my rights/groups with
https://commons.wikimedia.org/w/rest.php/oauth2/resource/profile
I get the following:
{"sub":xxxx,"username":"xxxxx","editcount":7,"confirmed_email":true,"blocked":false,"registered":"xxxx",
"groups":["*","user","autoconfirmed"],
"rights":["read","writeapi","viewmyprivateinfo","abusefilter-view","abusefilter-log","upload","upload_by_url","reupload-own","purge","reupload","autoconfirmed","editsemiprotected","skipcaptcha","abusefilter-log-detail","transcode-reset"],
"grants":["basic","uploadfile","uploadeditmovefile","privateinfo"],"realname":"","email":"xxxx"}
As you can see I am both a part of the required groups and also have the neccessairy upload right. The error message is quite clear, so I don't know what I am missing. It is not the CSRF token or access token, supplying these wrong results in a different error message. Any help is appreciated.
Well I finally figured it out: When requesting the app keys from mediawiki, you can select rights which the app has on behalf of the users. If you want to upload pictures to wikimedia commons, you do not only need the `
Interact with media: Upload new files; Upload, replace, and move
files
right, but also the
Create, edit, and move pages
right, since you are creating a new page with each upload. I hope this helps someone else in the future :`)

Facebook Graph API returns a different response on a different script but same -not invalid- tokens

I am trying to make a simple python script that posts a text message to a facebook page using requests.
I actually managed to succeed this feat, however, when I add the same logic to a bigger project of mine, a certain request returns a different json.
According to this page https://developers.facebook.com/docs/pages/access-tokens I can exchange the short lived user token I generate in the graph explorer tool for a long lived one that lasts 60 days. This worked for me until now. When I run the same functions, same variables on another .py file that includes other logic as well the request does not return this line:
"expires_in": SECONDS-UNTIL-TOKEN-EXPIRES
And of course later on if I continue the logic and use the token it returns (which is the same) for, let's say, a make_post function the request prints
{'error': {'message': '(#200) If posting to a group, requires app being installed in the group, and \\\n either publish_to_groups permission with user token, or both manage_pages \\\n and publish_pages permission with page token; If posting to a page, \\\n requires both manage_pages and publish_pages as an admin with \\\n sufficient administrative permission', 'type': 'OAuthException', 'code': 200, 'fbtrace_id': 'AqYMMeOcOniWAGgEEtsEURs'}
Why does it not successfully return, the user token had not expired and it has the requires rights. Furthermore I tested this in a smaller .py file and it worked.
Another thing I found out here https://developers.facebook.com/support/bugs/523165725596520/?join_id=f1ff8392b49675c here is that other people have actually reported the same issue but it has been closed as 'intended by design' however there is no information of a solution.
Running the request in my browser also does not work correctly.
Do you have any ideas? I am completely clueless.
Thank you very much in advance
As #CBroe in a comment said, the expires_in didn't have anything to do with my error. The token it returns if valid. The issue I had later on had to do with the url I was parsing

SendBird GET Request Api for retrieve previous messages not working properly

Im using SendBird platform API to create chat in my website,
when i try to retrieve the previously send messages in a channel using below API:
https://api.sendbird.com/v3/{channel_type}/{channel_url}/messages
METHOD : GET
Request: ?message_ts=long(Required)&prev_limit=int(Optional, default: 15, 0~200)&next_limit=int(Optional, default: 15, 0~200)&include=boolean(Optional, default: true)&reverse=boolean(Optional, default: false)&custom_type=string(Optional)&message_type=string(Optional)&sender_id=string(Optional)
after passing value to above request,im getting an error saying
{
"message": "Not authorized. Get messages function can be called only from Park or Enterprise plan.",
"code": 400108,
"error": true
}
can some one please help me with this
Thanks
Nithin
The Message Retrieval API which you are calling is a premium feature as you can see in Senbird's Pricing Page.
You will have to contact Sendbird and upgrade to their premium plan in order to retrieve message and successfully call the endpoint.
You can retrieve messages in SDKs (available for JavaScript too).
In Android call this method,
mChannel.getPreviousMessagesByTimestamp()
where mChannel is an object of type GroupChannel(OpenChannel also allowed).
And as far as I know, it is ok to retrieve messages like that.
For Javascript
refer to this link

Get data from Instagram API from confirmed project

I have two projects linked to one clientID. Project "A" is in sandbox, the "B" one is confirmed. I was calling feed with this type of URL
https://api.instagram.com/v1/users/[userID]/media/recent/?client_id=[clientID]&count=20&access_token=[mySecretToken]
The problem is, that with this type of URL I can retrieve data only for project A. For confirmed project B I always get an error
{"meta": {"error_type": "APINotFoundError", "code": 400, "error_message": "this user does not exist"}}
I'm following the documentation ( https://www.instagram.com/developer/endpoints/users/#get_users_media_recent ) but this absolutely doesn't work outside the sandbox!
In another part of documentation I have found this:
For example, if you query the /users/{user-id}/ endpoint and the {user-id} is a sandbox user, then you will get the normal API response; but if the {user-id} is not a sandbox user, you will get a APINotFound error.
That's really useful information, but I really can' find a way, how can I retrieve data from confirmed (live, reviewed) project.
Can plz anyone help how can I do it?

Get JSON from Google Apps Script URL via Erlang

Good Evening!
I've been looking into the possibility of using GAS(Google Apps Script) to host a small bit of javascript that lets me use the new Google finance apps api. The intention being that I'll be using the stock information for a project which involves the use of stock data. I know that there are a few ways to get stock information from Google, but the data that the finanace app returns is more in-line with other sources we are using. (One constraint on this project is that we have multiple sources).
I've written the javascript and I can call a httpc:request to the URL for the script given to me from Google. In the browser the JS returns the json object as I want it, however when the call is made from Erlang I'm getting it in a list of ascii. From checking the values it appears to be a document starting like:
Below is the javascript and the url to see the json:
https://script.google.com/macros/s/AKfycbzEvuuQl4jkrbPCz7hf9Zv4nvIOzqAkBxL1ixslLBxmSEhksQM/exec
function doGet() {
var stock = FinanceApp.getStockInfo('LON:TSCO');
return ContentService.createTextOutput(JSON.stringify(stock))
.setMimeType(ContentService.MimeType.JSON);
}
For the erlang, it's a simple request but I've not been doing erlang long, so perhaps I've messed something up here (The URL being the one mentioned above). I've got crypto / ssl / inets when I'm testing this on the command line.
{ok, {Version, Headers, Body}} = httpc:request(get, URL, []}, [], []).
I think it's also worth mentioning that when i curl it from Cygwin, I get a massive load of HTML also, I've included it below, but if you see it you'll thank me for not posting it in here! http://pastebin.com/UtJHXjRm
I've been updating the script as I go with the new versions but I'm at a bit of a loss as to why it's not returning correctly.
If anyone can give me any pointers I'd be very grateful! I get the feeling that it's not intended to be used this way, perhaps only within other Google products and such.
Cheers!
It would be necessary to review how are you deploying the Web App, specifically the Who has access to the app, to access without authentication should be configured as shown in the image:
See Deploying Your Script as a Web App from the documentation.
In my test, by running:
curl -L https://script.google.com/macros/s/************/exec
Get the following result:
{
"priceopen":358,
"change":2.199981689453125,
"high52":388.04998779296875,
"tradetime":"2013-10-11T15:35:18.000Z",
"currency":"GBX",
"timezone":"Europe/London",
"low52":307,
"quote":357.8999938964844,
"name":"Tesco PLC",
"exchange":"LON",
"marketcap":28929273763,
"symbol":"TSCO",
"volumedelay":0,
"shares":8083060703,
"pe":23.4719295501709,
"eps":0.15248000621795654,
"price":357.8999938964844,
"has_stock_data":true,
"volumeavg":14196534,
"volume":8885809,
"changepct":0.6184935569763184,
"high":359.5,
"datadelay":0,
"low":355.8999938964844,
"closeyest":355.70001220703125
}
Possibly your GET is not following the REDIRECT that happens when you use contentService. Look at the html returned there is a redirect in there.