Facebook Messenger Bot, send Image Attachment - facebook

I'm creating a Facebook bot that has images uploaded to it, and it responds with an image. Can I send the image in an attachment and delete it off my server or do I have to send a URL to the image and keep the image on my server?

You can use their Upload API to upload your attachments to their servers.
curl -X POST -H "Content-Type: application/json" -d '{
"message":{
"attachment":{
"type":"image",
"payload":{
"url":"http://www.messenger-rocks.com/image.jpg",
"is_reusable":true,
}
}
}
}' "https://graph.facebook.com/v2.6/me/message_attachments?access_token=PAGE_ACCESS_TOKEN"
The upload call will respond back an attachment_id which can be used to send the attachment to the user without uploading it again.
curl -X POST -H "Content-Type: application/json" -d '{
"recipient": {
"id": "USER_ID"
},
"message": {
"attachment": {
"type": "image",
"payload": {
"attachment_id": "1745504518999123"
}
}
}
}' "https://graph.facebook.com/me/messages?access_token=PAGE_ACCESS_TOKEN"

curl \
-F recipient='{"id":"USER_ID"}' \
-F message='{"attachment":{"type":"image", "payload":{}}}' \
-F filedata=#/tmp/testpng.png \
"https://graph.facebook.com/v2.6/me/messages?access_token=PAGE_ACCESS_TOKEN"
Here you can find an official example on how to atach a jpg or a png.
https://developers.facebook.com/docs/messenger-platform/send-api-reference#examples

I have the same problem, but still found no answer.
For now, the only way to send images with Facebook bot, is "image_url" with your's image url.

You can send attachments via the Facebook Messenger API by POSTing them directly (without using the payload.url option) with a multipart request. Here it is with PHP & Guzzle (though any good HTTP Request package should do, regardless of the scripting language):
use GuzzleHttp\Client;
$client = new Client();
$graphRequest = $client->request('POST', 'https://graph.facebook.com/v5.0/me/messages', [
'query' => [
'access_token' => $facebookInfo['pageAccessToken']
],
'multipart' => [
[
'name' => 'messaging_type',
'contents' => 'RESPONSE',
],
[
'name' => 'recipient',
'contents' => json_encode(['id' => $yourRecipientPSID]),
],
[
'name' => 'message',
'contents' => json_encode(['attachment' => ['type' => 'file', 'payload' => []]]),
],
[
'name' => 'filedata',
'contents' => fopen($yourFilePath, 'r'),
'filename' => $yourFileName,
],
],
]);
Note that the attachments.payload parameter is set, but null. The Graph API returns a 400 response if payload is not set.

Related

Trello API get attachment content with CURL?

I found in atlassian documentation this way to get card attachment, but it doesn't work, I get here unauthorized permission requested.
curl -H "Authorization: OAuth oauth_consumer_key="MY_API_KEY", oauth_token="MY_USER_TOKEN"" https://trello.com/1/cards/e7c74l8c5ce3tf6424f95e76/attachments/71cdef9e0734215e3ccbfa82/download/cv.pdf
I tried same with guzzlehttp but same result:
$params_arr = [
'headers' => [
'Authorization' => 'OAuth oauth_consumer_key="' . $api_key . '", oauth_token="' . $token_key . '"'
]
];
$request = $this->request($attachment_url, 'GET', $params_arr);
Does somebody have idea what could be wrong here?
You need to change the URL, replace trello.com with api.trello.com
The result will see something like this: https://api.trello.com/1/cards/e7c74l8c5ce3tf6424f95e76/attachments/71cdef9e0734215e3ccbfa82/download/cv.pdf

Convert cURL to Guzzle POST with --form-params and --header

I'm struggling with a given curl-request which I want to handle over guzzle.
The curl-request looks like this:
curl --location --request POST "https://apis.myrest.com" \
--header "Content-Type: multipart/form-data" \
--header "Authorization: Bearer YOUR-BEARER-TOKEN" \
--form "mediaUrl=https://myfile.mpg" \
--form "configuration={
\"speechModel\": { \"language\": \"en-US\" },
\"publish\": {
\"callbacks\": [{
\"url\" : \"https://example.org/callback\"
}]
}
}
And I want it to send via guzzle like that:
// 1. build guzzle client:
//----------------------------------------------------------------------
$this->client = new Client([
'base_uri' => $this->config->getBaseUri(),
]);
// 2. build guzzle request:
//----------------------------------------------------------------------
$request = new Request(
'POST',
'myendpoint',
[
'authorization' => 'Bearer ' . $this->config->getApiToken(),
'cache-control' => 'no-cache',
'content-type' => 'application/json',
// maybe here, or not?
form_params => ['mediaUrl' => 'www.media.com'],
]
);
// 3. send via client
//----------------------------------------------------------------------
response = $this->client->send($request, ['timeout' => self::TIMEOUT]);
My problem now is, that I have no clue how to handle this. In guzzle's documentation i found "form_params":
http://docs.guzzlephp.org/en/stable/quickstart.html#making-a-request#post-form-requests
But it does not seem to work. If I add the form_params-array to my request, the receiver does not get them. Can anybody tell me, how to write the exact curl-command with guzzle?
Thanks
Try using multipart instead of form_params.
http://docs.guzzlephp.org/en/latest/request-options.html#form-params
From Guzzle documentation:
form_params cannot be used with the multipart option. You will need to
use one or the other. Use form_params for
application/x-www-form-urlencoded requests, and multipart for
multipart/form-data requests.
Additionally try setting Guzzle Client with debug on, as it will display raw HTTP request that it sends, so you can compare it more easily with the curl command.
http://docs.guzzlephp.org/en/latest/request-options.html#debug
It is difficult to understand what is the exact request you would like to send, because there is incosistencies between the curl example and your code. I tried to replicate the curl as best as I could. Please note that Request 3rd parameter only expects headers, and for request options you have to use the 2nd parameter of send.
$client = new Client([
'base_uri' => 'https://example.org',
'http_errors' => false
]);
$request = new Request(
'POST',
'/test',
[
'Authorization' => 'Bearer 19237192837129387',
'Content-Type' => 'multipart/form-data',
]
);
$response = $client->send($request, [
'timeout' => 10,
'debug' => true,
'multipart' => [
[
'name' => 'mediaUrl',
'contents' => 'https://myfile.mpg'
],
[
'name' => 'configuration',
'contents' => json_encode([
'speechModel' => [
'language' => 'en-US'
],
'publish' => [
'callbacks' =>
[
[
'url' => 'https://example.org/callback'
]
]
]
])
]
]
]);

