{"id":37029567,"url":"https://github.com/messenger4j/messenger4j","last_synced_at":"2026-01-14T03:33:43.284Z","repository":{"id":57721442,"uuid":"74203633","full_name":"messenger4j/messenger4j","owner":"messenger4j","description":"A Java library for building Chatbots on the Facebook Messenger Platform - easy and fast.","archived":true,"fork":false,"pushed_at":"2019-06-03T15:54:44.000Z","size":429,"stargazers_count":211,"open_issues_count":0,"forks_count":113,"subscribers_count":32,"default_branch":"master","last_synced_at":"2025-07-11T08:46:18.767Z","etag":null,"topics":["api","bot","chatbots","conversational","facebook","framework","java","library","messenger","messenger-platform"],"latest_commit_sha":null,"homepage":"","language":"Java","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/messenger4j.png","metadata":{"files":{"readme":"README.adoc","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-11-19T11:10:39.000Z","updated_at":"2025-04-18T12:27:27.000Z","dependencies_parsed_at":"2022-09-13T08:40:38.793Z","dependency_job_id":null,"html_url":"https://github.com/messenger4j/messenger4j","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/messenger4j/messenger4j","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/messenger4j%2Fmessenger4j","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/messenger4j%2Fmessenger4j/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/messenger4j%2Fmessenger4j/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/messenger4j%2Fmessenger4j/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/messenger4j","download_url":"https://codeload.github.com/messenger4j/messenger4j/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/messenger4j%2Fmessenger4j/sbom","scorecard":{"id":637380,"data":{"date":"2025-08-11","repo":{"name":"github.com/messenger4j/messenger4j","commit":"cf91467608f7a705496362b3140d7f5241d91a95"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.2,"checks":[{"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":"Code-Review","score":0,"reason":"Found 2/30 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":"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":"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":"Maintained","score":0,"reason":"project is archived","details":["Warn: Repository is archived."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"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":"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":"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":"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":"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":"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":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"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 2 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":8,"reason":"2 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-4jrv-ppp4-jm57","Warn: Project is vulnerable to: GHSA-w33c-445m-f8w7"],"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-21T09:36:05.992Z","repository_id":57721442,"created_at":"2025-08-21T09:36:05.992Z","updated_at":"2025-08-21T09:36:05.992Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408843,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["api","bot","chatbots","conversational","facebook","framework","java","library","messenger","messenger-platform"],"created_at":"2026-01-14T03:33:42.577Z","updated_at":"2026-01-14T03:33:43.273Z","avatar_url":"https://github.com/messenger4j.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":":sourcedir: src/test/java/com/github/messenger4j/test/integration\n:m4j-version: 1.1.0\n:toc: macro\n\n= messenger4j\n\nimage:https://travis-ci.org/messenger4j/messenger4j.svg?branch=master[Build Status,link=https://travis-ci.org/messenger4j/messenger4j]\nimage:https://api.codacy.com/project/badge/Grade/b26d8f1fe4794b89b2ba439f35ac2af4[Codacy Badge,link=https://www.codacy.com/app/max_11/messenger4j?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=messenger4j/messenger4j\u0026amp;utm_campaign=Badge_Grade]\nimage:https://coveralls.io/repos/github/messenger4j/messenger4j/badge.svg[Coverage Status,link=https://coveralls.io/github/messenger4j/messenger4j]\nimage:https://img.shields.io/badge/license-MIT-blue.svg[License Badge, link=LICENSE]\n\n*A Java library for building Chatbots on the Facebook Messenger Platform.*\n\nUsing messenger4j is easy.\nIts modern object-oriented API is fully Java 8 compatible, expresses optionality, and is designed with immutability in mind.\nIt is fast, powerful, and at roughly 180KB, the library is very light.\n\nFor more information on the Facebook Messenger Platform refer to the https://developers.facebook.com/docs/messenger-platform[official documentation].\n\n_Please note that messenger4j 1.0.0 is a complete rewrite and has a lot of breaking changes. +\nThanks for all your valuable feedback and effort to make this library even better._\n\ntoc::[]\n\n== Download\n=== Maven\n[source,xml]\n[subs=\"+attributes\"]\n----\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.github.messenger4j\u003c/groupId\u003e\n  \u003cartifactId\u003emessenger4j\u003c/artifactId\u003e\n  \u003cversion\u003e{m4j-version}\u003c/version\u003e\n\u003c/dependency\u003e\n----\n\n=== Gradle\n[source]\n[subs=\"+attributes\"]\n----\ndependencies {\n  compile 'com.github.messenger4j:messenger4j:{m4j-version}'\n}\n----\n\n== Echo Example\n\n[source,java,indent=0]\n----\n    final String payload =\n        \"{\\n\"\n            + \"  \\\"object\\\": \\\"page\\\",\\n\"\n            + \"  \\\"entry\\\": [{\\n\"\n            + \"    \\\"id\\\": \\\"1717527131834678\\\",\\n\"\n            + \"    \\\"time\\\": 1475942721780,\\n\"\n            + \"    \\\"messaging\\\": [{\\n\"\n            + \"      \\\"sender\\\": {\\n\"\n            + \"        \\\"id\\\": \\\"1256217357730577\\\"\\n\"\n            + \"      },\\n\"\n            + \"      \\\"recipient\\\": {\\n\"\n            + \"        \\\"id\\\": \\\"1717527131834678\\\"\\n\"\n            + \"      },\\n\"\n            + \"      \\\"timestamp\\\": 1475942721741,\\n\"\n            + \"      \\\"message\\\": {\\n\"\n            + \"        \\\"mid\\\": \\\"mid.1475942721728:3b9e3646712f9bed52\\\",\\n\"\n            + \"        \\\"seq\\\": 123,\\n\"\n            + \"        \\\"text\\\": \\\"Hello Chatbot\\\"\\n\"\n            + \"      }\\n\"\n            + \"    }]\\n\"\n            + \"  }]\\n\"\n            + \"}\";\n\n    final Messenger messenger = Messenger.create(\"PAGE_ACCESS_TOKEN\", \"APP_SECRET\", \"VERIFY_TOKEN\");\n\n    messenger.onReceiveEvents(\n        payload,\n        Optional.empty(),\n        event -\u003e {\n          final String senderId = event.senderId();\n          if (event.isTextMessageEvent()) {\n            final String text = event.asTextMessageEvent().text();\n\n            final TextMessage textMessage = TextMessage.create(text);\n            final MessagePayload messagePayload =\n                MessagePayload.create(senderId, MessagingType.RESPONSE, textMessage);\n\n            try {\n              messenger.send(messagePayload);\n            } catch (MessengerApiException | MessengerIOException e) {\n              // Oops, something went wrong\n            }\n          }\n        });\n----\n\n== Reference\n=== Instantiation\n==== with default HTTP-Client (okHttp)\n[source,java,indent=0]\n----\n    final Messenger messenger = Messenger.create(\"PAGE_ACCESS_TOKEN\", \"APP_SECRET\", \"VERIFY_TOKEN\");\n----\n\n==== with custom HTTP-Client\n[source,java,indent=0]\n----\n    final MyCustomMessengerHttpClient customHttpClient = new MyCustomMessengerHttpClient();\n    final Messenger messenger =\n        Messenger.create(\n            \"PAGE_ACCESS_TOKEN\", \"APP_SECRET\", \"VERIFY_TOKEN\", Optional.of(customHttpClient));\n----\n\n=== Webhook / Receive Events\n==== helper for initial webhook verification request issued by Facebook\n[source,java,indent=0]\n----\n    messenger.verifyWebhook(mode, verifyToken);\n----\n\n==== handle incoming text message\n[source,java,indent=0]\n----\n    final String payload =\n        \"{\\\"object\\\":\\\"page\\\",\\\"entry\\\":[{\\\"id\\\":\\\"1717527131834678\\\",\\\"time\\\":1475942721780,\"\n            + \"\\\"messaging\\\":[{\\\"sender\\\":{\\\"id\\\":\\\"1256217357730577\\\"},\\\"recipient\\\":{\\\"id\\\":\\\"1717527131834678\\\"},\"\n            + \"\\\"timestamp\\\":1475942721741,\\\"message\\\":{\\\"mid\\\":\\\"mid.1475942721728:3b9e3646712f9bed52\\\",\"\n            + \"\\\"seq\\\":123,\\\"text\\\":\\\"34wrr3wr\\\"}}]}]}\";\n    final String signature = \"sha1=3daa41999293ff66c3eb313e04bcf77861bb0276\";\n\n    messenger.onReceiveEvents(\n        payload,\n        of(signature),\n        event -\u003e {\n          final String senderId = event.senderId();\n          final Instant timestamp = event.timestamp();\n\n          if (event.isTextMessageEvent()) {\n            final TextMessageEvent textMessageEvent = event.asTextMessageEvent();\n            final String messageId = textMessageEvent.messageId();\n            final String text = textMessageEvent.text();\n\n            log.debug(\n                \"Received text message from '{}' at '{}' with content: {} (mid: {})\",\n                senderId,\n                timestamp,\n                text,\n                messageId);\n          }\n        });\n----\n\n==== handle incoming attachment message\n[source,java,indent=0]\n----\n    final String payload =\n        \"{\\n\"\n            + \"    \\\"object\\\": \\\"page\\\",\\n\"\n            + \"    \\\"entry\\\": [{\\n\"\n            + \"        \\\"id\\\": \\\"PAGE_ID\\\",\\n\"\n            + \"        \\\"time\\\": 1458692752478,\\n\"\n            + \"        \\\"messaging\\\": [{\\n\"\n            + \"            \\\"sender\\\": {\\n\"\n            + \"                \\\"id\\\": \\\"USER_ID\\\"\\n\"\n            + \"            },\\n\"\n            + \"            \\\"recipient\\\": {\\n\"\n            + \"                \\\"id\\\": \\\"PAGE_ID\\\"\\n\"\n            + \"            },\\n\"\n            + \"            \\\"timestamp\\\": 1458692752478,\\n\"\n            + \"            \\\"message\\\": {\\n\"\n            + \"                \\\"mid\\\": \\\"mid.1458696618141:b4ef9d19ec21086067\\\",\\n\"\n            + \"                \\\"attachments\\\": [{\\n\"\n            + \"                    \\\"type\\\": \\\"image\\\",\\n\"\n            + \"                    \\\"payload\\\": {\\n\"\n            + \"                        \\\"url\\\": \\\"http://image.url\\\"\\n\"\n            + \"                    }\\n\"\n            + \"                }, {\\n\"\n            + \"                   \\\"type\\\":\\\"fallback\\\",\\n\"\n            + \"                   \\\"payload\\\":null,\\n\"\n            + \"                   \\\"title\\\":\\\"\u003cTITLE_OF_THE_URL_ATTACHMENT\u003e\\\",\\n\"\n            + \"                   \\\"URL\\\":\\\"\u003cURL_OF_THE_ATTACHMENT\u003e\\\"\\n\"\n            + \"                }, {\\n\"\n            + \"                    \\\"type\\\": \\\"location\\\",\\n\"\n            + \"                    \\\"payload\\\": {\\n\"\n            + \"                        \\\"coordinates\\\": {\\n\"\n            + \"                            \\\"lat\\\": 52.3765533,\\n\"\n            + \"                            \\\"long\\\": 9.7389123\\n\"\n            + \"                        }\\n\"\n            + \"                    }\\n\"\n            + \"                }]\\n\"\n            + \"            }\\n\"\n            + \"        }]\\n\"\n            + \"    }]\\n\"\n            + \"}\";\n\n    messenger.onReceiveEvents(\n        payload,\n        Optional.empty(),\n        event -\u003e {\n          final String senderId = event.senderId();\n          final Instant timestamp = event.timestamp();\n\n          log.debug(\"Received event from '{}' at '{}'\", senderId, timestamp);\n\n          if (event.isAttachmentMessageEvent()) {\n            final AttachmentMessageEvent attachmentMessageEvent = event.asAttachmentMessageEvent();\n            for (Attachment attachment : attachmentMessageEvent.attachments()) {\n              if (attachment.isRichMediaAttachment()) {\n                final RichMediaAttachment richMediaAttachment = attachment.asRichMediaAttachment();\n                final RichMediaAttachment.Type type = richMediaAttachment.type();\n                final URL url = richMediaAttachment.url();\n                log.debug(\"Received rich media attachment of type '{}' with url: {}\", type, url);\n              }\n              if (attachment.isLocationAttachment()) {\n                final LocationAttachment locationAttachment = attachment.asLocationAttachment();\n                final double longitude = locationAttachment.longitude();\n                final double latitude = locationAttachment.latitude();\n                log.debug(\"Received location information (long: {}, lat: {})\", longitude, latitude);\n              }\n            }\n          }\n        });\n----\n\n==== more event types\nIn addition to the event types described above the following events are also supported:\n\n* `PostbackEvent`\n* `QuickReplyMessageEvent`\n* `ReferralEvent`\n* `OptInEvent`\n* `AccountLinkingEvent`\n* `MessageDeliveredEvent`\n* `MessageReadEvent`\n* `MessageEchoEvent`\n\n=== Send API\n==== send sender action\n[source,java,indent=0]\n----\n    final String recipientId = \"USER_ID\";\n    final SenderAction senderAction = SenderAction.MARK_SEEN;\n\n    final SenderActionPayload payload = SenderActionPayload.create(recipientId, senderAction);\n\n    messenger.send(payload);\n----\n\n==== send text message\n[source,java,indent=0]\n----\n    final String recipientId = \"USER_ID\";\n    final String text = \"Hello Messenger Platform\";\n\n    final MessagePayload payload =\n        MessagePayload.create(recipientId, MessagingType.RESPONSE, TextMessage.create(text));\n\n    messenger.send(payload);\n----\n\n==== send text message with notification type and message tag\n[source,java,indent=0]\n----\n    final Recipient recipient = IdRecipient.create(\"USER_ID\");\n    final TextMessage message = TextMessage.create(\"Hello Messenger Platform\");\n    final NotificationType notificationType = NotificationType.SILENT_PUSH;\n    final MessageTag messageTag = MessageTag.APPLICATION_UPDATE;\n\n    final MessagePayload payload =\n        MessagePayload.create(\n            recipient, MessagingType.RESPONSE, message, of(notificationType), of(messageTag));\n\n    messenger.send(payload);\n----\n\n==== send text message with quick replies\n[source,java,indent=0]\n----\n    final IdRecipient recipient = IdRecipient.create(\"\u003cPSID\u003e\");\n\n    final String text = \"Here is a quick reply!\";\n\n    final TextQuickReply quickReplyA =\n        TextQuickReply.create(\n            \"Search\", \"\u003cPOSTBACK_PAYLOAD\u003e\", of(new URL(\"http://example.com/img/red.png\")));\n    final LocationQuickReply quickReplyB = LocationQuickReply.create();\n    final TextQuickReply quickReplyC =\n        TextQuickReply.create(\"Something Else\", \"\u003cPOSTBACK_PAYLOAD\u003e\");\n\n    final List\u003cQuickReply\u003e quickReplies = Arrays.asList(quickReplyA, quickReplyB, quickReplyC);\n\n    final TextMessage message = TextMessage.create(text, of(quickReplies), empty());\n    final MessagePayload payload =\n        MessagePayload.create(recipient, MessagingType.RESPONSE, message);\n\n    messenger.send(payload);\n----\n\n==== send text message with metadata\n[source,java,indent=0]\n----\n    final IdRecipient recipient = IdRecipient.create(\"USER_ID\");\n    final NotificationType notificationType = NotificationType.SILENT_PUSH;\n    final String text = \"Hello Messenger Platform\";\n    final String metadata = \"DEVELOPER_DEFINED_METADATA\";\n\n    final TextMessage textMessage = TextMessage.create(text, empty(), of(metadata));\n    final MessagePayload payload =\n        MessagePayload.create(\n            recipient, MessagingType.RESPONSE, textMessage, of(notificationType), empty());\n\n    messenger.send(payload);\n----\n\n==== send image attachment message using a URL\n[source,java,indent=0]\n----\n    final String recipientId = \"USER_ID\";\n    final String imageUrl = \"https://petersapparel.com/img/shirt.png\";\n\n    final UrlRichMediaAsset richMediaAsset = UrlRichMediaAsset.create(IMAGE, new URL(imageUrl));\n    final RichMediaMessage richMediaMessage = RichMediaMessage.create(richMediaAsset);\n    final MessagePayload payload =\n        MessagePayload.create(recipientId, MessagingType.RESPONSE, richMediaMessage);\n\n    messenger.send(payload);\n----\n\n==== send reusable image attachment message using a URL\n[source,java,indent=0]\n----\n    final IdRecipient recipient = IdRecipient.create(\"USER_ID\");\n    final NotificationType notificationType = NotificationType.NO_PUSH;\n    final String imageUrl = \"https://petersapparel.com/img/shirt.png\";\n\n    final UrlRichMediaAsset richMediaAsset =\n        UrlRichMediaAsset.create(IMAGE, new URL(imageUrl), of(true));\n    final RichMediaMessage richMediaMessage = RichMediaMessage.create(richMediaAsset);\n    final MessagePayload payload =\n        MessagePayload.create(\n            recipient, MessagingType.RESPONSE, richMediaMessage, of(notificationType), empty());\n\n    messenger.send(payload);\n----\n\n==== send image attachment message using an attachment ID\n[source,java,indent=0]\n----\n    final IdRecipient recipient = IdRecipient.create(\"USER_ID\");\n    final NotificationType notificationType = NotificationType.NO_PUSH;\n    final String attachmentId = \"1745504518999123\";\n\n    final ReusableRichMediaAsset richMediaAsset =\n        ReusableRichMediaAsset.create(IMAGE, attachmentId);\n    final RichMediaMessage richMediaMessage = RichMediaMessage.create(richMediaAsset);\n    final MessagePayload payload =\n        MessagePayload.create(\n            recipient, MessagingType.RESPONSE, richMediaMessage, of(notificationType), empty());\n\n    messenger.send(payload);\n----\n\n==== send button template\n[source,java,indent=0]\n----\n    final String recipientId = \"USER_ID\";\n\n    final UrlButton buttonA =\n        UrlButton.create(\"Show Website\", new URL(\"https://petersapparel.parseapp.com\"));\n    final PostbackButton buttonB = PostbackButton.create(\"Start Chatting\", \"USER_DEFINED_PAYLOAD\");\n    final UrlButton buttonC =\n        UrlButton.create(\n            \"Show Website\",\n            new URL(\"https://petersapparel.parseapp.com\"),\n            of(WebviewHeightRatio.FULL),\n            of(true),\n            of(new URL(\"https://petersfancyapparel.com/fallback\")),\n            empty());\n\n    final List\u003cButton\u003e buttons = Arrays.asList(buttonA, buttonB, buttonC);\n    final ButtonTemplate buttonTemplate =\n        ButtonTemplate.create(\"What do you want to do next?\", buttons);\n\n    final TemplateMessage templateMessage = TemplateMessage.create(buttonTemplate);\n    final MessagePayload payload =\n        MessagePayload.create(recipientId, MessagingType.RESPONSE, templateMessage);\n\n    messenger.send(payload);\n----\n\n==== send generic template with buttons\n[source,java,indent=0]\n----\n    final String recipientId = \"USER_ID\";\n\n    final List\u003cButton\u003e buttons =\n        Arrays.asList(\n            UrlButton.create(\n                \"Select Criteria\",\n                new URL(\"https://petersfancyapparel.com/criteria_selector\"),\n                of(WebviewHeightRatio.FULL),\n                of(true),\n                of(new URL(\"https://petersfancyapparel.com/fallback\")),\n                empty()),\n            CallButton.create(\"Call Representative\", \"+15105551234\"),\n            PostbackButton.create(\"Start Chatting\", \"DEVELOPER_DEFINED_PAYLOAD\"));\n\n    final DefaultAction defaultAction =\n        DefaultAction.create(\n            new URL(\"https://peterssendreceiveapp.ngrok.io/view?item=103\"),\n            of(WebviewHeightRatio.TALL),\n            of(true),\n            of(new URL(\"https://peterssendreceiveapp.ngrok.io/\")),\n            of(WebviewShareButtonState.HIDE));\n\n    final Element element =\n        Element.create(\n            \"Welcome to Peters Hats\",\n            of(\"We have got the right hat for everyone.\"),\n            of(new URL(\"https://petersfancybrownhats.com/company_image.png\")),\n            of(defaultAction),\n            of(buttons));\n\n    final GenericTemplate genericTemplate = GenericTemplate.create(singletonList(element));\n\n    final MessagePayload payload =\n        MessagePayload.create(\n            recipientId, MessagingType.RESPONSE, TemplateMessage.create(genericTemplate));\n\n    messenger.send(payload);\n----\n\n==== send receipt template\n[source,java,indent=0]\n----\n    final String recipientId = \"USER_ID\";\n\n    final Adjustment adjustment1 = Adjustment.create(\"New Customer Discount\", 20.00F);\n    final Adjustment adjustment2 = Adjustment.create(\"$10 Off Coupon\", 10.00F);\n\n    final Item item1 =\n        Item.create(\n            \"Classic White T-Shirt\",\n            50F,\n            of(\"100% Soft and Luxurious Cotton\"),\n            of(2),\n            of(\"USD\"),\n            of(new URL(\"http://petersapparel.parseapp.com/img/whiteshirt.png\")));\n\n    final Item item2 =\n        Item.create(\n            \"Classic Gray T-Shirt\",\n            25F,\n            of(\"100% Soft and Luxurious Cotton\"),\n            of(1),\n            of(\"USD\"),\n            of(new URL(\"http://petersapparel.parseapp.com/img/grayshirt.png\")));\n\n    final Address address =\n        Address.create(\"1 Hacker Way\", of(\"\"), \"Menlo Park\", \"94025\", \"CA\", \"US\");\n    final Summary summary = Summary.create(56.14F, of(75.00F), of(6.19F), of(4.95F));\n\n    final ReceiptTemplate receiptTemplate =\n        ReceiptTemplate.create(\n            \"Stephane Crozatier\",\n            \"12345678902\",\n            \"Visa 2345\",\n            \"USD\",\n            summary,\n            of(address),\n            of(Arrays.asList(item1, item2)),\n            of(Arrays.asList(adjustment1, adjustment2)),\n            empty(),\n            of(new URL(\"http://petersapparel.parseapp.com/order?order_id=123456\")),\n            empty(),\n            of(ZonedDateTime.of(2015, 4, 7, 22, 14, 12, 0, ZoneOffset.UTC).toInstant()));\n\n    final MessagePayload payload =\n        MessagePayload.create(\n            recipientId, MessagingType.RESPONSE, TemplateMessage.create(receiptTemplate));\n\n    messenger.send(payload);\n----\n\n==== send list template\n[source,java,indent=0]\n----\n    final String recipientId = \"USER_ID\";\n\n    final Element element1 =\n        Element.create(\n            \"Classic T-Shirt Collection\",\n            of(\"See all our colors\"),\n            of(new URL(\"https://peterssendreceiveapp.ngrok.io/img/collection.png\")),\n            of(\n                DefaultAction.create(\n                    new URL(\"https://peterssendreceiveapp.ngrok.io/shop_collection\"),\n                    of(WebviewHeightRatio.TALL),\n                    of(true),\n                    of(new URL(\"https://peterssendreceiveapp.ngrok.io/fallback\")),\n                    empty())),\n            of(\n                singletonList(\n                    UrlButton.create(\n                        \"View\",\n                        new URL(\"https://peterssendreceiveapp.ngrok.io/collection\"),\n                        of(WebviewHeightRatio.TALL),\n                        empty(),\n                        empty(),\n                        empty()))));\n\n    final Element element2 =\n        Element.create(\n            \"Classic White T-Shirt\",\n            of(\"100% Cotton, 200% Comfortable\"),\n            of(new URL(\"https://peterssendreceiveapp.ngrok.io/img/white-t-shirt.png\")),\n            of(\n                DefaultAction.create(\n                    new URL(\"https://peterssendreceiveapp.ngrok.io/view?item=100\"),\n                    of(WebviewHeightRatio.TALL),\n                    empty(),\n                    empty(),\n                    empty())),\n            of(\n                singletonList(\n                    UrlButton.create(\n                        \"Shop Now\",\n                        new URL(\"https://peterssendreceiveapp.ngrok.io/shop?item=100\"),\n                        of(WebviewHeightRatio.TALL),\n                        empty(),\n                        empty(),\n                        empty()))));\n\n    final Element element3 =\n        Element.create(\n            \"Classic Blue T-Shirt\",\n            of(\"100% Cotton, 200% Comfortable\"),\n            of(new URL(\"https://peterssendreceiveapp.ngrok.io/img/blue-t-shirt.png\")),\n            of(\n                DefaultAction.create(\n                    new URL(\"https://peterssendreceiveapp.ngrok.io/view?item=101\"),\n                    of(WebviewHeightRatio.TALL),\n                    empty(),\n                    empty(),\n                    empty())),\n            of(\n                singletonList(\n                    UrlButton.create(\n                        \"Shop Now\",\n                        new URL(\"https://peterssendreceiveapp.ngrok.io/shop?item=101\"),\n                        of(WebviewHeightRatio.TALL),\n                        empty(),\n                        empty(),\n                        empty()))));\n\n    final Element element4 =\n        Element.create(\n            \"Classic Black T-Shirt\",\n            of(\"100% Cotton, 200% Comfortable\"),\n            of(new URL(\"https://peterssendreceiveapp.ngrok.io/img/black-t-shirt.png\")),\n            of(\n                DefaultAction.create(\n                    new URL(\"https://peterssendreceiveapp.ngrok.io/view?item=102\"),\n                    of(WebviewHeightRatio.TALL),\n                    empty(),\n                    empty(),\n                    empty())),\n            of(\n                singletonList(\n                    UrlButton.create(\n                        \"Shop Now\",\n                        new URL(\"https://peterssendreceiveapp.ngrok.io/shop?item=102\"),\n                        of(WebviewHeightRatio.TALL),\n                        empty(),\n                        empty(),\n                        empty()))));\n\n    final ListTemplate listTemplate =\n        ListTemplate.create(\n            Arrays.asList(element1, element2, element3, element4),\n            of(TopElementStyle.LARGE),\n            of(singletonList(PostbackButton.create(\"View More\", \"payload\"))));\n\n    messenger.send(\n        MessagePayload.create(\n            recipientId, MessagingType.RESPONSE, TemplateMessage.create(listTemplate)));\n----\n\n==== send open graph template\n[source,java,indent=0]\n----\n    final String recipientId = \"USER_ID\";\n\n    final UrlButton urlButton =\n        UrlButton.create(\"View More\", new URL(\"https://en.wikipedia.org/wiki/Rickrolling\"));\n    final OpenGraphObject openGraphObject =\n        OpenGraphObject.create(\n            new URL(\"https://open.spotify.com/track/7GhIk7Il098yCjg4BQjzvb\"),\n            of(singletonList(urlButton)));\n    final OpenGraphTemplate openGraphTemplate =\n        OpenGraphTemplate.create(singletonList(openGraphObject));\n\n    messenger.send(\n        MessagePayload.create(\n            recipientId, MessagingType.RESPONSE, TemplateMessage.create(openGraphTemplate)));\n----\n\n==== handle successful response\n[source,java,indent=0]\n----\n    final UrlRichMediaAsset richMediaAsset =\n        UrlRichMediaAsset.create(IMAGE, new URL(\"http://image.url\"), of(true));\n    final MessagePayload payload =\n        MessagePayload.create(\n            \"USER_ID\", MessagingType.RESPONSE, RichMediaMessage.create(richMediaAsset));\n\n    final MessageResponse messageResponse = messenger.send(payload);\n\n    final Optional\u003cString\u003e recipientId = messageResponse.recipientId();\n    final Optional\u003cString\u003e messageId = messageResponse.messageId();\n    final Optional\u003cString\u003e attachmentId = messageResponse.attachmentId();\n    log.debug(\n        \"RecipientId: {} | MessageId: {} | AttachmentId: {}\", recipientId, messageId, attachmentId);\n----\n\n=== User Profile API\n==== query user information by user ID\n[source,java,indent=0]\n----\n    final UserProfile userProfile = messenger.queryUserProfile(userId);\n----\n\n=== Messenger Profile API\n==== set / update Get Started button\n[source,java,indent=0]\n----\n    final MessengerSettings messengerSettings =\n        MessengerSettings.create(\n            of(StartButton.create(\"Button pressed\")),\n            empty(),\n            empty(),\n            empty(),\n            empty(),\n            empty(),\n            empty());\n\n    messenger.updateSettings(messengerSettings);\n----\n\n==== delete Get Started button\n[source,java,indent=0]\n----\n    messenger.deleteSettings(MessengerSettingProperty.START_BUTTON);\n----\n\n==== set / update greeting text\n[source,java,indent=0]\n----\n    final Greeting greeting =\n        Greeting.create(\n            \"Hello!\",\n            LocalizedGreeting.create(SupportedLocale.en_US, \"Timeless apparel for the masses.\"));\n    final MessengerSettings messengerSettings =\n        MessengerSettings.create(\n            empty(), of(greeting), empty(), empty(), empty(), empty(), empty());\n\n    messenger.updateSettings(messengerSettings);\n----\n\n==== delete greeting text\n[source,java,indent=0]\n----\n    messenger.deleteSettings(MessengerSettingProperty.GREETING);\n----\n\n==== set / update persistent menu\n[source,java,indent=0]\n----\n    final PostbackCallToAction callToActionAA =\n        PostbackCallToAction.create(\"Pay Bill\", \"PAYBILL_PAYLOAD\");\n    final PostbackCallToAction callToActionAB =\n        PostbackCallToAction.create(\"History\", \"HISTORY_PAYLOAD\");\n    final PostbackCallToAction callToActionAC =\n        PostbackCallToAction.create(\"Contact Info\", \"CONTACT_INFO_PAYLOAD\");\n\n    final NestedCallToAction callToActionA =\n        NestedCallToAction.create(\n            \"My Account\", Arrays.asList(callToActionAA, callToActionAB, callToActionAC));\n\n    final UrlCallToAction callToActionB =\n        UrlCallToAction.create(\n            \"Latest News\",\n            new URL(\"http://petershats.parseapp.com/hat-news\"),\n            of(WebviewHeightRatio.FULL),\n            empty(),\n            empty(),\n            of(WebviewShareButtonState.HIDE));\n\n    final PersistentMenu persistentMenu =\n        PersistentMenu.create(\n            true,\n            of(Arrays.asList(callToActionA, callToActionB)),\n            LocalizedPersistentMenu.create(SupportedLocale.zh_CN, false, empty()));\n\n    final MessengerSettings messengerSettings =\n        MessengerSettings.create(\n            empty(), empty(), of(persistentMenu), empty(), empty(), empty(), empty());\n\n    messenger.updateSettings(messengerSettings);\n----\n\n==== delete persistent menu\n[source,java,indent=0]\n----\n    messenger.deleteSettings(MessengerSettingProperty.PERSISTENT_MENU);\n----\n\n==== set / update whitelisted domains\n[source,java,indent=0]\n----\n    final List\u003cURL\u003e whitelistedDomains =\n        Arrays.asList(new URL(\"http://example.url\"), new URL(\"http://second-example.url\"));\n\n    final MessengerSettings messengerSettings =\n        MessengerSettings.create(\n            empty(), empty(), empty(), of(whitelistedDomains), empty(), empty(), empty());\n\n    messenger.updateSettings(messengerSettings);\n----\n\n==== delete whitelisted domains\n[source,java,indent=0]\n----\n    messenger.deleteSettings(MessengerSettingProperty.WHITELISTED_DOMAINS);\n----\n\n==== set / update account linking url\n[source,java,indent=0]\n----\n    final MessengerSettings messengerSettings =\n        MessengerSettings.create(\n            empty(),\n            empty(),\n            empty(),\n            empty(),\n            of(new URL(\"http://example.url\")),\n            empty(),\n            empty());\n\n    messenger.updateSettings(messengerSettings);\n----\n\n==== delete account linking url\n[source,java,indent=0]\n----\n    messenger.deleteSettings(MessengerSettingProperty.ACCOUNT_LINKING_URL);\n----\n\n==== set / update home url\n[source,java,indent=0]\n----\n    final HomeUrl homeUrl =\n        HomeUrl.create(new URL(\"http://example.url\"), true, of(WebviewShareButtonState.HIDE));\n\n    final MessengerSettings messengerSettings =\n        MessengerSettings.create(empty(), empty(), empty(), empty(), empty(), of(homeUrl), empty());\n\n    messenger.updateSettings(messengerSettings);\n----\n\n==== delete home url\n[source,java,indent=0]\n----\n    messenger.deleteSettings(MessengerSettingProperty.HOME_URL);\n----\n\n==== set / update target audience (open to all)\n[source,java,indent=0]\n----\n    final AllTargetAudience allTargetAudience = AllTargetAudience.create();\n\n    final MessengerSettings messengerSettings =\n        MessengerSettings.create(\n            empty(), empty(), empty(), empty(), empty(), empty(), of(allTargetAudience));\n\n    messenger.updateSettings(messengerSettings);\n----\n\n==== set / update target audience (closed to all)\n[source,java,indent=0]\n----\n    final NoneTargetAudience noneTargetAudience = NoneTargetAudience.create();\n\n    final MessengerSettings messengerSettings =\n        MessengerSettings.create(\n            empty(), empty(), empty(), empty(), empty(), empty(), of(noneTargetAudience));\n\n    messenger.updateSettings(messengerSettings);\n----\n\n==== set / update target audience (custom whitelist)\n[source,java,indent=0]\n----\n    final WhitelistTargetAudience whitelistTargetAudience =\n        WhitelistTargetAudience.create(Arrays.asList(SupportedCountry.US, SupportedCountry.CA));\n\n    final MessengerSettings messengerSettings =\n        MessengerSettings.create(\n            empty(), empty(), empty(), empty(), empty(), empty(), of(whitelistTargetAudience));\n\n    messenger.updateSettings(messengerSettings);\n----\n\n==== set / update target audience (custom blacklist)\n[source,java,indent=0]\n----\n    final BlacklistTargetAudience blacklistTargetAudience =\n        BlacklistTargetAudience.create(Arrays.asList(SupportedCountry.US, SupportedCountry.CA));\n\n    final MessengerSettings messengerSettings =\n        MessengerSettings.create(\n            empty(), empty(), empty(), empty(), empty(), empty(), of(blacklistTargetAudience));\n\n    messenger.updateSettings(messengerSettings);\n----\n\n==== delete target audience\n[source,java,indent=0]\n----\n    messenger.deleteSettings(MessengerSettingProperty.TARGET_AUDIENCE);\n----\n\n== Requirements\n* Java 8+\n* slf4j\n* Gson\n* okHttp (optional =\u003e HTTP-Client is pluggable)\n\n== Contributing\nContributions are very welcome!\nPlease perform changes and submit pull requests from the `develop` branch instead of `master`, and open an issue before start working.\nWhen submitting code, please make every effort to follow existing conventions and style in order to keep the code as readable as possible.\nPlease also make sure your code compiles by running `mvn clean verify`.\n\n== License\nThis project is licensed under the terms of the link:LICENSE[MIT license].\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmessenger4j%2Fmessenger4j","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmessenger4j%2Fmessenger4j","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmessenger4j%2Fmessenger4j/lists"}