Coder Social home page Coder Social logo

fbmessenger's Introduction

Facebook Messenger

PyPI Build Status Coverage Status PyPI

A python library to communicate with the Facebook Messenger API's

Table of Contents

Installation

Install from pip

pip install fbmessenger

Facebook app setup

Example usage with Flask

First you need to create a verify token, this can be any string e.g.

'my_verify_token'

Messenger class

We need to extend the BaseMessenger abstract class and implement methods for each of the following subscription fields.

  • message
  • delivery
  • read
  • optin
  • postback
  • account_linking
from fbmessenger import BaseMessenger


class Messenger(BaseMessenger):
    def __init__(self, page_access_token, app_secret=None):
        self.page_access_token = page_access_token
        self.app_secret = app_secret
        self.client = MessengerClient(self.page_access_token, app_secret=self.app_secret)

    def message(self, message):
        self.send({'text': 'Received: {0}'.format(message['message']['text'])}, 'RESPONSE')

    def delivery(self, message):
        pass

    def read(self, message):
        pass

    def account_linking(self, message):
        pass

    def postback(self, message):
        pass

    def optin(self, message):
        pass

Create a route for the callback url

This can be used to process any messages received and also to verify your app

import os
from flask import Flask, request

app = Flask(__name__)
app.debug = True

messenger = Messenger(os.environ.get('FB_PAGE_TOKEN'))

@app.route('/webhook', methods=['GET', 'POST'])
def webhook():
    if request.method == 'GET':
        if (request.args.get('hub.verify_token') == os.environ.get('FB_VERIFY_TOKEN')):
            return request.args.get('hub.challenge')
        raise ValueError('FB_VERIFY_TOKEN does not match.')
    elif request.method == 'POST':
        messenger.handle(request.get_json(force=True))
    return ''


if __name__ == "__main__":
    app.run(host='0.0.0.0')

Timeouts

Any method on either the BaseMessenger or MessengerClient classes which perform network access accept an optional timeout parameter. This should be a number, and causes an exception to be raised if the server (ie. Facebook) has not started responding within timeout seconds (more precisely, if no bytes have been received on the underlying socket for timeout seconds). If no timeout is specified explicitly, requests do not time out. Note that in particular, timeout is not a time limit on the entire response download - just the initial connection.

For example, this call will raise a socket timeout exception if the start of a response has not been received within 10 seconds:

messenger.send({'text': msg}, 'RESPONSE', timeout=10)

If no timeout is provided (the default) then connection attempts will not time out.

Elements

Import the elements (or just the ones you need)

from fbmessenger import elements

Messaging type

Starting from 7th May 2018, Facebook requires that all message sends must include the messaging_type property:

https://developers.facebook.com/docs/messenger-platform/reference/send-api

This is passed in the send() calls below - in each case, we'll just use RESPONSE. You should use whatever value is appropriate for your application. Supported values are:

  • RESPONSE (default)
  • UPDATE
  • MESSAGE_TAG

See Messaging Types for more information.

Notification Type

Any of the elements below may be sent in conjunction with a notification type (see the Send API documentation for more details). notification_type is an optional parameter to the .send() call. For example:

messenger.send({'text': msg}, 'RESPONSE', notification_type='REGULAR')

Supported values are are:

  • REGULAR (default)
  • SILENT_PUSH
  • NO_PUSH

Message Tags

Message tags give you the ability to send messages to a person outside of the normally allowed 24-hour window for a limited number of purposes that require continual notification or updates.

messenger.send({'text': msg}, 'MESSAGE_TAG', tag='NON_PROMOTIONAL_SUBSCRIPTION')

Supported values are are:

  • BUSINESS_PRODUCTIVITY
  • COMMUNITY_ALERT
  • CONFIRMED_EVENT_REMINDER
  • NON_PROMOTIONAL_SUBSCRIPTION
  • for more see Supported Tags

See Message Tags for more information.

Text

You can pass a simple dict or use the Class

messenger.send({'text': msg}, 'RESPONSE')

