rehabstudio / fbmessenger

A python library to communicate with the Facebook Messenger API's
Other
115 stars 50 forks source link

[question] Is sending attachments from file supported? #76

Closed kmbt closed 4 years ago

kmbt commented 4 years ago

Hi, I would like to know if the library supports sending attachments from file as described here: https://developers.facebook.com/docs/messenger-platform/send-messages#sending_attachments in section "Attaching from File". Thank you :)

rickydunlop commented 4 years ago

Hey, Yeah it is currently supported, you can see an example here https://github.com/rehabstudio/fbmessenger/blob/master/tests/test_attachments.py#L45

kmbt commented 4 years ago

@rickydunlop Thank you for your quick answer! Still, it is not quite clear to me how do I attach a file from a local filesystem. The example you have provided seems to do what is described as "Attaching from URL" in the Messenger docs. What I would like to do is "Attaching from File".

rickydunlop commented 4 years ago

You would need to upload the attachment and use the attachment_id from the response. You can do this using the Send API

The example they give uses curl but you can do this using requests (I haven't tested this so it may have some mistakes)

data = {
    'recipient': {'id': '<PSID>'},
    'message': {'attachment': {'type': '<ASSET_TYPE>', 'payload': {'is_reusable': true}}},
}
files = {
    'filedata': open('/tmp/shirt.png', 'rb')
}

You can try using the requests session from the messenger client

response = messenger.client.session.post(
  'https://graph.facebook.com/v8.0/me/messages',
  params=messenger.client.auth_args,
  data=data, 
  files=files,
)

If that doesn't work just import the requests library and use it directly, don't forget to pass the auth params

params = {
    'access_token':  '<PAGE_ACCESS_TOKEN>',
}

You can then get the ID from the response and send that as attachment_id instead the url

result = response.json()
attachment_id = result['attachment_id']

Hope this helps

kmbt commented 4 years ago

@rickydunlop Wow, thank you!

That did almost work. The API gave me errors in form of:

'{"error":{"message":"(#100) param recipient must be non-empty.","type":"OAuthException","code":100,"fbtrace_id":"<SOME_ID>"}}'

This was a considerable progress for me because I've received an error message I could search the web for, and thus found the following solution: https://stackoverflow.com/questions/39563786/python-curl-f-equivalent-with-requests-or-other

So the corrected working code is:

image_path = "/tmp/placeholder.png"
files = {"filedata": ('filename.png', open( image_path, 'rb'), 'image/png')}
data = {
    "recipient": json.dumps({"id": recipient_id}),
    "message": json.dumps({"attachment": {"type": "image", "payload": {"is_reusable": False}}})
}

r = messenger.client.session.post(
    'https://graph.facebook.com/v8.0/me/messages',
    params=messenger.client.auth_args,
    files=files,
    data=data
)

The recipient and message values for some reason must be JSON-ified first. Otherwise, it does not work.