How can I do multipart requests mith Mojo::UserAgent?

I'd like to perform a multipart file upload to Google Drive as described here using a Mojo::UserAgent. I currently do it like this:
my $url = Mojo::URL->new('https://www.googleapis.com/upload/drive/v3/files');
$url->query({ fields => 'id,parents',
ocr => 'true',
ocrLanguage => 'de',
uploadType => 'multipart' });
my $tx = $ua->post($url,
json => { parents => [ '0ByFk4UawESNUX1Bwak1Ka1lwVE0' ] },
{
'Content-Type' => 'multipart/related',
'parents' => [ '0ByFk4UawESNUX1Bwak1Ka1lwVE0' ]
},
$content );
but it doesn't work.
I've managed authorization OK (omitted here) and simple file upload works fine. I just can't seem to do the multipart.
I've tried to make sense of the docs here - but to no avail, in the sense that the file gets uploaded OK, but the JSON part gets ignored, and the file gets uploaded in the root folder.

Facebook Messenger API Error: Payload cannot be empty for postback type button

I successfully set up Greeting Text, and now I trying to set up a payload for a Get Started button by this guide:
I send exactly:
curl -X POST -H "Content-Type: application/json" -d '{
"setting_type":"call_to_actions",
"thread_state":"new_thread",
"call_to_actions":[
{
"payload":"START"
}
]
}' "https://graph.facebook.com/v2.6/me/thread_settings?access_token=PAGE_ACCESS_TOKEN"
but receive an error:
{"error":{"message":"(#100) Payload cannot be empty for postback type button","type":"OAuthException","code":100,"fbtrace_id":"GWv5XughbUQ"}}
What i do wrong?
Finally, I found my mistake. CBroe said I was wrong in request structure.
I used PHP and sent:
$requset = [
'call_to_actions' => [
'payload' => 'START'
],
'setting_type' => 'call_to_actions',
'thread_state' => 'new_thread'
];
But right form is:
$requset = [
'call_to_actions' => [
['payload' => 'START']
],
'setting_type' => 'call_to_actions',
'thread_state' => 'new_thread'
];

Parse REST API set ACL to an object

I'm trying to set the ACL permissions for an object created through the Parse REST API. I want it to have only public read access. Only the server can create or modify the objects in the class. I read the parse REST documentation on how to set ACL permissions.
When I run the following:
$InputData = array('votes' => 1, 'ACL' => array('*' => array('read' => true, 'write' => false)), 'user' => array('__type' => 'Pointer', 'className' => '_User', 'objectId' => $objectId));
$rest = curl_init();
curl_setopt($rest,CURLOPT_URL,$url);
curl_setopt($rest,CURLOPT_PORT,443);
curl_setopt($rest,CURLOPT_POST,1);
curl_setopt($rest,CURLOPT_POSTFIELDS, json_encode($InputData));
curl_setopt($rest,CURLOPT_HTTPHEADER,
array("X-Parse-Application-Id: " . $appId,
"X-Parse-Master-Key: " . $restKey,
"Content-Type: application/json"));
I get:
{"code":123,"error":"Invalid acl {\"*\":{\"read\":false,\"write\":false}}"} 1
What is wrong with my code, specifically the ACL part? Help!
Hope it helps.
curl -X POST \
-H "Content-Type: application/json" \
-H "X-Parse-Application-Id: xxxxxxxxxxxxxxx" \
-H "X-Parse-REST-API-Key: xxxxxxxxxxxxx" \
-H "X-Parse-Session-Token: xxxxxxxxxxxxxx" \
-d "{\"name\":\"MyName\", \"ACL\": {\"ErKLiQfj8Q\" : { \"read\": true, \"write\": true }, \"*\" : {}}}" \
https://api.parse.com/1/classes/Tasks
JSON obj
{
"name":"MyName",
"ACL":
{
"ErKLiQfj8Q" : { "read": true, "write": true },
"*" : {}
}
}