elem = elements.Text('Your Message')
messenger.send(elem.to_dict(), 'RESPONSE')

Web button

btn = elements.Button(title='Web button', url='http://example.com')
messenger.send(btn.to_dict(), 'RESPONSE')

Payload button

To use these buttons you must have the message_deliveries subscription enabled

btn = elements.Button(title='Postback button', payload='payload')
messenger.send(btn.to_dict(), 'RESPONSE')

Attachments

You can upload attachments to Facebook for use in their other APIs:

attachment = attachments.Image(url='https://example.com/image.jpg')
client = MessengerClient(page_access_token=12345678)
res = client.upload_attachment(attachment)
print(res)
{"attachment_id": "12345"}

Images

image = attachments.Image(url='http://example.com/image.jpg')
messenger.send(image.to_dict(), 'RESPONSE')

Audio

audio = attachments.Image(url='http://example.com/audio.mp3')
messenger.send(audio.to_dict(), 'RESPONSE')

Video

video = attachments.Video(url='http://example.com/video.mp4')
messenger.send(video.to_dict(), 'RESPONSE')

Files

file = attachments.File(url='http://example.com/file.txt')
messenger.send(file.to_dict(), 'RESPONSE')

Templates

Import the templates (or just the ones you need)

from fbmessenger import templates

Generic template

btn = elements.Button(title='Web button', url='http://facebook.com')
elems = elements.Element(
    title='Element',
    item_url='http://facebook.com',
    image_url='http://facebook.com/image.jpg',
    subtitle='Subtitle',
    buttons=[
        btn
    ]
)
res = templates.GenericTemplate(elements=[elems])
messenger.send(res.to_dict(), 'RESPONSE')

Button template

btn = elements.Button(title='Web button', url='http://facebook.com')
btn2 = elements.Button(title='Postback button', payload='payload')
res = templates.ButtonTemplate(
    text='Button template',
    buttons=[btn, btn2]
)
messenger.send(res.to_dict(), 'RESPONSE')

Receipt template

element = elements.Element(
    title='Classic White T-Shirt',
    subtitle='100% Soft and Luxurious Cotton',
    quantity=2,
    price=50,
    currency='USD',
    image_url='http://petersapparel.parseapp.com/img/whiteshirt.png',
)
adjustment1 = elements.Adjustment(name='New Customer Discount', amount=20)
adjustment2 = elements.Adjustment(name='$10 Off Coupon', amount=10)
address = elements.Address(
    street_1='1 Hacker Way',
    city='Menlo Park',
    postal_code='94025',
    state='CA',
    country='US'
)
summary = elements.Summary(
    subtotal=75.00,
    shipping_cost=4.95,
    total_tax=6.19,
    total_cost=56.14
)
res = templates.ReceiptTemplate(
    recipient_name='Stephane Crozatier',
    order_number='12345678902',
    currency='USD',
    payment_method='Visa 2345',
    order_url='http://petersapparel.parseapp.com/order?order_id=123456',
    timestamp='1428444852',
    address=address,
    summary=summary,
    adjustments=[adjustment1, adjustment2],
    elements=[element]
)
messenger.send(res.to_dict(), 'RESPONSE')

Media template

btn = elements.Button(
    button_type='web_url',
    title='Web button',
    url='http://facebook.com'
)
attachment = attachments.Image(attachment_id='12345')
res = templates.MediaTemplate(attachment, buttons=[btn])
messenger.send(res.to_dict())

Sender Actions

Typing on

typing_on = SenderAction(sender_action='typing_on')
messenger.send_action(typing_on.to_dict())

Typing off

typing_ffn = SenderAction(sender_action='typing_off')
messenger.send_action(typing_off.to_dict())

Mark seen

mark_seen = SenderAction(sender_action='mark_seen')
messenger.send_action(mark_seen.to_dict())

Quick Replies

