{"id":16049090,"url":"https://github.com/alexindigo/fbbot","last_synced_at":"2025-03-17T16:31:47.344Z","repository":{"id":57233646,"uuid":"64025718","full_name":"alexindigo/fbbot","owner":"alexindigo","description":"Minimal framework/SDK for facebook messenger bots. BYOS (Bring Your Own Server)","archived":false,"fork":false,"pushed_at":"2020-09-03T23:26:51.000Z","size":96,"stargazers_count":47,"open_issues_count":1,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-06T09:36:59.273Z","etag":null,"topics":["byos","facebook","facebook-messenger-bot","fb-bot","framework","messenger-platform","minimal","nodejs","sdk"],"latest_commit_sha":null,"homepage":"https://npmjs.com/fbbot","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/alexindigo.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":"2016-07-23T16:44:11.000Z","updated_at":"2022-08-27T02:50:51.000Z","dependencies_parsed_at":"2022-08-31T20:51:26.409Z","dependency_job_id":null,"html_url":"https://github.com/alexindigo/fbbot","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexindigo%2Ffbbot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexindigo%2Ffbbot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexindigo%2Ffbbot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexindigo%2Ffbbot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexindigo","download_url":"https://codeload.github.com/alexindigo/fbbot/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243871860,"owners_count":20361378,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["byos","facebook","facebook-messenger-bot","fb-bot","framework","messenger-platform","minimal","nodejs","sdk"],"created_at":"2024-10-09T00:13:23.149Z","updated_at":"2025-03-17T16:31:47.046Z","avatar_url":"https://github.com/alexindigo.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fbbot [![NPM Module](https://img.shields.io/npm/v/fbbot.svg?style=flat)](https://www.npmjs.com/package/fbbot)\n\nMinimal framework/SDK for facebook messenger bots. BYOS (Bring Your Own Server).\n\n[![patform@1.2](https://img.shields.io/badge/messenger_platform-v1.2-brightgreen.svg?style=flat)](https://developers.facebook.com/docs/messenger-platform)\n\n[![Linux Build](https://img.shields.io/travis/alexindigo/fbbot/master.svg?label=linux:0.12-6.x\u0026style=flat)](https://travis-ci.org/alexindigo/fbbot)\n[![MacOS Build](https://img.shields.io/travis/alexindigo/fbbot/master.svg?label=macos:0.12-6.x\u0026style=flat)](https://travis-ci.org/alexindigo/fbbot)\n[![Windows Build](https://img.shields.io/appveyor/ci/alexindigo/fbbot/master.svg?label=windows:0.12-6.x\u0026style=flat)](https://ci.appveyor.com/project/alexindigo/fbbot)\n\n[![Coverage Status](https://img.shields.io/coveralls/alexindigo/fbbot/master.svg?label=code+coverage\u0026style=flat)](https://coveralls.io/github/alexindigo/fbbot?branch=master)\n[![Dependency Status](https://img.shields.io/david/alexindigo/fbbot/master.svg?style=flat)](https://david-dm.org/alexindigo/fbbot)\n[![bitHound Overall Score](https://www.bithound.io/github/alexindigo/fbbot/badges/score.svg)](https://www.bithound.io/github/alexindigo/fbbot)\n\n[![express](https://img.shields.io/badge/express-tested-brightgreen.svg?style=flat)](http://expressjs.com)\n[![hapi](https://img.shields.io/badge/hapi-tested-brightgreen.svg?lstyle=flat)](http://hapijs.com)\n[![restify](https://img.shields.io/badge/restify-tested-brightgreen.svg?style=flat)](http://restify.com)\n[![http](https://img.shields.io/badge/http-tested-brightgreen.svg?style=flat)](https://nodejs.org/api/http.html)\n\n## Install\n\n```\nnpm install --save fbbot\n```\n\n## Table of Contents\n\n\u003c!-- TOC --\u003e\n- [Examples](#examples)\n  - [Listening for messages](#listening-for-messages)\n  - [Adding middleware](#adding-middleware)\n  - [Sending messages to user](#sending-messages-to-user)\n  - [Logging](#logging)\n- [API](#api)\n  - [Fbbot#use](#fbbotuse)\n  - [Fbbot#on](#fbboton)\n  - [Fbbot#send](#fbbotsend)\n  - [Convenience Methods](#convenience-methods)\n    - [`send.message`](#sendmessage)\n    - [`send.markSeen`](#sendmarkseen)\n    - [`send.typingOn`](#sendtypingon)\n    - [`send.typingOff`](#sendtypingoff)\n    - [`send.text`](#sendtext)\n    - [`send.image`](#sendimage)\n    - [`send.audio`](#sendaudio)\n    - [`send.video`](#sendvideo)\n    - [`send.file`](#sendfile)\n    - [`send.generic`](#sendgeneric)\n    - [`send.button`](#sendbutton)\n    - [`send.receipt`](#sendreceipt)\n    - [`send.quickReplies`](#sendquickreplies)\n  - [Message Types](#message-types)\n    - [`MESSAGE`](#message)\n    - [`MARK_SEEN`](#mark_seen)\n    - [`TYPING_ON`](#typing_on)\n    - [`TYPING_OFF`](#typing_off)\n    - [`TEXT`](#text)\n    - [`IMAGE`](#image)\n    - [`AUDIO`](#audio)\n    - [`VIDEO`](#video)\n    - [`FILE`](#file)\n    - [`GENERIC`](#generic)\n    - [`BUTTON`](#button)\n    - [`RECEIPT`](#receipt)\n    - [`QUICK_REPLIES`](#quick_replies)\n  - [Hooks](#hooks)\n    - [Incoming](#incoming)\n    - [Outgoing](#outgoing)\n- [Roadmap](#roadmap)\n- [License](#license)\n\n\u003c!-- TOC END --\u003e\n\n## Examples\n\n### Listening for messages\n\n```javascript\n// also works with `hapi`, `restify` and built-in `http`\nvar express = require('express');\nvar Fbbot = require('fbbot');\n\nvar app = express();\nvar fbbot = new Fbbot({token: '...', secret: '...'});\n\n// plug-in fbbot\n// It will also listen for GET requests to authorize fb app.\napp.all('/webhook', fbbot.requestHandler);\n// assuming HTTPS is terminated elsewhere,\n// or you can use standard express https capabilities\napp.listen(8080);\n\n// catching messages\nfbbot.on('message', function(message, send)\n{\n  // message.type \u003c-- type of the message (text, attachment, quick_reply, sticker, etc)\n  // message.user \u003c-- user object\n  // message.text \u003c-- text for text messages\n  // message.attachments \u003c-- list of attachments if available\n  // send \u003c-- send method with baked in user.id `send(fbbot.\u003cmessage_type\u003e, \u003cpayload\u003e, \u003ccallback\u003e)`\n});\n\n// handle only text messages\nfbbot.on('message.text', function(message, send)\n{\n  // message.user \u003c-- user object\n  // message.text \u003c-- text for text messages\n  // send \u003c-- send method with baked in user.id `send(fbbot.\u003cmessage_type\u003e, \u003cpayload\u003e, \u003ccallback\u003e)`\n});\n\nfbbot.on('postback', function(postback, send)\n{\n  // postback.user \u003c-- user object\n  // postback.payload \u003c-- parsed payload\n  // send \u003c-- send method with baked in user.id `send(fbbot.\u003cmessage_type\u003e, \u003cpayload\u003e, \u003ccallback\u003e)`\n});\n```\n\nCheck out [test folder](test/fixtures) for available options.\n\n### Adding middleware\n\n```javascript\nvar express = require('express');\nvar Fbbot = require('fbbot');\n\nvar app = express();\nvar fbbot = new Fbbot({token: '...', secret: '...'});\n\n// plug-in fbbot\napp.all('/webhook', fbbot.requestHandler);\n// assuming HTTPS is terminated elsewhere,\n// or you can use standard express https capabilities\napp.listen(8080);\n\nfbbot.use('message', function(payload, callback)\n{\n  // do something with the payload, async or sync\n  setTimeout(function()\n  {\n    payload.fooWasHere = true;\n    // pass it to callback\n    callback(null, payload);\n  }, 500);\n});\n\n// catching messages\nfbbot.on('message', function(message, send)\n{\n  // modified message payload\n  message.fooWasHere; // true\n});\n\n```\n\nMore middleware examples could be found in [incoming](incoming/) folder.\n\n### Sending messages to user\n\nHere are two ways of sending messages, using per-instance fbbot.send method,\nor the one tailored to the user, provided to the event handlers.\n\n```javascript\nvar express = require('express');\nvar Fbbot = require('fbbot');\n\nvar app = express();\nvar fbbot = new Fbbot({token: '...', secret: '...'});\n\n// plug-in fbbot\napp.all('/webhook', fbbot.requestHandler);\n// assuming HTTPS is terminated elsewhere,\n// or you can use standard express https capabilities\napp.listen(8080);\n\n// \"standalone\" send function\n// send reguar text message\nfbbot.send(1234567890, fbbot.TEXT, 'Hi there!', function(error, response)\n{\n  // error \u003c!-- message composition error or transport error\n  // response \u003c-- response from the remote server\n});\n\n// sending messages as reply\nfbbot.on('message', function(message, send)\n{\n  // tailored to the user\n  // callback is optional\n  send(fbbot.IMAGE, 'https://petersapparel.com/img/shirt.png');\n\n  // also message type tailored methods are available\n  send.image('https://petersapparel.com/img/shirt.png');\n});\n```\n\nMore details could be found in [test-send.js](test/test-send.js).\n\n### Logging\n\n```javascript\nvar Fbbot = require('fbbot');\nvar fbbot = new Fbbot({token: '...', secret: '...', logger: myCustomLogger});\n\n// turn on logging\n// uses `bole` out of the box\nFbbot.logger.output({\n  level : 'info',\n  stream: process.stdout\n});\n\n```\n\n## API\n\n### Fbbot#use\n\nAdds middleware for both incoming and outgoing flows. Outgoing hooks prefixed with `send`. Each middleware handler function expected to invoke callback with payload object, modified or not.\n\n```javascript\nfbbot.use([String hook ,] Function handler)\n```\n\nIf no `hook` specified, provided function will be applied to entire incoming payload.\n\n- `hook`: *(optional)* hook handle to attach middleware handler to.\n- `handler`: middleware handler, expected to have following signature:\n\n```javascript\nhandler(Object payload, Function callback)\n```\n\n- `payload`: chunk of the payload corresponding to the attached hook.\n- `callback`: standard error-back pattern, with updated `payload` as second argument.\n\nList of available hooks could be found [below](#hooks).\n\n### Fbbot#on\n\nAdds event listener for both incoming and outgoing flows. Outgoing events (hooks) prefixed with `send`. Each event listener function will receive `send` method tailored for the event in question.\n\n```javascript\nfbbot.on(String hook, Function listener)\n```\n\n- `hook`: hook handle to attach event listener to.\n- `listener`: event listener, expected to have following signature:\n\n```javascript\nlistener(Object payload, Function send)\n```\n\n- `payload`: chunk of the payload corresponding to the attached hook.\u003csup\u003e1\u003c/sup\u003e\n- `send`: function being tailored specifically for the event – baked in user id where it's available,\nand set of convenience methods for sending specific message types, [listed below](#convenience-methods).\n\n\u003csup\u003e1\u003c/sup\u003e Message payload augmented with `type` property and reference `user` object. All payloads have prototype object with reference to the \"parent\" object.\n\nList of available hooks could be found [below](#hooks).\n\n### Fbbot#send\n\nSends provided payload to the specified (by either `id` or `phone_number`) user,\nreconstructs platform expected payload based on the message type and minimal data set.\n\nWill automatically stringify payload object for _postback_ buttons, since Messenger Platform expects it to be a string.\n\n```javascript\nfbbot.send(String|Object user, [String type ,] [String|Array|Object payload ,] [Function callback]);\n```\n\n- `user`: user id or phone number, provided via string (user id) or object with `id` or `phone_number` properties.\n- `type`: *(optional)* message type, if not provided, will fallback to `Fbbot#MESSAGE` type.\n- `payload`: *(optional)* payload object for the chosen message type, not expected for `MARK_SEEN`, `TYPING_ON` and `TYPING_OFF` types.\n- `callback`: *(optional)* standard error-back pattern, with `response` object as second argument.\n\nList of available message types could be found [below](#message-types).\n\nAlso `send` method with backed in user id available as second argument for event listeners:\n\n```javascript\nsend([String type ,] [String|Array|Object payload ,] [Function callback]);\n```\n\nAlong with convenience methods per supported message type:\n\n```javascript\nsend.\u003ctype\u003e([Object payload ,] [Function callback]);\n```\n\n### Convenience Methods\n\n#### `send.message`\n\nSends payload as raw message.\n\n```javascript\nsend.message(Object payload [, Function callback])\n```\n\nExample payload could be found [below](#message).\n\n#### `send.markSeen`\n\nMarks last message as read.\n\n```javascript\nsend.markSeen([Function callback])\n```\n\n#### `send.typingOn`\n\nTurns typing indicators on.\n\n```javascript\nsend.typingOn([Function callback])\n```\n\n#### `send.typingOff`\n\nTurns typing indicators off.\n\n```javascript\nsend.typingOff([Function callback])\n```\n\n#### `send.text`\n\nSends text message. Expects text string as payload. Will truncate provided string to 320 characters, as per Messenger Platform limitations.\n\n```javascript\nsend.text(String text [, Function callback])\n```\n\n#### `send.image`\n\nSends image attachment. Expects string with image url as payload.\n\n```javascript\nsend.image(String url [, Function callback])\n```\n\n#### `send.audio`\n\nSends audio attachment. Expects string with url to audio file as payload.\n\n```javascript\nsend.audio(String url [, Function callback])\n```\n\n#### `send.video`\n\nSends video attachment. Expects string with url to video file as payload.\n\n```javascript\nsend.video(String url [, Function callback])\n```\n\n#### `send.file`\n\nSends generic file attachment. Expects string with url to a file as payload.\n\n```javascript\nsend.file(String url [, Function callback])\n```\n\n#### `send.generic`\n\nSends generic template attachment. Expects array of \"card\" objects as payload. Will send first 10 elements, as per Messenger Platform limitations.\n\n```javascript\nsend.generic(Array elements [, Function callback])\n```\n\nExample payload could be found [below](#generic).\n\n#### `send.button`\n\nSends button template attachment. Expects object with text and array of buttons as payload. Will send first 3 buttons, as per Messenger Platform limitations.\n\n```javascript\nsend.button(Object payload [, Function callback])\n```\n\nExample payload could be found [below](#button).\n\n#### `send.receipt`\n\nSends receipt template attachment. Expects receipt object as payload. Will send first 100 item elements, as per Messenger Platform limitations.\n\n```javascript\nsend.receipt(Object payload [, Function callback])\n```\n\nExample payload could be found [below](#receipt).\n\n#### `send.quickReplies`\n\nSends quick replies object. Expects object with text and array of quick_reply buttons as payload. Will send first 10 buttons, as per Messenger Platform limitations. Will automatically stringify payload property.\n\n```javascript\nsend.quickReplies(Object payload [, Function callback])\n```\n\nExample payload could be found [below](#quick_replies).\n\n### Message Types\n\nAvailable as properties of the Fbbot instance, like `fbbot.MESSAGE` and `fbbot.MARK_SEEN`.\n\n#### `MESSAGE`\n\nTreats payload as raw message.\n\nExample payload:\n\n```json\n{\n  \"attachment\": {\n    \"type\": \"template\",\n    \"payload\": {\n      \"template_type\": \"generic\",\n      \"elements\": [{\n        \"title\": \"Welcome to Peter's Hats\",\n        \"item_url\": \"https://petersfancybrownhats.com\",\n        \"image_url\": \"https://petersfancybrownhats.com/company_image.png\",\n        \"subtitle\": \"We've got the right hat for everyone.\",\n        \"buttons\": [{\n          \"type\": \"web_url\",\n          \"url\": \"https://petersfancybrownhats.com\",\n          \"title\": \"View Website\"\n        }, {\n          \"type\": \"postback\",\n          \"title\": \"Start Chatting\",\n          \"payload\": {\n            \"developer\": [\"defined\", \"payload\"],\n          }\n        }]\n      }]\n    }\n  }\n}\n```\n\n#### `MARK_SEEN`\n\nDoesn't require payload, corresponds to `mark_seen` sender action.\n\n#### `TYPING_ON`\n\nDoesn't require payload, corresponds to `typing_on` sender action.\n\n#### `TYPING_OFF`\n\nDoesn't require payload, corresponds to `typing_off` sender action.\n\n#### `TEXT`\n\nTreats payload as text message. Expects text string as payload. Will truncate provided string to 320 characters, as per Messenger Platform limitations.\n\n#### `IMAGE`\n\nTreats payload as image attachment. Expects string with image url as payload.\n\n#### `AUDIO`\n\nTreats payload as audio attachment. Expects string with url to audio file as payload.\n\n#### `VIDEO`\n\nTreats payload as video attachment. Expects string with url to video file as payload.\n\n#### `FILE`\n\nTreats payload as generic file attachment. Expects string with url to a file as payload.\n\n#### `GENERIC`\n\nTreats payload as generic template attachment. Expects array of \"card\" objects as payload. Will send first 10 elements, as per Messenger Platform limitations.\n\nExample payload:\n\n```json\n[\n  {\n    \"title\": \"Welcome to Peter's Hats\",\n    \"item_url\": \"https://petersfancybrownhats.com\",\n    \"image_url\": \"https://petersfancybrownhats.com/company_image.png\",\n    \"subtitle\": \"We've got the right hat for everyone.\",\n    \"buttons\": [{\n      \"type\": \"web_url\",\n      \"url\": \"https://petersfancybrownhats.com\",\n      \"title\": \"View Website\"\n    }, {\n      \"type\": \"postback\",\n      \"title\": \"Start Chatting\",\n      \"payload\": \"DEVELOPER_DEFINED_PAYLOAD\"\n    }]\n  },\n\n  {\n    \"title\": \"Welcome to Peter's Boots\",\n    \"item_url\": \"https://petersokredboots.com\",\n    \"image_url\": \"https://petersokredboots.com/company_image.png\",\n    \"subtitle\": \"We've got the left boots for everyone.\",\n    \"buttons\": [{\n      \"type\": \"web_url\",\n      \"url\": \"https://petersokredboots.com\",\n      \"title\": \"View Website\"\n    }, {\n      \"type\": \"postback\",\n      \"title\": \"Start Chatting\",\n      \"payload\": {\n        \"developer\": [\"defined\", \"payload\"],\n      }\n    }]\n  }\n]\n```\n\n#### `BUTTON`\n\nTreats payload as button template attachment. Expects object with text and array of buttons as payload. Will send first 3 buttons, as per Messenger Platform limitations.\n\nExample payload:\n\n```json\n{\n  \"text\": \"What do you want to do next?\",\n  \"buttons\":\n  [\n    {\n      \"type\": \"web_url\",\n      \"url\": \"https://petersapparel.parseapp.com\",\n      \"title\": \"Show Website\"\n    },\n    {\n      \"type\": \"postback\",\n      \"title\": \"Start Chatting\",\n      \"payload\": {\n        \"developer\": [\"defined\", \"payload\"],\n      }\n    }\n  ]\n}\n```\n\n#### `RECEIPT`\n\nTreats payload as receipt template attachment. Expects receipt object as payload. Will send first 100 item elements, as per Messenger Platform limitations.\n\nExample payload:\n\n```json\n{\n  \"recipient_name\": \"Stephane Crozatier\",\n  \"order_number\": \"12345678902\",\n  \"currency\": \"USD\",\n  \"payment_method\": \"Visa 2345\",\n  \"order_url\": \"http://petersapparel.parseapp.com/order?order_id=123456\",\n  \"timestamp\": \"1428444852\",\n  \"elements\": [{\n    \"title\": \"Classic White T-Shirt\",\n    \"subtitle\": \"100% Soft and Luxurious Cotton\",\n    \"quantity\": 2,\n    \"price\": 50,\n    \"currency\": \"USD\",\n    \"image_url\": \"http://petersapparel.parseapp.com/img/whiteshirt.png\"\n  }, {\n    \"title\": \"Classic Gray T-Shirt\",\n    \"subtitle\": \"100% Soft and Luxurious Cotton\",\n    \"quantity\": 1,\n    \"price\": 25,\n    \"currency\": \"USD\",\n    \"image_url\": \"http://petersapparel.parseapp.com/img/grayshirt.png\"\n  }],\n  \"address\": {\n    \"street_1\": \"1 Hacker Way\",\n    \"street_2\": \"\",\n    \"city\": \"Menlo Park\",\n    \"postal_code\": \"94025\",\n    \"state\": \"CA\",\n    \"country\": \"US\"\n  },\n  \"summary\": {\n    \"subtotal\": 75.00,\n    \"shipping_cost\": 4.95,\n    \"total_tax\": 6.19,\n    \"total_cost\": 56.14\n  },\n  \"adjustments\": [{\n    \"name\": \"New Customer Discount\",\n    \"amount\": 20\n  }, {\n    \"name\": \"$10 Off Coupon\",\n    \"amount\": 10\n  }]\n}\n```\n\n#### `QUICK_REPLIES`\n\nTreats payload as quick replies object. Expects object with text and array of quick_reply buttons as payload. Will send first 10 buttons, as per Messenger Platform limitations. Will automatically stringify payload property.\n\nExample payload:\n\n```json\n{\n  \"text\": \"Pick a color:\",\n  \"quick_replies\": [{\n    \"content_type\": \"text\",\n    \"title\": \"Red\",\n    \"payload\": \"DEVELOPER_DEFINED_PAYLOAD_FOR_PICKING_RED\"\n  }, {\n    \"content_type\": \"text\",\n    \"title\": \"Green\",\n    \"payload\": {\n      \"custom\": \"payload\",\n      \"for\": \"quick_reply\"\n    }\n  }, {\n    \"content_type\": \"location\"\n  }]\n}\n```\n\n### Hooks\n\nSame hooks work (applied) for both middleware and event listeners.\n\n#### Incoming\n\nAvailable incoming hooks (in the following order):\n\n- `payload`: *(default, if no hook specified)* applied to entire payload.\n- `entry`: applied per each entry of the payload.\n- `messaging`: applied per each messaging element of the payload.\n- `delivery`: applied to delivery notifications.\n- `postback`: applied to postback messages.\n- `message`: applied to regular messages.\n  - `message.attachment`: applied to attachment type messages only.\n  - `message.quick_reply`: applied to quick reply type messages only.\n  - `message.sticker`: applied to sticker type messages only.\n  - `message.text`: applied to text type messages only.\n- `quick_reply`: applied to quick reply payload.\n- `attachment`: applied per each attachment.\n  - `attachment.audio`: applied to audio attachments only.\n  - `attachment.fallback`: applied to fallback attachments only.\u003csup\u003e2\u003c/sup\u003e\n  - `attachment.file`: applied to file attachments only.\n  - `attachment.image`: applied to image attachments only.\n  - `attachment.location`: applied to location attachments only.\n\n\u003csup\u003e2\u003c/sup\u003e Some undocumented case when user sends only link without any other text in the message,\nyour bot would receive as dual quantum state message, which would have regular text field with the link as text,\nas well as attachment object with type `fallback` with `url` field and prefetched `title` of the linked page.\nExample of such payload could be found in [message-attachment-fallback-text.json](test/fixtures/incoming/message-attachment-fallback-text.json).\n\nSample payloads could be found in [incoming fixtures](test/fixtures/incoming) folder.\n\n#### Outgoing\n\n- `send`: applied to the entire outgoing payload.\n- `send.message`: applied to all outgoing messages (status updates, like `typing_on` are not messages).\n- `send.attachment`: applied to outgoing attachments.\n  - `send.attachment.audio`: applied to outgoing audio attachments only.\n  - `send.attachment.file`: applied to outgoing file attachments only.\n  - `send.attachment.image`: applied to outgoing image attachments only.\n  - `send.attachment.video`: applied to outgoing video attachments only.\n  - `send.attachment.template`: applied to templated attachments.\n- `send.quick_reply`: applied per each outgoing quick reply element.\n- `send.payload`: applied to payload objects within outgoing message.\n  - `send.payload.generic`: applied to payload objects with generic template.\n  - `send.payload.receipt`: applied to payload objects with receipt template.\n  - `send.payload.button`: applied to payload objects with button template.\n- `send.element`: applied per each element of the outgoing payload.\n- `send.button`: applied per button options within message, either button template or buttons option within other templates.\n  - `send.button.web_url`: applied to buttons with urls only.\n  - `send.button.postback`: applied to postback buttons only.\n  - `send.button.phone_number`: applied to call buttons only.\n  - `send.button.element_share`: applied to share buttons only.\u003csup\u003e3\u003c/sup\u003e\n  - `send.button.payment`: applied to buy buttons only.\u003csup\u003e4\u003c/sup\u003e\n\n\u003csup\u003e3\u003c/sup\u003e The [Share Button](https://developers.facebook.com/docs/messenger-platform/send-api-reference/share-button) only works with the Generic Template.\n\n\u003csup\u003e4\u003c/sup\u003e The [Buy Button](https://developers.facebook.com/docs/messenger-platform/send-api-reference/buy-button) only works with the Generic Template and it must be the first button.\n\n## Roadmap\n\n- add `send.batch` method, for sending series of messages, with smart `notification_type`s.\n- support for `read` and `echo` notification\n- add `airline` templates\n- fetch user info middleware\n- initialization actions (welcome page, menu, white-listing, etc)\n\n## License\n\nFBBot is released under the [MIT](LICENSE) license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexindigo%2Ffbbot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexindigo%2Ffbbot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexindigo%2Ffbbot/lists"}