diff --git a/.gitignore b/.gitignore index bd64e12..bc0d8d4 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ dist/ test.py .idea/ +.vscode/ # Created by https://www.gitignore.io/api/python diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 2e05245..9f761ef 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -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) diff --git a/pymessenger/bot.py b/pymessenger/bot.py index 5a7311c..75dc3a3 100644 --- a/pymessenger/bot.py +++ b/pymessenger/bot.py @@ -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): """ @@ -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 """ @@ -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': { @@ -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 @@ -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 """ @@ -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 """ 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 """ @@ -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 """ @@ -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 """ 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 """ - 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 """ - 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 """ - 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 """ - 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 """ - 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 """ - 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 """ - 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 """ - 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 diff --git a/test/bot_test.py b/test/bot_test.py index 06077d1..f0a5ff3 100644 --- a/test/bot_test.py +++ b/test/bot_test.py @@ -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') @@ -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' @@ -35,6 +42,18 @@ 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' @@ -42,6 +61,14 @@ def test_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' @@ -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