quick_reply_1 = QuickReply(title='Do something', payload='Send me this payload')
quick_reply_2 = QuickReply(title='Do something else', payload='Send me this other payload')
quick_replies = QuickReplies(quick_replies=[
	quick_reply_1,
	quick_reply_2
])
text = { text: 'A message' }
text['quick_replies'] = quick_replies.to_dict()
messenger.send(text, 'RESPONSE')

Messenger Profile

Greeting Text

from fbmessenger.thread_settings import GreetingText, MessengerProfile

greeting_text = GreetingText('Welcome to my bot')
messenger_profile = MessengerProfile(greetings=[greeting_text])
messenger.set_messenger_profile(messenger_profile.to_dict())

Get Started Button

from fbmessenger.thread_settings import GetStartedButton, MessengerProfile

get_started = GetStartedButton(payload='GET_STARTED')
messenger_profile = MessengerProfile(get_started=get_started)
messenger.set_messenger_profile(messenger_profile.to_dict())

You can then check for this payload in the postback method

Persistent Menu

from fbmessenger.thread_settings import PersistentMenu, PersistentMenuItem, MessengerProfile

menu_item_1 = PersistentMenuItem(item_type='web_url', title='Menu Item 1', url='https://facebook.com')
menu_item_2 = PersistentMenuItem(item_type='postback', title='Menu Item 2', payload='PAYLOAD')

menu = PersistentMenu(menu_items=[menu_item_1, menu_item_2])

messenger_profile = MessengerProfile(persistent_menus=[menu])
messenger.set_messenger_profile(messenger_profile.to_dict())

fbmessenger's People

Contributors

danfairs avatar edison12a avatar elinguiuriel avatar jacquerie avatar noamkush avatar rickydunlop avatar tirkarthi avatar wittfabian avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fbmessenger's Issues

Update README.md

  • add app_secret
  • add api version
  • update "Create a route for the callback url"
  • remove NON_PROMOTIONAL_SUBSCRIPTION

update "Create a route for the callback url":
messenger = Messenger(os.environ.get('FB_VERIFY_TOKEN'),os.environ.get('FB_PAGE_TOKEN'))

should be

messenger = Messenger(os.environ.get('FB_PAGE_TOKEN'))

How to send Youtube Videos as Message

Sending videos is as simple as adding the URL with .mp4 extension. But most of us share youtube videos across messenger.

So how can we send a Youtube video other than sending as a URL?

Infinite loop

hi there,

I'm using the example, but I'm getting a loop at the messages. I send "video", then I receive thousands of video responses. Also, the example doesn't cover the message_type. I've put a fixed "RESPONSE" there.

Or else I get TypeError: send() missing 1 required positional argument: 'messaging_type'

Send Image with caption

Hi, there and thank you for your library!

Currently, there is no way to add text to an image. Can it be implemented in the future versions? Thanks

class Image(BaseAttachment):
    def __init__(self, url=None, is_reusable=None, quick_replies=None, attachment_id=None):
        self.attachment_type = 'image'
        self.url = url
        self.is_reusable = is_reusable
        self.quick_replies = quick_replies
        self.attachment_id = attachment_id
        super(Image, self).__init__(self.attachment_type, self.url, self.is_reusable,
                                    self.quick_replies, self.attachment_id)

What is the right syntax for calling async functions?

Would you like assistance or advice?
assistance

Issue description
in the example below, trying to call an async function from within "def message(self, message):"

Steps to reproduce
insert "await inside the "def message(self, message):" where is a function defined as async

Traceback or other info

  • fbmessenger version: latest
  • python version: 3.7.3
  • Facebook Messenger API version: 11.0

Post response time

Using the method fbmessenger.send() I have a very slow response time (~ 800ms), has anybody encountered that before ?
I am having decent response (~80ms) time with slack on the same platform, so I am sure it doesn't come from my connection.

Sending multiple images as a group

Would you like assistance or advice?
Advice, please!

Issue description
When I drag and drop multiple images to a facebook messenger, they are sent as a group

Screen Shot 2021-09-12 at 2 13 31 PM

How do I do this as a bot?

Steps to reproduce
NA

