{"id":41952299,"url":"https://github.com/risan/fbm-send","last_synced_at":"2026-01-25T21:34:26.073Z","repository":{"id":57233675,"uuid":"114500641","full_name":"risan/fbm-send","owner":"risan","description":"Send message through Facebook Messenger Send API.","archived":false,"fork":false,"pushed_at":"2020-02-25T13:22:34.000Z","size":148,"stargazers_count":1,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-08T09:52:56.776Z","etag":null,"topics":["bot","chat","facebook","messenger","send-api"],"latest_commit_sha":null,"homepage":"","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/risan.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":"2017-12-17T01:06:19.000Z","updated_at":"2024-11-02T17:17:04.000Z","dependencies_parsed_at":"2022-08-31T20:51:31.102Z","dependency_job_id":null,"html_url":"https://github.com/risan/fbm-send","commit_stats":null,"previous_names":["risan/messenger-client"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/risan/fbm-send","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/risan%2Ffbm-send","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/risan%2Ffbm-send/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/risan%2Ffbm-send/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/risan%2Ffbm-send/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/risan","download_url":"https://codeload.github.com/risan/fbm-send/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/risan%2Ffbm-send/sbom","scorecard":{"id":777156,"data":{"date":"2025-08-11","repo":{"name":"github.com/risan/fbm-send","commit":"91efb9da315a0f3b357e808edf916c1e893fcd61"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/9 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":"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":"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":"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":"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":"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":"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":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"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 'master'"],"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 23 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"}}]},"last_synced_at":"2025-08-23T03:54:13.647Z","repository_id":57233675,"created_at":"2025-08-23T03:54:13.647Z","updated_at":"2025-08-23T03:54:13.647Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28759412,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T20:56:06.009Z","status":"ssl_error","status_checked_at":"2026-01-25T20:54:48.203Z","response_time":113,"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","chat","facebook","messenger","send-api"],"created_at":"2026-01-25T21:34:25.399Z","updated_at":"2026-01-25T21:34:26.068Z","avatar_url":"https://github.com/risan.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Facebook Messenger Send API Client\n\n[![Build Status](https://badgen.net/travis/risan/fbm-send)](https://travis-ci.org/risan/fbm-send)\n[![Test Covarage](https://badgen.net/codecov/c/github/risan/fbm-send)](https://codecov.io/gh/risan/fbm-send)\n[![Latest Version](https://badgen.net/npm/v/fbm-send)](https://www.npmjs.com/package/fbm-send)\n\nSend message through Facebook Messenger Send API.\n\n## Installation\n\n```bash\n$ npm install fbm-send\n```\n\n## Usage\n\nUse the [`fbm-webhook`](https://github.com/risan/fbm-webhook) module for handling the Facebook Messenger [webhook events](https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/).\n\n```js\nconst FbmSend = require(\"fbm-send\");\nconst fbmWebhook = require(\"fbm-webhook\");\n\nconst webhook = fbmWebhook({\n  path: \"/webhook\",\n  appSecret: \"Your Facebook App Secret\",\n  verifyToken: \"Your Predefined Verify Token\"\n});\n\nconst fbmSend = new FbmSend({\n  accessToken: \"Your Page Access Token\",\n  version: \"4.0\"\n});\n\n// Listen to the message event.\nwebhook.on(\"message\", async event =\u003e {\n  // Reply with text.\n  const response = await fbmSend.request({\n    recipient: event.sender,\n    messaging_type: \"RESPONSE\",\n    message: {\n      text: \"Hello World!\"\n    }\n  });\n\n  console.log(response);\n});\n\nwebhook.listen(3000, () =\u003e console.log(\"Server is running on port: 3000\"));\n```\n\n* `accessToken`: Your Facebook page access token, default to `process.env.FB_PAGE_ACCESS_TOKEN`.\n* `version`: The Facebook Graph API version, default to `4.0`.\n\nYou can use the `try...catch` block to catch the API error response:\n\n```js\ntry {\n  await fbmSend.request({\n    recipient: event.sender,\n    messaging_type: \"RESPONSE\",\n    message: {\n      text: \"Hello World!\"\n    }\n  });\n} catch(error) {\n  if (error.response) {\n    console.log(error.response); // The API error response object.\n  }\n}\n```\n\n## API and Examples\n\n### Table of Contents\n\n* [Constructor](#constructor)\n* [Send Request](#send-request)\n* [Send Text](#send-text)\n* [Send Attachment](#send-attachment)\n* [Send Image/Video/Audio](#send-imagevideoaudio)\n* [Send Saved Attachment](#send-saved-attachment)\n* [Send Sender Action](#send-sender-action)\n* [Send Mark Seen/Typing On/Typing Off](#send-mark-seentyping-ontyping-off)\n\n### Constructor\n\nCreate a new `fbm-send` instance.\n\n```js\nnew FbmSend([{\n  accessToken = process.env.FB_PAGE_ACCESS_TOKEN,\n  version = \"4.0\"\n}]);\n```\n\n#### Parameters\n\n* **`accessToken`** (optional *`String`*): The Facebook page access token, default to `process.env.FB_PAGE_ACCESS_TOKEN`.\n* **`version`** (optional *`String`*): The Facebook Graph API version, default to `4.0`.\n\n### Send Request\n\nUse the `request` method to send an HTTP request to the Send API. All other methods are just a wrapper around this method.\n\n```js\nconst response = await request({\n  recipient,\n  formData = false,\n  ...body\n});\n```\n\n#### Parameters\n\n* **`recipient`** (*`String`*|*`Object`*): The message [recipient](#recipient).\n* **`formData`** (optional *`Boolean`*): Send the request as a `multipart/form-data` (for uploading a local file), default to `false`.\n* **`body`** (`Object`): The request payload to send.\n\n#### Recipient\n\nThe recipient can be a `String`: `PSID`, `phone_number`, or a `user_ref`.\n\nIt can also be an `Object` as defined in the documentation: [recipient object](https://developers.facebook.com/docs/messenger-platform/reference/send-api#recipient).\n\n```js\n// Recipient as a string.\nconst recipient = \"1234567\"; // PSID, phone_number, or user_ref\n\n// Equals to recipient as an object.\nconst recipient = {\n  id: \"1234567\"\n}\n```\n\n#### Messaging Type\n\nAs of Graph API version `2.2`, you're required to pass the `messaging_type` (`String`). There are three supported values for `messaging_type`:\n\n* `RESPONSE` (default value)\n* `UPDATE`\n* `MESSAGE_TAG`\n\nRead more in the [messaging type documentation](https://developers.facebook.com/docs/messenger-platform/send-messages#messaging_types).\n\n#### Return\n\nIt returns a `Promise` which when resolved contains a response from the API.\n\n#### Examples\n\nSend a simple text to the user:\n\n```js\nconst response = await fbmSend.request({\n  recipient: \"123456\",\n  messaging_type = \"RESPONSE\",\n  message: {\n    text: \"Hello World!\"\n  }\n});\n\n// Equals to:\nconst response = await fbmSend.request({\n  recipient: {\n    id: \"123456\"\n  },\n  messaging_type = \"RESPONSE\",\n  message: {\n    text: \"Hello World!\"\n  }\n});\n```\n\nSend a file from a local filesystem:\n\n```js\nconst fs = require(\"fs\");\n\nconst myFile = fs.createReadStream(`${__dirname}/test.txt`);\n\nconst response = await fbmSend.request({\n  recipient: \"123456\",\n  messaging_type = \"RESPONSE\",\n  message: {\n    attachment: {\n      type: \"file\",\n      payload: {\n        is_reusable: true\n      }\n    }\n  },\n  filedata: myFile,\n  formData: true // Must be set to TRUE!\n});\n```\n\nCheck the [Send Attachment](#send-attachment) feature for more simpler approach.\n\nSend quick replies:\n\n```js\nconst response = await fbmSend.request({\n  recipient: \"123456\",\n  messaging_type: \"RESPONSE\",\n  message: {\n    text: \"Choose your Jedi\",\n    quick_replies: [\n      {\n        content_type: \"text\",\n        title: \"Yoda\",\n        payload: \"yoda\"\n      },\n      {\n        content_type: \"text\",\n        title: \"Luke Skywalker\",\n        payload: \"luke_skywalker\"\n      }\n    ]\n  }\n});\n```\n\nSend URL buttons:\n\n```js\nconst response = await fbmSend.request({\n  recipient: \"123456\",\n  messaging_type: \"RESPONSE\",\n  message: {\n    attachment: {\n      type: \"template\",\n      payload: {\n        template_type: \"button\",\n        text: \"Jedi Wiki\",\n        buttons: [\n          {\n            type: \"web_url\",\n            url: \"https://en.wikipedia.org/wiki/Yoda\",\n            title: \"Yoda\"\n          },\n          {\n            type: \"web_url\",\n            url: \"https://en.wikipedia.org/wiki/Luke_Skywalker\",\n            title: \"Luke Skywalker\"\n          }\n        ]\n      }\n    }\n  }\n});\n```\n\n### Send Text\n\nSend a plain text to the user:\n\n```js\nconst response = await fbmSend.text(text, {\n  to,\n  messagingType: \"RESPONSE\"\n});\n```\n\n#### Parameters\n\n* **`text`** (*`String`*): The text to send.\n* **`to`** (*`String`*|*`Object`*): The [recipient](#recipient).\n* **`messagingType`** (optional *`String`*): The [messaging type](#messaging-type), default to `RESPONSE`.\n\n#### Examples\n\n```js\nconst response = await fbmSend.text(\"Hello World!\", {\n  to: \"123456\"\n});\n```\n\nOverriding the default messaging type:\n\n```js\nconst { UPDATE } from \"fbm-send/messaging-types\";\n\nconst response = await fbmSend.text(\"Hello World!\", {\n  to: \"123456\",\n  messagingType: UPDATE\n});\n```\n\n### Send Attachment\n\nSend an attachment to the user:\n\n```js\nconst response = await fbmSend.attachment(file, {\n  to,\n  messagingType = \"RESPONSE\",\n  type = \"file\",\n  isReusable = false\n});\n```\n\n#### Parameters\n\n* **`file`** (*`String`*): The remote URL of the file or the local file path.\n* **`to`** (*`String`*|*`Object`*): The [recipient](#recipient).\n* **`messagingType`** (optional *`String`*): The [messaging type](#messaging-type), default to `RESPONSE`.\n* **`type`** (optional *`String`*): The type of the attachment: `file`, `image`, `video`, or `audio`. Default to `file`.\n* **`isReusable`** (optional *`Boolean`*): Set to `true` to make the attachment reusable (no need to re-upload it again). Default to `false`.\n\n#### Examples\n\nProvide file attachment as a remote URL (must be started with `http://` or `https://`):\n\n```js\nconst response = await fbmSend.attachment(\"https://example.com/photo.jpg\", {\n  to: \"1234567\",\n  type = \"image\"\n});\n```\n\nProvide file attachment as a local file:\n\n```js\nconst response = await fbmSend.attachment(`${__dirname}/test.txt`, {\n  to: \"1234567\",\n  type: \"file\"\n});\n```\n\nSet `isReusable` to `true` to save the attachment, so it can later be reused without the needs to upload it again.\n\n```js\n// The attachment_id can later be used\nconst { attachment_id } = await fbmSend.attachment(`${__dirname}/test.txt`, {\n  to: \"1234567\",\n  type: \"file\",\n  isReusable: true\n});\n```\n\nInstead of re-uploading the file, the `attachment_id` can later be referenced.\n\n### Send Image/Video/Audio\n\nThere are also wrapper methods to send an attachment with image, video, or audio type:\n\n```js\n// Send image.\nconst response = await fbmSend.image(file, {\n  to,\n  messagingType = \"RESPONSE\",\n  isReusable = false\n});\n\n// Send video.\nconst response = await fbmSend.video(file, {\n  to,\n  messagingType = \"RESPONSE\",\n  isReusable = false\n});\n\n// Send audio.\nconst response = await fbmSend.audio(file, {\n  to,\n  messagingType = \"RESPONSE\",\n  isReusable = false\n});\n```\n\n#### Parameters\n\n* **`file`** (*`String`*): The remote URL of the file or the local file path.\n* **`to`** (*`String`*|*`Object`*): The [recipient](#recipient).\n* **`messagingType`** (optional *`String`*): The [messaging type](#messaging-type), default to `RESPONSE`.\n* **`isReusable`** (optional *`Boolean`*): Set to `true` to make the attachment reusable (no need to re-upload it again). Default to `false`.\n\n#### Examples\n\n```js\nconst response = await fbmSend.image(\"https://example.com/photo.jpg\", {\n  to: \"1234567\"\n});\n\nconst response = await fbmSend.video(`../videos/cat.mp4`, {\n  to: \"1234567\",\n  isReusable: true\n});\n\nconst response = await fbmSend.audio(\"https://example.com/sound.mp3\", {\n  to: \"1234567\",\n  messagingType: \"UPDATE\"\n});\n```\n\n### Send Saved Attachment\n\nWhen sending an attachment, set the `isReusable` to `true` to save the file for later use. You'll get the `attachment_id` from the API response. You can use this `attachment_id` to send the same file without the needs to re-upload it again.\n\n```js\nconst response = await fbmSend.attachmentId(id, {\n  to,\n  messagingType = \"RESPONSE\",\n  type = \"file\"\n});\n```\n\n#### Parameters\n\n* **`id`** (*`String`*): The attachment id.\n* **`to`** (*`String`*|*`Object`*): The [recipient](#recipient).\n* **`messagingType`** (optional *`String`*): The [messaging type](#messaging-type), default to `RESPONSE`.\n* **`type`** (optional *`String`*): The type of the attachment: `file`, `image`, `video`, or `audio`. Default to `file`.\n\n#### Examples\n\n```js\n// Send an attachment and get the id for later use.\nconst { attachment_id } = await fbmSend.attachment(`${__dirname}/test.txt`, {\n  to: \"123456\",\n  type: \"file\",\n  isReusable: true // Set to TRUE\n});\n\n// Use the saved attachment file.\nconst response = await fbmSend.attachmentId(\"98765432\", {\n  to: \"567890\",\n  type: \"file\"\n});\n```\n\n### Send Sender Action\n\nSend sender action to the user:\n\n```js\nconst response = await fbmSend.action(type, {\n  to\n});\n```\n\n#### Parameters\n\n* **`type`** (*`String`*): The action type: `mark_seen`, `typing_on`, or `typing_off`.\n* **`to`** (*`String`*|*`Object`*): The [recipient](#recipient).\n\n#### Examples\n\n```js\nconst { MARK_SEEN, TYPING_ON, TYPING_OFF } = require(\"fbm-send/src/sender-actions\");\n\nconst response = await fbmSend.action(MARK_SEEN, {\n  to: \"1234\"\n});\n\nconst response = await fbmSend.action(TYPING_ON, {\n  to: \"1234\"\n});\n\nconst response = await fbmSend.action(TYPING_OFF, {\n  to: \"1234\"\n});\n```\n\n### Send Mark Seen/Typing On/Typing Off\n\nThere are also wrapper methods to send mark seen/typing on/typing off action to the user:\n\n```js\nconst response = await fbmSend.markSeen({ to });\n\nconst response = await fbmSend.typingOn({ to });\n\nconst response = await fbmSend.typingOff({ to });\n```\n\n#### Parameters\n\n* **`to`** (*`String`*|*`Object`*): The [recipient](#recipient).\n\n#### Examples\n\n```js\n// Send mark as seen action.\nconst response = await fbmSend.markSeen({\n  to: \"1234\"\n});\n\n// Send typing on action.\nconst response = await fbmSend.typingOn({\n  to: \"1234\"\n});\n\n// Send typing off action.\nawait fbmSend.typingOff({\n  to: \"1234\"\n});\n```\n\n## Related\n\n* [fbm-webhook](https://github.com/risan/fbm-webhook): Facebook Messenger webhook middleware for Express.\n\n## License\n\n[MIT](https://github.com/risan/fbm-send/blob/master/LICENSE) © [Risan Bagja Pradana](https://risanb.com)\n\n## Legal\n\nThis code is in no way affiliated with, authorized, maintained, sponsored or endorsed by [Facebook](https://www.facebook.com) or any of its affiliates or subsidiaries. This is an independent and unofficial API.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frisan%2Ffbm-send","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frisan%2Ffbm-send","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frisan%2Ffbm-send/lists"}