{"id":38669102,"url":"https://github.com/pvangool/rcs-maap-bot","last_synced_at":"2026-01-17T09:53:01.185Z","repository":{"id":35130903,"uuid":"175438351","full_name":"pvangool/rcs-maap-bot","owner":"pvangool","description":"A Node client for RCS MaaP chatbots","archived":false,"fork":false,"pushed_at":"2023-02-21T22:18:59.000Z","size":60,"stargazers_count":5,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"develop","last_synced_at":"2025-09-27T02:58:46.484Z","etag":null,"topics":["bot","maap","rcs"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pvangool.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-13T14:34:09.000Z","updated_at":"2024-12-29T00:21:24.000Z","dependencies_parsed_at":"2023-01-15T14:26:54.499Z","dependency_job_id":null,"html_url":"https://github.com/pvangool/rcs-maap-bot","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/pvangool/rcs-maap-bot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pvangool%2Frcs-maap-bot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pvangool%2Frcs-maap-bot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pvangool%2Frcs-maap-bot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pvangool%2Frcs-maap-bot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pvangool","download_url":"https://codeload.github.com/pvangool/rcs-maap-bot/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pvangool%2Frcs-maap-bot/sbom","scorecard":{"id":750486,"data":{"date":"2025-08-11","repo":{"name":"github.com/pvangool/rcs-maap-bot","commit":"11fc0debb33922e91c44deffaec8bc73a91aeb85"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.5,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":0,"reason":"Found 0/20 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'develop'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 12 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":6,"reason":"4 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T20:12:00.414Z","repository_id":35130903,"created_at":"2025-08-22T20:12:00.414Z","updated_at":"2025-08-22T20:12:00.414Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28505565,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T06:57:29.758Z","status":"ssl_error","status_checked_at":"2026-01-17T06:56:03.931Z","response_time":85,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bot","maap","rcs"],"created_at":"2026-01-17T09:53:01.057Z","updated_at":"2026-01-17T09:53:01.133Z","avatar_url":"https://github.com/pvangool.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rcs-maap-bot\n[![npm version](https://img.shields.io/npm/v/rcs-maap-bot.svg)](https://www.npmjs.com/package/rcs-maap-bot)\n[![dependencies](https://david-dm.org/pvangool/rcs-maap-bot.svg)](https://david-dm.org/pvangool/rcs-maap-bot)\n[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)\n\nA Node client for [RCS MaaP chatbots](https://www.gsma.com/futurenetworks/wp-content/uploads/2017/11/FNW.11_v1.0.pdf).\n\nRequires Node \u003e=4.0.0.\n\n## Installation\n\n```bash\nnpm install rcs-maap-bot\n```\n\n## Example\n\nSee more examples in [the example folder](https://github.com/pvangool/rcs-maap-bot/tree/master/example).\n\n```js\nconst http = require('http')\nconst Maap = require('rcs-maap-bot')\n\nlet bot = new Maap.Bot({\n  token: 'TOKEN',\n  api_url: 'API_URL',\n  bot_id: 'BOT_ID'\n})\n\nbot.on('error', (err) =\u003e {\n  console.log(err.message)\n})\n\nbot.on('message', (payload, reply) =\u003e {\n  reply(\n    \"You wrote: \" + payload.RCSMessage.textMessage,\n    null,\n    (err, body) =\u003e {\n      if (err) throw err\n    }\n  )\n})\n\nhttp.createServer(bot.handleWebhook()).listen(3000)\n\nconsole.log('Echo bot server running on port 3000.')\n```\n\n`reply` Is a convenience function that calls `bot.sendMessage`, with the recipient already set to the message\nsender.\n\nAn example of calling `bot.sendMessage` with `suggestions` is below:\n\n```js\nbot.on('message', (payload, reply) =\u003e {\n  let suggestions = new Maap.Suggestions();\n  suggestions.addReply('English', 'Language_en');\n  suggestions.addReply('日本語', 'Language_jp');\n\n  bot.sendMessage(\n    payload.messageContact,\n    \"What language do you prefer?\",\n    suggestions,\n    (err, body) =\u003e {\n      if (err) throw err\n    }\n  )\n})\n```\n\nSpecifiying the `recipient` can be done by creating a `MessageContact` object:\n\n```js\nbot.on('message', (payload, reply) =\u003e {\n  let suggestions = new Maap.Suggestions();\n  suggestions.addReply('English', 'Language_en');\n  suggestions.addReply('日本語', 'Language_jp');\n\n  bot.sendMessage(\n    new Maap.MessageContact(\"+18055551234\", null),\n    \"What language do you prefer?\",\n    suggestions,\n    (err, body) =\u003e {\n      if (err) throw err\n    }\n  )\n})\n```\n\n## Usage\n\n### Bot Functions\n\n#### constructor(opts)\n\nReturns a new `Bot` instance.\n\n`opts` - Object\n\n* `token` - String: The authentication token for your bot.\n* `api_url` - String: The URL to the MaaP gateway endpoint (http://host:port/serverRoot/rcs/bot/v1).\n* `bot_id` - String: The identifier for your bot.\n\n#### sendMessage(recipient, content, [suggestions], [cb])\n\nSends a message with `content` and optional `suggestions` to the target `recipient`, and calls the callback if any. Returns a promise.\n\n* `recipient` - Object: A `MessageContact` object.\n* `content` - Object: The message payload. Either a string, an `AudioMessage` object, a `FileMessage` object, a `GeolocationPushMessage` object, a `Richcard` object, or a `RichcardCarousel` object.\n* `suggestions` - (Optional) Object: A `Suggestions` object.\n* `cb` - (Optional) Function: Called with `(err, body)` once the request has completed. `err` contains an error, if any, and `body` contains the response from the MaaP gateway.\n\n#### getMessageStatus(messageId, [cb])\n\nGets the status of a message with `messageId`, and calls the callback if any. Returns a promise.\n\n* `messageId` - String: The message identifier.\n* `cb` - (Optional) Function: Called with `(err, body)` once the request has completed. `err` contains an error, if any, and `body` contains the response from the MaaP gateway.\n\n#### updateMessageStatus(messageId, status, [cb])\n\nUpdates the status of a message with `messageId` to `status`, and calls the callback if any. Returns a promise.\n\n* `messageId` - String: The message identifier.\n* `status` - String: The requested status. Needs to be either `Maap.MESSAGE_STATUS_CANCELLED` or `Maap.MESSAGE_STATUS_DISPLAYED`.\n* `cb` - (Optional) Function: Called with `(err, body)` once the request has completed. `err` contains an error, if any, and `body` contains the response from the MaaP gateway.\n\n#### getContactCapabilities(userContact, chatId, [cb])\n\nGets the capabilities for a subscriber, and calls the callback if any. Returns a promise. Either `userContact` or `chatId` needs to be specified.\n\n* `userContact` - String: The subscriber's MSISDN.\n* `chatId` - String: The user's anonymous token.\n* `cb` - (Optional) Function: Called with `(err, body)` once the request has completed. `err` contains an error, if any, and `body` contains the response from the MaaP gateway.\n\n#### uploadFile(path, url, fileType, until, [cb])\n\nUploads a file of type `fileType` to the MaaP content storage until it expires at date `until`, and calls the callback if any. Returns a promise. Either `path` or `url` needs to be specified.\n\n* `path` - String: The path to the file.\n* `url` - String: The URL to the file.\n* `fileType` - String: The file's content type.\n* `until` - Date: The date at which time the content should be expired.\n* `cb` - (Optional) Function: Called with `(err, body)` once the request has completed. `err` contains an error, if any, and `body` contains the response from the MaaP gateway.\n\n#### deleteFile(fileId, [cb])\n\nDeletes a file with identifier `fileId` from the MaaP content storage, and calls the callback if any. Returns a promise.\n\n* `fileId` - String: The file identifier.\n* `cb` - (Optional) Function: Called with `(err, body)` once the request has completed. `err` contains an error, if any, and `body` contains the response from the MaaP gateway.\n\n#### getFile(fileId, [cb])\n\nGets info for a file with identifier `fileId` from the MaaP content storage, and calls the callback if any. Returns a promise.\n\n* `fileId` - String: The file identifier.\n* `cb` - (Optional) Function: Called with `(err, body)` once the request has completed. `err` contains an error, if any, and `body` contains the response from the MaaP gateway.\n\n#### startTyping(recipient, [cb])\n\nStarts the 'is typing' indicator for the target `recipient`, and calls the callback if any. Returns a promise.\n\n* `recipient` - Object: A `MessageContact` object.\n* `cb` - (Optional) Function: Called with `(err, body)` once the request has completed. `err` contains an error, if any, and `body` contains the response from the MaaP gateway.\n\n#### stopTyping(recipient, [cb])\n\nStops the 'is typing' indicator for the target `recipient`, and calls the callback if any. Returns a promise.\n\n* `recipient` - Object: A `MessageContact` object.\n* `cb` - (Optional) Function: Called with `(err, body)` once the request has completed. `err` contains an error, if any, and `body` contains the response from the MaaP gateway.\n\n#### handleWebhook()\n\nThe main middleware for your bot's webhook. Returns a function.\n\n#### handleRequest(json)\n\nThe underlying method used by `bot.handleWebhook()` to parse the message payload, and fire the appropriate events.\n\n### FileMessage Functions\n\nAn `FileMessage` object representes a file and has the following properties:\n\n| Property | Type | Mandatory | Description |\n| --- | --- | --- | --- |\n| `fileUrl` | String | Yes | The URL of the file. |\n| `fileName` | String | No | The file name. |\n| `fileMIMEType` | String | No | The MIME type of the file. |\n| `fileSize` | Number | No | The size of the file. |\n| `thumbnailUrl` | String | No | The URL of the thumbnail. |\n| `thumbnailFileName` | String | No | The file name of the thumbnail. |\n| `thumbnailMIMEType` | String | No | The MIME type of the thumbnail. |\n| `thumbnailFileSize` | Number | No | The size of the thumbnail. |\n\n#### constructor(fileUrl)\n\nReturns a new `FileMessage` instance.\n\n* `fileUrl` - String: The URL of the file.\n\n#### setFileName(fileName)\n\nSet the `fileName` property.\n\n* `fileName` - String: The file name.\n\n#### setFileMIMEType(fileMIMEType)\n\nSet the `fileMIMEType` property.\n\n* `fileMIMEType` - String: The MIME type of the file.\n\n#### setFileSize(fileSize)\n\nSet the `fileSize` property.\n\n* `fileSize` - Number: The size of the file.\n\n#### setThumbnailUrl(thumbnailUrl)\n\nSet the `thumbnailUrl` property.\n\n* `thumbnailUrl` - String: The URL of the thumbnail.\n\n#### setThumbnailFileName(thumbnailFileName)\n\nSet the `thumbnailFileName` property.\n\n* `thumbnailFileName` - String: The file name of the thumbnail.\n\n#### setThumbnailMIMEType(thumbnailMIMEType)\n\nSet the `thumbnailMIMEType` property.\n\n* `thumbnailMIMEType` - String: The MIME type of the thumbnail.\n\n#### setThumbnailFileSize(thumbnailFileSize)\n\nSet the `thumbnailFileSize` property.\n\n* `thumbnailFileSize` - Number: The size of the thumbnail.\n\n### AudioMessage Functions\n\nAn `AudioMessage` object representes an audio file and has the following properties:\n\n| Property | Type | Mandatory | Description |\n| --- | --- | --- | --- |\n| `fileUrl` | String | Yes | The URL of the file. |\n| `fileName` | String | No | The file name. |\n| `fileMIMEType` | String | No | The MIME type of the file. |\n| `fileSize` | Number | No | The size of the file. |\n| `playingLength` | Number | No | The playing length of the audio. |\n\n#### constructor(fileUrl)\n\nReturns a new `AudioMessage` instance.\n\n* `fileUrl` - String: The URL of the file.\n\n#### setFileName(fileName)\n\nSet the `fileName` property.\n\n* `fileName` - String: The file name.\n\n#### setFileMIMEType(fileMIMEType)\n\nSet the `fileMIMEType` property.\n\n* `fileMIMEType` - String: The MIME type of the file.\n\n#### setFileSize(fileSize)\n\nSet the `fileSize` property.\n\n* `fileSize` - Number: The size of the file.\n\n#### setPlayingLength(playingLength)\n\nSet the `playingLength` property.\n\n* `playingLength` - Number: The playing length of the audio.\n\n### GeolocationPushMessage\n\n| Property | Type | Mandatory | Description |\n| --- | --- | --- | --- |\n| `pos` | String | Yes | This are the coordinates in WGS 84 (latitude, longitude) decimal notation. Example \"26.118 1289 - 80.1283921\" |\n| `label` | String | No | This can be used to tag the nature of the location. |\n| `timestamp` | String | No | This is the time when the location information was pushed. |\n| `expiry` | String | No | This is an absolute date at which time the recipient is no longer permitted to possess the location information. |\n| `timeOffset` | Number | No | This is the time zone where the location information was pushed, expressed as the number of minutes away from UTC. |\n| `radius` | Number | No | The radius of the circle will be represented in meters. |\n\n#### constructor(pos)\n\nReturns a new `GeolocationPushMessage` instance. This is a geolocation push to be sent via RCS Geolocation Push.\n\n* `pos` - String: This are the coordinates in WGS 84 (latitude, longitude) decimal notation.\n\n#### setLabel(label)\n\nSet the `label` property.\n\n* `label` - String: This can be used to tag the nature of the location.\n\n#### setTimestamp(timestamp)\n\nSet the `timestamp` property.\n\n* `timestamp` - String: This is the time when the location information was pushed.\n\n#### setExpiry(expiry)\n\nSet the `expiry` property.\n\n* `expiry` - String: This is an absolute date at which time the recipient is no longer permitted to possess the location information.\n\n#### setTimeOffset(timeOffset)\n\nSet the `timeOffset` property.\n\n* `timeOffset` - Number: This is the time zone where the location information was pushed, expressed as the number of minutes away from UTC.\n\n#### setRadius(radius)\n\nSet the `radius` property.\n\n* `radius` - Number: The radius of the circle will be represented in meters.\n\n### Richcard Functions\n\n#### constructor()\n\nReturns a new `Richcard` instance.\n\n#### setCardOrientation(cardOrientation)\n\nSet the orientation of the card.\n\n* `cardOrientation` - String: Either `Maap.ORIENTATION_HORIZONTAL` or `Maap.ORIENTATION_VERTICAL`.\n\n#### setImageAlignment(imageAlignment)\n\nSet the alignment of the image on the card.\n\n* `imageAlignment` - String: Either `Maap.ALIGNMENT_LEFT` or `Maap.ALIGNMENT_RIGHT`.\n\n#### setMedia(mediaUrl, mediaContentType, mediaFileSize, height, [thumbnailUrl], [thumbnailContentType], [thumbnailFileSize], [contentDescription])\n\nSet the media (image) to be displayed on the richcard.\n\n* `mediaUrl` - String: The URL to the image.\n* `mediaContentType` - String: The content type of the image.\n* `mediaFileSize` - Number: The size of the image.\n* `height` - String: Either `Maap.MEDIA_SHORT_HEIGHT` or `Maap.MEDIA_MEDIUM_HEIGHT` or `Maap.MEDIA_TALL_HEIGHT`.\n* `thumbnailUrl` - (Optional) String: The URL to the thumbnail for the image.\n* `thumbnailContentType` - (Optional) String: The content type of the thumbnail.\n* `thumbnailFileSize` - (Optional) Number: The size of the thumbnail.\n* `contentDescription` - (Optional) String: Textual description of media content.\n\nThe `thumbnailUrl` property is optional, but if used, `thumbnailContentType` and `thumbnailFileSize` must be provided as well.\n\n#### setTitle(title)\n\nSet the title of the card.\n\n* `title` - String: The title.\n\n#### setDescription(description)\n\nSet the description of the card.\n\n* `description` - String: The description.\n\n#### setSuggestions(suggestions)\n\nAdd suggestions to the card.\n\n* `suggestions` - Suggestions: The suggestions.\n\n### RichcardCarousel Functions\n\n#### constructor()\n\nReturns a new `RichcardCarousel` instance.\n\n#### setCardWidth(cardWidth)\n\nSet the width of the cards in the carousel.\n\n* `cardWidth` - String: Either `Maap.CARD_WIDTH_SMALL` or `Maap.CARD_WIDTH_MEDIUM`.\n\n#### addRichcard(richcard)\n\nAdd a card to the carousel.\n\n* `richcard` - Richcard: The `Richcard` object.\n\n### Suggestions Functions\n\nSuggested Replies consist of a display text and a set of postback data.\n\nSuggested Actions are grouped into seven different categories supporting a total of twelve different suggested actions:\n\n* urlAction:\n  * openUrl - Opens a web site or app via deep linking.\n* dialerAction:\n  * dialPhoneNumber - Calls a phone number via the user's dialer app.\n  * dialEnrichedCall - Start an Enriched Call via the user’s dialer app.\n  * dialVideoCall - Start a video call via the user’s dialer app.\n* mapAction:\n  * showLocation - Show location(s) on a map for given coordinates or search query.\n  * requestLocationPush - Request for a one-time geo location push.\n* calendarAction:\n  * createCalendarEvent - Creates a new event on the user's calendar.\n* composeAction:\n  * composeTextMessage - Compose a draft text message.\n  * composeRecordingMessage - Compose a draft message and start recording audio or video.\n* deviceAction:\n  * 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).\n* settingsAction:\n  * disableAnonymization - Ask the user to disable the anonymization setting.\n  * enableDisplayedNotifications - Ask the user to enable sending displayed notifications.\n\nMost 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.\n\n#### constructor()\n\nReturns a new `Suggestions` instance.\n\n#### addReply(displayText, postbackData)\n\nOn-the-wire example:\n\n```json\n{\n  \"reply\": {\n    \"displayText\": \"Yes\",\n    \"postback\": {\n      \"data\": \"set_by_chatbot_reply_yes\"\n    }\n  } \n}\n```\n\n#### addUrlAction(displayText, postbackData, url)\n\nOn-the-wire example:\n\n```json\n{\n  \"action\": {\n    \"urlAction\": {\n      \"openUrl\": {\n        \"url\": \"https://www.google.com\"\n      }\n    },\n    \"displayText\": \"Open website or deep link\",\n    \"postback\": {\n      \"data\": \"set_by_chatbot_open_url\"\n    }\n  }\n}\n```\n\n#### addDialerAction(displayText, postbackData, dialType, phoneNumber, fallbackUrl, [subject])\n\nOn-the-wire example:\n\n```json\n{\n  \"action\": {\n    \"dialerAction\": {\n      \"dialPhoneNumber\": {\n        \"phoneNumber\": \"+1650253000\"\n      }\n    },\n    \"displayText\": \"Call a phone number\",\n    \"postback\": {\n      \"data\": \"set_by_chatbot_dial_phone_number\"\n    }\n  }\n},\n{\n  \"action\": {\n    \"dialerAction\": {\n      \"dialEnrichedCall\": {\n        \"phoneNumber\": \"+1650253000\",\n        \"subject\": \"The optional subject for the enriched call\"\n      }\n    },\n    \"displayText\": \"Start enriched call\",\n    \"postback\": {\n      \"data\": \"set_by_chatbot_dial_enriched_call\"\n    }\n  }\n},\n{\n  \"action\": {\n    \"dialerAction\": {\n      \"dialVideoCall\": {\n        \"phoneNumber\": \"+1650253000\"\n      }\n    },\n    \"displayText\": \"Start video call\",\n    \"postback\": {\n      \"data\": \"set_by_chatbot_dial_video_call\"\n    }\n  }\n}\n```\n\n#### addRequestLocationPushMapAction(displayText, postbackData)\n\nOn-the-wire example:\n\n```json\n{\n  \"action\": {\n    \"mapAction\": {\n      \"requestLocationPush\": {}\n    },\n    \"displayText\": \"Request a geo location\",\n    \"postback\": {\n      \"data\": \"set_by_chatbot_request_location_push\"\n    }\n  }\n}\n```\n\n#### addShowLocationMapAction(displayText, postbackData, latitude, longitude, label, query, fallbackUrl)\n\nOn-the-wire example:\n\n```json\n{\n  \"action\": {\n    \"mapAction\": {\n      \"showLocation\": {\n        \"location\": {\n          \"latitude\": 37.4220041,\n          \"longitude\": -122.0862515,\n          \"label\": \"Googleplex\"\n        },\n        \"fallbackUrl\": \"https://www.google.com/maps/@37.4219162,-122.078063,15z\"\n      }\n    },\n    \"displayText\": \"Show location on a map\",\n    \"postback\": {\n      \"data\": \"set_by_chatbot_show_location\"\n    }\n  }\n},\n{\n  \"action\": {\n    \"mapAction\": {\n      \"showLocation\": {\n        \"location\": {\n          \"query\": \"restaurants\"\n        },\n        \"fallbackUrl\": \"https://www.google.com/maps/search/restaurants\"\n      }\n    },\n    \"displayText\": \"Search location(s) on map\",\n    \"postback\": {\n      \"data\": \"set_by_chatbot_search_locations\"\n    }\n  }\n}\n```\n\n#### addCalendarAction(displayText, postbackData, startTime, endTime, title, description, fallbackUrl)\n\nOn-the-wire example:\n\n```json\n{\n  \"action\": {\n    \"calendarAction\": {\n      \"createCalendarEvent\": {\n        \"startTime\": \"2017-03-14T00:00:00Z\",\n        \"endTime\": \"2017-03-14T23:59:59Z\",\n        \"title\": \"Meeting\",\n        \"description\": \"GSG review meeting\"\n      }\n    },\n    \"displayText\": \"Schedule Meeting\",\n    \"postback\": {\n      \"data\": \"set_by_chatbot_create_calendar_event\"\n    }\n  }\n}\n```\n\n#### addTextComposeAction(displayText, postbackData, phoneNumber, text)\n\nOn-the-wire example:\n\n```json\n{\n  \"action\": {\n    \"composeAction\": {\n      \"composeTextMessage\": {\n        \"phoneNumber\": \"+1650253000\",\n        \"text\": \"Draft to go into the send message text field.\"\n      }\n    },\n    \"displayText\": \"Draft a text message\",\n    \"postback\": {\n      \"data\": \"set_by_chatbot_compose_text_message\"\n    }\n  }\n}\n```\n\n#### addRecordingComposeAction(displayText, postbackData, phoneNumber, type)\n\nOn-the-wire example:\n\n```json\n{\n  \"action\": {\n    \"composeAction\": {\n      \"composeRecordingMessage\": {\n        \"phoneNumber\": \"+1650253000\",\n        \"type\": \"VIDEO\"\n      }\n    },\n    \"displayText\": \"Record audio or video\",\n    \"postback\": {\n      \"data\": \"set_by_chatbot_compose_recording_message\"\n    }\n  }\n}\n```\n\n#### addDeviceAction(displayText, postbackData)\n\nOn-the-wire example:\n\n```json\n{\n  \"action\": {\n    \"deviceAction\": {\n      \"requestDeviceSpecifics\": {}\n    },\n    \"displayText\": \"Request device specifics\",\n    \"postback\": {\n      \"data\": \"set_by_chatbot_request_device_specifics\"\n    }\n  }\n}\n```\n\n#### addSettingsAction(displayText, postbackData, settingsType)\n\nOn-the-wire example:\n\n```json\n{\n  \"action\": {\n    \"settingsAction\": {\n      \"disableAnonymization\": {}\n    },\n    \"displayText\": \"Share your phone number\",\n    \"postback\": {\n      \"data\": \"set_by_chatbot_disable_anonymization\"\n    }\n  }\n},\n{\n  \"action\": {\n    \"settingsAction\": {\n      \"enableDisplayedNotifications\": {}\n    },\n    \"displayText\": \"Send read receipts\",\n    \"postback\": {\n      \"data\": \"set_by_chatbot_enable_displayed_notifications\"\n    }\n  }\n}\n```\n\n### Events\n\nA different event is triggered for each type of event an RCS MaaP chatbot can receive. Below are all\nthe possible events with an example of the payload they provide.\n\n#### on('message', (payload, reply))\n\nTriggered when a 'message' event is sent to the bot.\n\n* `payload` - Object: An object containing the 'message' event payload.\n* `reply` - Function: A convenience function that calls `bot.sendMessage`, with the recipient already set to the message sender.\n\nExample usage:\n\n```js\nbot.on('message', (payload, reply) =\u003e {\n  reply('we got your message!', null, (err, info) =\u003e {})\n})\n```\n\nSample payload:\n\n```json\n{\n  \"RCSMessage\": {\n    \"msgId\": \"Xs8CI3tdf\",\n    \"textMessage\": \"hello world\",\n    \"timestamp\": \"2017-09-26T01:33:20.315Z\"\n  },\n  \"messageContact\": {\n    \"userContact\": \"+14251234567\"\n  },\n  \"event\": \"message\"\n}\n```\n\n#### on('isTyping', (payload, reply))\n\nTriggered when an 'isTyping' event is sent to the bot.\n\n* `payload` - Object: An object containing the 'isTyping' event payload.\n* `reply` - Function: A convenience function that calls `bot.sendMessage`, with the recipient already set to the message sender.\n\nExample usage:\n\n```js\nbot.on('isTyping', (payload, reply) =\u003e {\n  reply('we see you are typing!', null, (err, info) =\u003e {})\n})\n```\n\nSample payload:\n\n```json\n{\n  \"RCSMessage\": {\n    \"msgId\": \"Xs8CI3tdf\",\n    \"isTyping\": \"active\",\n    \"timestamp\": \"2017-09-26T01:33:20.315Z\"\n  },\n  \"messageContact\": {\n    \"userContact\": \"+14251234567\"\n  },\n  \"event\": \"isTyping\"\n}\n```\n\n#### on('messageStatus', (payload, reply))\n\nTriggered when a 'messageStatus' event is sent to the bot.\n\n* `payload` - Object: An object containing the 'messageStatus' event payload.\n* `reply` - Function: A convenience function that calls `bot.sendMessage`, with the recipient already set to the message sender.\n\nExample usage:\n\n```js\nbot.on('messageStatus', (payload, reply) =\u003e {\n  reply('you read our message!', null, (err, info) =\u003e {})\n})\n```\n\nSample payload:\n\n```json\n{\n  \"RCSMessage\": {\n    \"msgId\": \"MzJmajlmamVzZGZ8bmk5MHNlbmRmZTAz\",\n    \"status\": \"displayed\",\n    \"timestamp\": \"2017-09-26T01:33:20.315Z\"\n  },\n  \"messageContact\": {\n    \"userContact\": \"+14251234567\"\n  },\n  \"event\": \"messageStatus\"\n}\n```\n\n#### on('fileStatus', (payload))\n\nTriggered when a 'fileStatus' event is sent to the bot.\n\n* `payload` - Object: An object containing the 'fileStatus' event payload.\n\nExample usage:\n\n```js\nbot.on('fileStatus', (payload) =\u003e {\n  console.log('was the file uploaded?')\n})\n```\n\nSample payload:\n\n```json\n{\n  \"file\": {\n    \"fileId\": \"MzJmajlmamVzZGZ8bmk5MHNlbmRmZTAz\",\n    \"fileUrl\": \"http://www.example.com/files/f.jpg\",\n    \"fileSize\": 123456,\n    \"status\": \"ready\",\n    \"validity\": \"2017-10-03T22:31:00.597Z\"\n  },\n  \"event\": \"fileStatus\"\n}\n```\n\n#### on('response', (payload, reply))\n\nTriggered when a 'response' event is sent to the bot.\n\n* `payload` - Object: An object containing the 'response' event payload.\n* `reply` - Function: A convenience function that calls `bot.sendMessage`, with the recipient already set to the message sender.\n\nExample usage:\n\n```js\nbot.on('response', (payload, reply) =\u003e {\n  reply('you clicked on a button?', null, (err, info) =\u003e {})\n})\n```\n\nSample payload:\n\n```json\n{\n  \"RCSMessage\": {\n    \"msgId\": \"MzJmajlmamVzZGZ8bmk5MHNlbmRmZTAz\",\n    \"suggestedResponse\": {\n      \"response\": {\n        \"action\": {\n          \"displayText\": \"Visit Website\",\n          \"postback\": {\n            \"data\": \"set_by_chatbot_reply_yes\"\n          }\n        }\n      }\n    },\n    \"timestamp\": \"2017-09-26T01:33:20.315Z\"\n  },\n  \"messageContact\": {\n    \"userContact\": \"+14251234567\"\n  },\n  \"event\": \"response\"\n}\n```\n\n#### on('alias', (payload, reply))\n\nTriggered when a 'alias' event is sent to the bot.\n\n* `payload` - Object: An object containing the 'alias' event payload.\n* `reply` - Function: A convenience function that calls `bot.sendMessage`, with the recipient already set to the message sender.\n\nExample usage:\n\n```js\nbot.on('alias', (payload, reply) =\u003e {\n  reply('thank you for sharing your info', null, (err, info) =\u003e {})\n})\n```\n\nSample payload:\n\n```json\n{\n  \"RCSMessage\": {\n    \"msgId\": \"MzJmajlmamVzZGZ8bmk5MHNlbmRmZTAz\",\n    \"timestamp\": \"2017-09-26T01:33:20.315Z\"\n  },\n  \"messageContact\": {\n    \"userContact\": \"+14251234567\",\n    \"chatId\": \"93JF93SEIJFE\"\n  },\n  \"event\": \"alias\"\n}\n```\n\n#### on('newUser', (payload, reply))\n\nTriggered when a 'newUser' event is sent to the bot.\n\n* `payload` - Object: An object containing the 'newUser' event payload.\n* `reply` - Function: A convenience function that calls `bot.sendMessage`, with the recipient already set to the message sender.\n\nExample usage:\n\n```js\nbot.on('newUser', (payload, reply) =\u003e {\n  reply('welcome!', null, (err, info) =\u003e {})\n})\n```\n\nSample payload:\n\n```json\n{\n  \"RCSMessage\": {\n    \"msgId\": \"MzJmajlmamVzZGZ8bmk5MHNlbmRmZTAz\",\n    \"suggestedResponse\": {\n      \"response\": {\n        \"reply\": {\n          \"displayText\": \"Start Chat\",\n          \"postback\": {\n            \"data\": \"new_bot_user_initiation\"\n          }\n        }\n      }\n    },\n    \"timestamp\": \"2017-09-26T01:33:20.315Z\"\n  },\n  \"messageContact\": {\n    \"userContact\": \"+14251234567\"\n  },\n  \"event\": \"newUser\"\n}\n```\n\n## To Do\n\n* Verify constraints before sending\n* Look for missing fields like trafficType (there may be more)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpvangool%2Frcs-maap-bot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpvangool%2Frcs-maap-bot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpvangool%2Frcs-maap-bot/lists"}