Traceback or other info
NA

  • fbmessenger version: latest / master@commit
  • python version: 3.7
  • Facebook Messenger API version: 11

Fetching User Information

Can anyone brief me on getting user information of the sender?
Details Such as Name, Location etc.

Allow Messaging with Tags in messenger.send(...)

The BaseMessenger.send instance method doesn't take in a message tag parameter which is required when the messaging_type is "MESSAGE_TAG". As per the FB Docs, we should allow an extra optional parameter to the send method called tag which gets sent in the request body when the messaging_type is "MESSAGE_TAG".

Without this, we are not able to use this library for proactively messaging the users.

Sending multiple text responses

Hi, I need to send the reply back to facebook as 2 different messages. How can i handle this?

response = Text(text='Sorry, I am not able to answer for your queries right now.')

I need Sorry and I am not able to answer for your queries right now. as two different messages.

Please help.

Keep getting the same message from messenger

fbmessenger version 5.0.0
I am using Rasa-core which uses the fbmessenger as facebook connector, Issue is when my bot takes long time to respond which usually happens when some API is being called I start getting the same message back from messenger no mattter what is being typed by user .So I searched a bit and I came to this conclusion that facebook sends the same message when it doesn't get a response in few seconds .OR it may be due to my localtunnel being patchy.

Answer concurrent messages

Hi everyone, first of all thank you in advance for your patience. I have a question: I noticed that using standard Flask configuration (as in the example), the library processes one message at a time. Therefore, I changed Flask WSGI server to gevent, to handle multiple concurrent connections. However, if two users send concurrent messages, the answers seem to be randomly mixing up. I noticed that send method of BaseMessenger class uses last_message, which doesn't seem to be thread-safe. Therefore, in the class extending BaseMessenger class, I implemented some sort of override of the send method like this:

    def raw_send(self, recipient_id, message_data, messaging_type='RESPONSE', tag=None):
        self.client.send(payload=self.build_message_template(message_data), 
                         entry={"sender": {"id": recipient_id}},
                         messaging_type=messaging_type,
                         tag=tag)

Did I do the right thing? Is there a way to use the library with concurrent requests? At the moment I am using fbmessenger 5.3.2. I hope my question isn't stupid. Thank you again.

Sending a message to a specific user by ID

Would you like assistance or advice?
Assistance.
Issue description
I can't seem to be able to send a message to a specific user after getting his ID
Steps to reproduce
I get the recipient_id through sender=self.get_user_id()
Then why I try to use self.send({'text': "msg"}, sender, 'RESPONSE') it fails with the error:
ValueError: '2595091087229339' is not a valid 'messaging_type'
It seems like it's handling the variable sender as if it's the messaging_type not recipient_id
Any idea what am I doing wrong?

  • fbmessenger version: 6.0.0 / master@commit
  • python version: 3.7.1

Django integration

I have a django project and I will like to build a chatbot for it, but instead of running a different flask server i would like to build a new app inside the project with the bot functionality, any idea of how to do this?

error in response of init_bot()

[2018-08-29 04:53:10,185] DEBUG in bot: Response: {'error': {'message': '(#100) Requires one of the params: get_started,persistent_menu,target_audience,whitelisted_domains,greeting,account_linking_url,payment_settings,home_url', 'type': 'OAuthException', 'code': 100, 'fbtrace_id': 'FncS+nanDCj'}}

Is there a way to send local file?

Would you like assistance or advice?

advice

Issue description

Would like to send a file from a local filesystem.

file = attachments.File(url="file://./file.txt")
client.send(file.to_dict(), recipient_id=user_id, messaging_type='RESPONSE')

Steps to reproduce

the above code returns "(#100) file://./file.txt should represent a valid URL)"
also tried other variations of file:// syntax as well as simply ./file.txt and file.txt

Traceback or other info

  • fbmessenger version: master@commit
  • python version: 3.7
  • Facebook Messenger API version: 13

Thanks!

API version

How to set Facebook messenger API version ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.