Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ dist/
test.py

.idea/
.vscode/

# Created by https://www.gitignore.io/api/python

Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ Special thanks to the following people who has contributed to this project!
* [bildzeitung](https://github.com/bildzeitung)
* [Cretezy](https://github.com/Cretezy)
* [Onyenanu](https://github.com/madewithkode)
* [Mohamed Taha](https://github.com/mohamed-taha)
125 changes: 94 additions & 31 deletions pymessenger/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ class NotificationType(Enum):
no_push = "NO_PUSH"


class MessagingType(Enum):
response = "RESPONSE"
update = "UPDATE"
message_tag = "MESSAGE_TAG"

class MessageTag(Enum):
confirmed_event_update = "CONFIRMED_EVENT_UPDATE"
post_purchase_update = "POST_PURCHASE_UPDATE"
account_update = "ACCOUNT_UPDATE"
human_agent = "HUMAN_AGENT"

class Bot:
def __init__(self, access_token, **kwargs):
"""
Expand Down Expand Up @@ -42,25 +53,34 @@ def auth_args(self):
self._auth_args = auth
return self._auth_args

def send_recipient(self, recipient_id, payload, notification_type=NotificationType.regular):
def send_recipient(self, recipient_id, payload, notification_type=NotificationType.regular,
messaging_type=MessagingType.response, tag=MessageTag.account_update):
payload['recipient'] = {
'id': recipient_id
}
payload['notification_type'] = notification_type.value
payload['messaging_type'] = messaging_type.value
if messaging_type == MessagingType.message_tag:
payload['tag'] = tag.value
return self.send_raw(payload)

def send_message(self, recipient_id, message, notification_type=NotificationType.regular):
def send_message(self, recipient_id, message, notification_type=NotificationType.regular,
messaging_type=MessagingType.response, tag=MessageTag.account_update):
return self.send_recipient(recipient_id, {
'message': message
}, notification_type)
'message': message,
}, notification_type, messaging_type, tag)

def send_attachment(self, recipient_id, attachment_type, attachment_path,
notification_type=NotificationType.regular):
notification_type=NotificationType.regular,
messaging_type=MessagingType.response,
tag=MessageTag.account_update):
"""Send an attachment to the specified recipient using local path.
Input:
recipient_id: recipient id to send to
attachment_type: type of attachment (image, video, audio, file)
attachment_path: Path of attachment
messaging_type: message type
tag: message tag in case of the message type is tag
Output:
Response from API as <dict>
"""
Expand All @@ -71,6 +91,7 @@ def send_attachment(self, recipient_id, attachment_type, attachment_path,
}
},
'notification_type': notification_type,
'messaging_type': messaging_type.value,
'message': {
{
'attachment': {
Expand All @@ -81,6 +102,8 @@ def send_attachment(self, recipient_id, attachment_type, attachment_path,
},
'filedata': (os.path.basename(attachment_path), open(attachment_path, 'rb'))
}
if messaging_type == MessagingType.message_tag:
payload['tag'] = tag.value
multipart_data = MultipartEncoder(payload)
multipart_header = {
'Content-Type': multipart_data.content_type
Expand All @@ -89,12 +112,16 @@ def send_attachment(self, recipient_id, attachment_type, attachment_path,
params=self.auth_args, headers=multipart_header).json()

def send_attachment_url(self, recipient_id, attachment_type, attachment_url,
notification_type=NotificationType.regular):
notification_type=NotificationType.regular,
messaging_type=MessagingType.response,
tag=MessageTag.account_update):
"""Send an attachment to the specified recipient using URL.
Input:
recipient_id: recipient id to send to
attachment_type: type of attachment (image, video, audio, file)
attachment_url: URL of attachment
messaging_type: message type
tag: message tag in case of the message type is tag
Output:
Response from API as <dict>
"""
Expand All @@ -105,27 +132,33 @@ def send_attachment_url(self, recipient_id, attachment_type, attachment_url,
'url': attachment_url
}
}
}, notification_type)
}, notification_type, messaging_type, tag)

def send_text_message(self, recipient_id, message, notification_type=NotificationType.regular):
def send_text_message(self, recipient_id, message, notification_type=NotificationType.regular,
messaging_type=MessagingType.response, tag=MessageTag.account_update):
"""Send text messages to the specified recipient.
https://developers.facebook.com/docs/messenger-platform/send-api-reference/text-message
Input:
recipient_id: recipient id to send to
message: message to send
messaging_type: message type
tag: message tag in case of the message type is tag
Output:
Response from API as <dict>
"""
return self.send_message(recipient_id, {
'text': message
}, notification_type)
}, notification_type, messaging_type, tag)

def send_generic_message(self, recipient_id, elements, notification_type=NotificationType.regular):
def send_generic_message(self, recipient_id, elements, notification_type=NotificationType.regular,
messaging_type=MessagingType.response, tag=MessageTag.account_update):
"""Send generic messages to the specified recipient.
https://developers.facebook.com/docs/messenger-platform/send-api-reference/generic-template
Input:
recipient_id: recipient id to send to
elements: generic message elements to send
messaging_type: message type
tag: message tag in case of the message type is tag
Output:
Response from API as <dict>
"""
Expand All @@ -137,15 +170,18 @@ def send_generic_message(self, recipient_id, elements, notification_type=Notific
"elements": elements
}
}
}, notification_type)
}, notification_type, messaging_type, tag)

def send_button_message(self, recipient_id, text, buttons, notification_type=NotificationType.regular):
def send_button_message(self, recipient_id, text, buttons, notification_type=NotificationType.regular,
messaging_type=MessagingType.response, tag=MessageTag.account_update):
"""Send text messages to the specified recipient.
https://developers.facebook.com/docs/messenger-platform/send-api-reference/button-template
Input:
recipient_id: recipient id to send to
text: text of message to send
buttons: buttons to send
messaging_type: message type
tag: message tag in case of the message type is tag
Output:
Response from API as <dict>
"""
Expand All @@ -158,115 +194,142 @@ def send_button_message(self, recipient_id, text, buttons, notification_type=Not
"buttons": buttons
}
}
}, notification_type)
}, notification_type, messaging_type, tag)

def send_action(self, recipient_id, action, notification_type=NotificationType.regular):
def send_action(self, recipient_id, action, notification_type=NotificationType.regular,
messaging_type=MessagingType.response, tag=MessageTag.account_update):
"""Send typing indicators or send read receipts to the specified recipient.
https://developers.facebook.com/docs/messenger-platform/send-api-reference/sender-actions

Input:
recipient_id: recipient id to send to
action: action type (mark_seen, typing_on, typing_off)
messaging_type: message type
tag: message tag in case of the message type is tag
Output:
Response from API as <dict>
"""
return self.send_recipient(recipient_id, {
'sender_action': action
}, notification_type)
}, notification_type, messaging_type, tag)

def send_image(self, recipient_id, image_path, notification_type=NotificationType.regular):
def send_image(self, recipient_id, image_path, notification_type=NotificationType.regular,
messaging_type=MessagingType.response, tag=MessageTag.account_update):
"""Send an image to the specified recipient.
Image must be PNG or JPEG or GIF (more might be supported).
https://developers.facebook.com/docs/messenger-platform/send-api-reference/image-attachment
Input:
recipient_id: recipient id to send to
image_path: path to image to be sent
messaging_type: message type
tag: message tag in case of the message type is tag
Output:
Response from API as <dict>
"""
return self.send_attachment(recipient_id, "image", image_path, notification_type)
return self.send_attachment(recipient_id, "image", image_path, notification_type, messaging_type, tag)

def send_image_url(self, recipient_id, image_url, notification_type=NotificationType.regular):
def send_image_url(self, recipient_id, image_url, notification_type=NotificationType.regular,
messaging_type=MessagingType.response, tag=MessageTag.account_update):
"""Send an image to specified recipient using URL.
Image must be PNG or JPEG or GIF (more might be supported).
https://developers.facebook.com/docs/messenger-platform/send-api-reference/image-attachment
Input:
recipient_id: recipient id to send to
image_url: url of image to be sent
messaging_type: message type
tag: message tag in case of the message type is tag
Output:
Response from API as <dict>
"""
return self.send_attachment_url(recipient_id, "image", image_url, notification_type)
return self.send_attachment_url(recipient_id, "image", image_url, notification_type, messaging_type, tag)

def send_audio(self, recipient_id, audio_path, notification_type=NotificationType.regular):
def send_audio(self, recipient_id, audio_path, notification_type=NotificationType.regular,
messaging_type=MessagingType.response, tag=MessageTag.account_update):
"""Send audio to the specified recipient.
Audio must be MP3 or WAV
https://developers.facebook.com/docs/messenger-platform/send-api-reference/audio-attachment
Input:
recipient_id: recipient id to send to
audio_path: path to audio to be sent
messaging_type: message type
tag: message tag in case of the message type is tag
Output:
Response from API as <dict>
"""
return self.send_attachment(recipient_id, "audio", audio_path, notification_type)
return self.send_attachment(recipient_id, "audio", audio_path, notification_type, messaging_type, tag)

def send_audio_url(self, recipient_id, audio_url, notification_type=NotificationType.regular):
def send_audio_url(self, recipient_id, audio_url, notification_type=NotificationType.regular,
messaging_type=MessagingType.response, tag=MessageTag.account_update):
"""Send audio to specified recipient using URL.
Audio must be MP3 or WAV
https://developers.facebook.com/docs/messenger-platform/send-api-reference/audio-attachment
Input:
recipient_id: recipient id to send to
audio_url: url of audio to be sent
messaging_type: message type
tag: message tag in case of the message type is tag
Output:
Response from API as <dict>
"""
return self.send_attachment_url(recipient_id, "audio", audio_url, notification_type)
return self.send_attachment_url(recipient_id, "audio", audio_url, notification_type, messaging_type, tag)

def send_video(self, recipient_id, video_path, notification_type=NotificationType.regular):
def send_video(self, recipient_id, video_path, notification_type=NotificationType.regular,
messaging_type=MessagingType.response, tag=MessageTag.account_update):
"""Send video to the specified recipient.
Video should be MP4 or MOV, but supports more (https://www.facebook.com/help/218673814818907).
https://developers.facebook.com/docs/messenger-platform/send-api-reference/video-attachment
Input:
recipient_id: recipient id to send to
video_path: path to video to be sent
messaging_type: message type
tag: message tag in case of the message type is tag
Output:
Response from API as <dict>
"""
return self.send_attachment(recipient_id, "video", video_path, notification_type)
return self.send_attachment(recipient_id, "video", video_path, notification_type, messaging_type, tag)

def send_video_url(self, recipient_id, video_url, notification_type=NotificationType.regular):
def send_video_url(self, recipient_id, video_url, notification_type=NotificationType.regular,
messaging_type=MessagingType.response, tag=MessageTag.account_update):
"""Send video to specified recipient using URL.
Video should be MP4 or MOV, but supports more (https://www.facebook.com/help/218673814818907).
https://developers.facebook.com/docs/messenger-platform/send-api-reference/video-attachment
Input:
recipient_id: recipient id to send to
video_url: url of video to be sent
messaging_type: message type
tag: message tag in case of the message type is tag
Output:
Response from API as <dict>
"""
return self.send_attachment_url(recipient_id, "video", video_url, notification_type)
return self.send_attachment_url(recipient_id, "video", video_url, notification_type, messaging_type, tag)

def send_file(self, recipient_id, file_path, notification_type=NotificationType.regular):
def send_file(self, recipient_id, file_path, notification_type=NotificationType.regular,
messaging_type=MessagingType.response, tag=MessageTag.account_update):
"""Send file to the specified recipient.
https://developers.facebook.com/docs/messenger-platform/send-api-reference/file-attachment
Input:
recipient_id: recipient id to send to
file_path: path to file to be sent
messaging_type: message type
tag: message tag in case of the message type is tag
Output:
Response from API as <dict>
"""
return self.send_attachment(recipient_id, "file", file_path, notification_type)
return self.send_attachment(recipient_id, "file", file_path, notification_type, messaging_type, tag)

def send_file_url(self, recipient_id, file_url, notification_type=NotificationType.regular):
def send_file_url(self, recipient_id, file_url, notification_type=NotificationType.regular,
messaging_type=MessagingType.response, tag=MessageTag.account_update):
"""Send file to the specified recipient.
https://developers.facebook.com/docs/messenger-platform/send-api-reference/file-attachment
Input:
recipient_id: recipient id to send to
file_url: url of file to be sent
messaging_type: message type
tag: message tag in case of the message type is tag
Output:
Response from API as <dict>
"""
return self.send_attachment_url(recipient_id, "file", file_url, notification_type)
return self.send_attachment_url(recipient_id, "file", file_url, notification_type, messaging_type, tag)

def get_user_info(self, recipient_id, fields=None):
"""Getting information about the user
Expand Down
31 changes: 29 additions & 2 deletions test/bot_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os

from pymessenger.bot import Bot
from pymessenger.bot import Bot, MessagingType, MessageTag
from pymessenger import Element, Button

TOKEN = os.environ.get('TOKEN')
Expand All @@ -23,6 +23,13 @@ def test_text_message():
assert result.get('message_id') is not None
assert result.get('recipient_id') is not None

def test_tag_text_message():
result = bot.send_text_message(recipient_id, "test",
messaging_type=MessagingType.message_tag, tag=MessageTag.confirmed_event_update)
assert type(result) is dict
assert result.get('message_id') is not None
assert result.get('recipient_id') is not None


def test_elements():
image_url = 'https://lh4.googleusercontent.com/-dZ2LhrpNpxs/AAAAAAAAAAI/AAAAAAAA1os/qrf-VeTVJrg/s0-c-k-no-ns/photo.jpg'
Expand All @@ -35,13 +42,33 @@ def test_elements():
assert result.get('message_id') is not None
assert result.get('recipient_id') is not None

def test_elements_in_tag_message():
image_url = 'https://lh4.googleusercontent.com/-dZ2LhrpNpxs/AAAAAAAAAAI/AAAAAAAA1os/qrf-VeTVJrg/s0-c-k-no-ns/photo.jpg'
elements = []
element = Element(title="Arsenal", image_url=image_url, subtitle="Click to go to Arsenal website.",
item_url="http://arsenal.com")
elements.append(element)
result = bot.send_generic_message(recipient_id, elements,
messaging_type=MessagingType.message_tag, tag=MessageTag.confirmed_event_update)
assert type(result) is dict
assert result.get('message_id') is not None
assert result.get('recipient_id') is not None


def test_image_url():
image_url = 'https://lh4.googleusercontent.com/-dZ2LhrpNpxs/AAAAAAAAAAI/AAAAAAAA1os/qrf-VeTVJrg/s0-c-k-no-ns/photo.jpg'
result = bot.send_image_url(recipient_id, image_url)
assert type(result) is dict
assert result.get('message_id') is not None
assert result.get('recipient_id') is not None

def test_image_url_in_tag_message():
image_url = 'https://lh4.googleusercontent.com/-dZ2LhrpNpxs/AAAAAAAAAAI/AAAAAAAA1os/qrf-VeTVJrg/s0-c-k-no-ns/photo.jpg'
result = bot.send_image_url(recipient_id, image_url,
messaging_type=MessagingType.message_tag, tag=MessageTag.account_update)
assert type(result) is dict
assert result.get('message_id') is not None
assert result.get('recipient_id') is not None

def test_image_gif_url():
image_url = 'https://media.giphy.com/media/rl0FOxdz7CcxO/giphy.gif'
Expand Down Expand Up @@ -73,4 +100,4 @@ def test_fields():
fields = ['first_name', 'last_name']
user_profile = bot.get_user_info(recipient_id, fields=fields)
assert user_profile is not None
assert len(user_profile.keys()) == len(fields)
assert len(user_profile.keys()) == len(fields) + 1