Package: rcs-chatbot
rcs_chatbotA Python SDK forRCS MaaP chatbots.Installationpipinstallrcs_chatbotExampleSee more examples inthe example folder.importflaskimportloggingimportrcs_chatbotchatbot=rcs_chatbot.Chatbot("API_URL","BOT_ID","TOKEN",None,logging.DEBUG)app=flask.Flask(__name__)@app.route('/',methods=['POST'])defevent():try:chatbot.processEvent(flask.request.get_json())return"ok",200exceptmaap.RequestFailedasex:print("Request failed: "+str(ex))return"ok",200@chatbot.registerEventHandler(rcs_chatbot.EventType.MESSAGE)defmessageHandler(event):userContact=NonechatId=Noneif"userContact"inevent["messageContact"]:userContact=event["messageContact"]["userContact"]if"chatId"inevent["messageContact"]:chatId=event["messageContact"]["chatId"]contact=rcs_chatbot.MessageContact(userContact,chatId)suggestions=rcs_chatbot.Suggestions()suggestions.addReply("reply","reply")suggestions.addUrlAction("url","url","http://example.com")chatbot.sendMessage(contact,"You wrote: "+event["RCSMessage"]["textMessage"],suggestions)@chatbot.registerEventHandler(rcs_chatbot.EventType.ISTYPING)defisTypingHandler(event):print("isTypingHandler")@chatbot.registerEventHandler(rcs_chatbot.EventType.MESSAGESTATUS)defmessageStatusHandler(event):print("messageStatusHandler")@chatbot.registerEventHandler(rcs_chatbot.EventType.FILESTATUS)deffileStatusHandler(event):print("fileStatusHandler")@chatbot.registerEventHandler(rcs_chatbot.EventType.RESPONSE)defresponseHandler(event):print("responseHandler")@chatbot.registerEventHandler(rcs_chatbot.EventType.ALIAS)defaliasHandler(event):print("aliasHandler")@chatbot.registerEventHandler(rcs_chatbot.EventType.NEWUSER)defnewUserHandler(event):print("newUserHandler")if__name__=='__main__':app.run(port=5000,debug=False)Instead of a simple message, you can also usesendMessageto send anAudioMessage, etc. Show below is
how to send aRichcardCarouselmessage.@chatbot.registerEventHandler(maap.EventType.MESSAGE)defmessageHandler(event):userContact=NonechatId=Noneif"userContact"inevent["messageContact"]:userContact=event["messageContact"]["userContact"]if"chatId"inevent["messageContact"]:chatId=event["messageContact"]["chatId"]contact=maap.MessageContact(userContact,chatId)card1=maap.Richcard()card1.setTitle("title")card2=maap.Richcard()card2.setTitle("title")carousel=maap.RichcardCarousel()carousel.addRichcard(card1)carousel.addRichcard(card2)chatbot.sendMessage(contact,carousel)UsageChatbot FunctionsconstructorsendMessage(recipient, content, suggestions = None)Sends a message withcontentand optionalsuggestionsto the targetrecipient.recipient- Object: AMessageContactobject.content- Object: The message payload. Either a string, anAudioMessageobject, aFileMessageobject, aGeolocationPushMessageobject, aRichcardobject, or aRichcardCarouselobject.suggestions- (Optional) Object: ASuggestionsobject.getMessageStatus(messageId)Gets the status of a message withmessageId.messageId- String: The message identifier.updateMessageStatus(messageId, status)Updates the status of a message withmessageIdtostatus.messageId- String: The message identifier.status- String: The requested status. Needs to be eitherrcs_chatbot.MessageStatus.CANCELLEDorrcs_chatbot.MessageStatus.DISPLAYED.getContactCapabilities(userContact, chatId)Gets the capabilities for a subscriber. EitheruserContactorchatIdneeds to be specified.userContact- String: The subscriber's MSISDN.chatId- String: The user's anonymous token.uploadFile(path, url, fileType, until)Uploads a file of typefileTypeto the MaaP content storage until it expires at dateuntilEitherpathorurlneeds to be specified.path- String: The path to the file.url- String: The URL to the file.fileType- String: The file's content type.until- Date: The date at which time the content should be expired.deleteFile(fileId)Deletes a file with identifierfileIdfrom the MaaP content storage.fileId- String: The file identifier.getFile(fileId)Gets info for a file with identifierfileIdfrom the MaaP content storage.fileId- String: The file identifier.startTyping(recipient)Starts the 'is typing' indicator for the targetrecipient.recipient- Object: AMessageContactobject.stopTyping(recipient)Stops the 'is typing' indicator for the targetrecipient.recipient- Object: AMessageContactobject.processEvent(json)The main middleware for your bot's webhook. It parses the message payload, and fire the appropriate event.FileMessage FunctionsAnFileMessageobject representes a file and has the following properties:PropertyTypeMandatoryDescriptionfileUrlStringYesThe URL of the file.fileNameStringNoThe file name.fileMIMETypeStringNoThe MIME type of the file.fileSizeNumberNoThe size of the file.thumbnailUrlStringNoThe URL of the thumbnail.thumbnailFileNameStringNoThe file name of the thumbnail.thumbnailMIMETypeStringNoThe MIME type of the thumbnail.thumbnailFileSizeNumberNoThe size of the thumbnail.constructor(fileUrl)Returns a newFileMessageinstance.fileUrl- String: The URL of the file.setFileName(fileName)Set thefileNameproperty.fileName- String: The file name.setFileMIMEType(fileMIMEType)Set thefileMIMETypeproperty.fileMIMEType- String: The MIME type of the file.setFileSize(fileSize)Set thefileSizeproperty.fileSize- Number: The size of the file.setThumbnailUrl(thumbnailUrl)Set thethumbnailUrlproperty.thumbnailUrl- String: The URL of the thumbnail.setThumbnailFileName(thumbnailFileName)et thethumbnailFileNameproperty.thumbnailFileName- String: The file name of the thumbnail.setThumbnailMIMEType(thumbnailMIMEType)Set thethumbnailMIMETypeproperty.thumbnailMIMEType- String: The MIME type of the thumbnail.setThumbnailFileSize(thumbnailFileSize)Set thethumbnailFileSizeproperty.thumbnailFileSize- Number: The size of the thumbnail.AudioMessage FunctionsAnAudioMessageobject representes an audio file and has the following properties:PropertyTypeMandatoryDescriptionfileUrlStringYesThe URL of the file.fileNameStringNoThe file name.fileMIMETypeStringNoThe MIME type of the file.fileSizeNumberNoThe size of the file.playingLengthNumberNoThe playing length of the audio.constructor(fileUrl)Returns a newAudioMessageinstance.fileUrl- String: The URL of the file.setFileName(fileName)Set thefileNameproperty.fileName- String: The file name.setFileMIMEType(fileMIMEType)Set thefileMIMETypeproperty.fileMIMEType- String: The MIME type of the file.setFileSize(fileSize)Set thefileSizeproperty.fileSize- Number: The size of the file.setPlayingLength(playingLength)Set theplayingLengthproperty.playingLength- Number: The playing length of the audio.GeolocationPushMessagePropertyTypeMandatoryDescriptionposStringYesThis are the coordinates in WGS 84 (latitude, longitude) decimal notation. Example "26.118 1289 - 80.1283921"labelStringNoThis can be used to tag the nature of the location.timestampStringNoThis is the time when the location information was pushed.expiryStringNoThis is an absolute date at which time the recipient is no longer permitted to possess the location information.timeOffsetNumberNoThis is the time zone where the location information was pushed, expressed as the number of minutes away from UTC.radiusNumberNoThe radius of the circle will be represented in meters.constructor(pos)Returns a newGeolocationPushMessageinstance. This is a geolocation push to be sent via RCS Geolocation Push.pos- String: This are the coordinates in WGS 84 (latitude, longitude) decimal notation.setLabel(label)Set thelabelproperty.label- String: This can be used to tag the nature of the location.setTimestamp(timestamp)Set thetimestampproperty.timestamp- String: This is the time when the location information was pushed.setExpiry(expiry)Set theexpiryproperty.expiry- String: This is an absolute date at which time the recipient is no longer permitted to possess the location information.setTimeOffset(timeOffset)Set thetimeOffsetproperty.timeOffset- Number: This is the time zone where the location information was pushed, expressed as the number of minutes away from UTC.setRadius(radius)Set theradiusproperty.radius- Number: The radius of the circle will be represented in meters.Richcard Functionsconstructor()Returns a newRichcardinstance.Returns a newRichcardinstance.setCardOrientation(cardOrientation)Set the orientation of the card.cardOrientation- String: Eitherrcs_chatbot.CardOrientation.HORIZONTALorrcs_chatbot.CardOrientation.VERTICAL.setImageAlignment(imageAlignment)Set the alignment of the image on the card.imageAlignment- String: Eitherrcs_chatbot.ImageAlignment.LEFTorrcs_chatbot.ImageAlignment.RIGHT.setMedia(mediaUrl, mediaContentType, mediaFileSize, height, [thumbnailUrl], [thumbnailContentType], [thumbnailFileSize], [contentDescription])Set the media (image) to be displayed on the richcard.mediaUrl- String: The URL to the image.mediaContentType- String: The content type of the image.mediaFileSize- Number: The size of the image.height- String: Eitherrcs_chatbot.MediaHeight.SHORTorrcs_chatbot.MediaHeight.MEDIUMorrcs_chatbot.MediaHeight.TALL.thumbnailUrl- (Optional) String: The URL to the thumbnail for the image.thumbnailContentType- (Optional) String: The content type of the thumbnail.thumbnailFileSize- (Optional) Number: The size of the thumbnail.contentDescription- (Optional) String: Textual description of media content.ThethumbnailUrlproperty is optional, but if used,thumbnailContentTypeandthumbnailFileSizemust be provided as well.setTitle(title)Set the title of the card.title- String: The title.setDescription(description)Set the description of the card.description- String: The description.setSuggestions(suggestions)Add suggestions to the card.suggestions- Suggestions: The suggestions.RichcardCarousel Functionsconstructor()Returns a newRichcardCarouselinstance.setCardWidth(cardWidth)Set the width of the cards in the carousel.cardWidth- String: Eitherrcs_chatbot.CardWidth.SMALLorrcs_chatbot.CardWidth.MEDIUM.addRichcard(richcard)Add a card to the carousel.richcard- Richcard: TheRichcardobject.Suggestions FunctionsSuggested Replies consist of a display text and a set of postback data.Suggested Actions are grouped into seven different categories supporting a total of twelve different suggested actions:urlAction:openUrl - Opens a web site or app via deep linking.dialerAction:dialPhoneNumber - Calls a phone number via the user's dialer app.dialEnrichedCall - Start an Enriched Call via the user’s dialer app.dialVideoCall - Start a video call via the user’s dialer app.mapAction:showLocation - Show location(s) on a map for given coordinates or search query.requestLocationPush - Request for a one-time geo location push.calendarAction:createCalendarEvent - Creates a new event on the user's calendar.composeAction:composeTextMessage - Compose a draft text message.composeRecordingMessage - Compose a draft message and start recording audio or video.deviceAction:requestDeviceSpecifics - Request for a one-time share of device specifics (device model, operating system version, messaging client identifier and version, and remaining battery charge in minutes).settingsAction:disableAnonymization - Ask the user to disable the anonymization setting.enableDisplayedNotifications - Ask the user to enable sending displayed notifications.Most actions allow fallback URLs in case a user does not have any app of the required type installed. Chatbot platforms can use the fallback URL to suggest an appropriate app to the user.constructor()Returns a newSuggestionsinstance.addReply(displayText, postbackData)On-the-wire example:{"reply":{"displayText":"Yes","postback":{"data":"set_by_chatbot_reply_yes"}}}addUrlAction(displayText, postbackData, url)On-the-wire example:{"action":{"urlAction":{"openUrl":{"url":"https://www.google.com"}},"displayText":"Open website or deep link","postback":{"data":"set_by_chatbot_open_url"}}}addDialerAction(displayText, postbackData, dialType, phoneNumber, fallbackUrl, subject = None)On-the-wire example:{"action":{"dialerAction":{"dialPhoneNumber":{"phoneNumber":"+1650253000"}},"displayText":"Call a phone number","postback":{"data":"set_by_chatbot_dial_phone_number"}}},{"action":{"dialerAction":{"dialEnrichedCall":{"phoneNumber":"+1650253000","subject":"The optional subject for the enriched call"}},"displayText":"Start enriched call","postback":{"data":"set_by_chatbot_dial_enriched_call"}}},{"action":{"dialerAction":{"dialVideoCall":{"phoneNumber":"+1650253000"}},"displayText":"Start video call","postback":{"data":"set_by_chatbot_dial_video_call"}}}addRequestLocationPushMapAction(displayText, postbackData)On-the-wire example:{"action":{"mapAction":{"requestLocationPush":{}},"displayText":"Request a geo location","postback":{"data":"set_by_chatbot_request_location_push"}}}addShowLocationMapAction(displayText, postbackData, latitude, longitude, label, query, fallbackUrl)On-the-wire example:{"action":{"mapAction":{"showLocation":{"location":{"latitude":37.4220041,"longitude":-122.0862515,"label":"Googleplex"},"fallbackUrl":"https://www.google.com/maps/@37.4219162,-122.078063,15z"}},"displayText":"Show location on a map","postback":{"data":"set_by_chatbot_show_location"}}},{"action":{"mapAction":{"showLocation":{"location":{"query":"restaurants"},"fallbackUrl":"https://www.google.com/maps/search/restaurants"}},"displayText":"Search location(s) on map","postback":{"data":"set_by_chatbot_search_locations"}}}addCalendarAction(displayText, postbackData, startTime, endTime, title, description, fallbackUrl)On-the-wire example:{"action":{"calendarAction":{"createCalendarEvent":{"startTime":"2017-03-14T00:00:00Z","endTime":"2017-03-14T23:59:59Z","title":"Meeting","description":"GSG review meeting"}},"displayText":"Schedule Meeting","postback":{"data":"set_by_chatbot_create_calendar_event"}}}addTextComposeAction(displayText, postbackData, phoneNumber, text)On-the-wire example:{"action":{"composeAction":{"composeTextMessage":{"phoneNumber":"+1650253000","text":"Draft to go into the send message text field."}},"displayText":"Draft a text message","postback":{"data":"set_by_chatbot_compose_text_message"}}}addRecordingComposeAction(displayText, postbackData, phoneNumber, type)On-the-wire example:{"action":{"composeAction":{"composeRecordingMessage":{"phoneNumber":"+1650253000","type":"VIDEO"}},"displayText":"Record audio or video","postback":{"data":"set_by_chatbot_compose_recording_message"}}}addDeviceAction(displayText, postbackData)On-the-wire example:{"action":{"deviceAction":{"requestDeviceSpecifics":{}},"displayText":"Request device specifics","postback":{"data":"set_by_chatbot_request_device_specifics"}}}addSettingsAction(displayText, postbackData, settingsType)On-the-wire example:{"action":{"settingsAction":{"disableAnonymization":{}},"displayText":"Share your phone number","postback":{"data":"set_by_chatbot_disable_anonymization"}}},{"action":{"settingsAction":{"enableDisplayedNotifications":{}},"displayText":"Send read receipts","postback":{"data":"set_by_chatbot_enable_displayed_notifications"}}}EventsA different event is triggered for each type of event an RCS chatbot can receive. Below are all
the possible events with an example of the payload they provide.EventType.MESSAGETriggered when a 'message' event is sent to the bot.event- Object: An object containing the 'message' event payload.Example usage:@chatbot.registerEventHandler(rcs_chatbot.EventType.MESSAGE)defmessageHandler(event):print("messageHandler")Sample payload:{"RCSMessage":{"msgId":"Xs8CI3tdf","textMessage":"hello world","timestamp":"2017-09-26T01:33:20.315Z"},"messageContact":{"userContact":"+14251234567"},"event":"message"}EventType.ISTYPINGTriggered when an 'isTyping' event is sent to the bot.event- Object: An object containing the 'isTyping' event payload.Example usage:@chatbot.registerEventHandler(rcs_chatbot.EventType.ISTYPING)defisTypingHandler(event):print("isTypingHandler")Sample payload:{"RCSMessage":{"msgId":"Xs8CI3tdf","isTyping":"active","timestamp":"2017-09-26T01:33:20.315Z"},"messageContact":{"userContact":"+14251234567"},"event":"isTyping"}EventType.MESSAGESTATUSTriggered when a 'messageStatus' event is sent to the bot.event- Object: An object containing the 'messageStatus' event payload.Example usage:@chatbot.registerEventHandler(rcs_chatbot.EventType.MESSAGESTATUS)defmessageStatusHandler(event):print("messageStatusHandler")Sample payload:{"RCSMessage":{"msgId":"MzJmajlmamVzZGZ8bmk5MHNlbmRmZTAz","status":"displayed","timestamp":"2017-09-26T01:33:20.315Z"},"messageContact":{"userContact":"+14251234567"},"event":"messageStatus"}EventType.FILESTATUSTriggered when a 'fileStatus' event is sent to the bot.event- Object: An object containing the 'fileStatus' event payload.Example usage:@chatbot.registerEventHandler(rcs_chatbot.EventType.FILESTATUS)deffileStatusHandler(event):print("fileStatusHandler")Sample payload:{"file":{"fileId":"MzJmajlmamVzZGZ8bmk5MHNlbmRmZTAz","fileUrl":"http://www.example.com/files/f.jpg","fileSize":123456,"status":"ready","validity":"2017-10-03T22:31:00.597Z"},"event":"fileStatus"}EventType.RESPONSETriggered when a 'response' event is sent to the bot.event- Object: An object containing the 'response' event payload.Example usage:@chatbot.registerEventHandler(rcs_chatbot.EventType.RESPONSE)defresponseHandler(event):print("responseHandler")Sample payload:{"RCSMessage":{"msgId":"MzJmajlmamVzZGZ8bmk5MHNlbmRmZTAz","suggestedResponse":{"response":{"action":{"displayText":"Visit Website","postback":{"data":"set_by_chatbot_reply_yes"}}}},"timestamp":"2017-09-26T01:33:20.315Z"},"messageContact":{"userContact":"+14251234567"},"event":"response"}EventType.ALIASTriggered when a 'alias' event is sent to the bot.event- Object: An object containing the 'alias' event payload.Example usage:@chatbot.registerEventHandler(rcs_chatbot.EventType.ALIAS)defaliasHandler(event):print("aliasHandler")Sample payload:{"RCSMessage":{"msgId":"MzJmajlmamVzZGZ8bmk5MHNlbmRmZTAz","timestamp":"2017-09-26T01:33:20.315Z"},"messageContact":{"userContact":"+14251234567","chatId":"93JF93SEIJFE"},"event":"alias"}EventType.NEWUSERTriggered when a 'newUser' event is sent to the bot.event- Object: An object containing the 'newUser' event payload.Example usage:@chatbot.registerEventHandler(rcs_chatbot.EventType.NEWUSER)defnewUserHandler(event):print("newUserHandler")Sample payload:{"RCSMessage":{"msgId":"MzJmajlmamVzZGZ8bmk5MHNlbmRmZTAz","suggestedResponse":{"response":{"reply":{"displayText":"Start Chat","postback":{"data":"new_bot_user_initiation"}}}},"timestamp":"2017-09-26T01:33:20.315Z"},"messageContact":{"userContact":"+14251234567"},"event":"newUser"}To DoVerify constraints before sendingLook for missing fields like trafficType (there may be more)