Messenger4j
A Java library for building Chatbots on the Facebook Messenger Platform - easy and fast.
Install / Use
/learn @messenger4j/Messenger4jREADME
:sourcedir: src/test/java/com/github/messenger4j/test/integration :m4j-version: 1.1.0 :toc: macro
= messenger4j
image:https://travis-ci.org/messenger4j/messenger4j.svg?branch=master[Build Status,link=https://travis-ci.org/messenger4j/messenger4j] image:https://api.codacy.com/project/badge/Grade/b26d8f1fe4794b89b2ba439f35ac2af4[Codacy Badge,link=https://www.codacy.com/app/max_11/messenger4j?utm_source=github.com&utm_medium=referral&utm_content=messenger4j/messenger4j&utm_campaign=Badge_Grade] image:https://coveralls.io/repos/github/messenger4j/messenger4j/badge.svg[Coverage Status,link=https://coveralls.io/github/messenger4j/messenger4j] image:https://img.shields.io/badge/license-MIT-blue.svg[License Badge, link=LICENSE]
A Java library for building Chatbots on the Facebook Messenger Platform.
Using messenger4j is easy. Its modern object-oriented API is fully Java 8 compatible, expresses optionality, and is designed with immutability in mind. It is fast, powerful, and at roughly 180KB, the library is very light.
For more information on the Facebook Messenger Platform refer to the https://developers.facebook.com/docs/messenger-platform[official documentation].
Please note that messenger4j 1.0.0 is a complete rewrite and has a lot of breaking changes. + Thanks for all your valuable feedback and effort to make this library even better.
toc::[]
== Download === Maven [source,xml] [subs="+attributes"]
<dependency> <groupId>com.github.messenger4j</groupId> <artifactId>messenger4j</artifactId> <version>{m4j-version}</version> </dependency> ----=== Gradle [source] [subs="+attributes"]
dependencies { compile 'com.github.messenger4j:messenger4j:{m4j-version}' }
== Echo Example
[source,java,indent=0]
final String payload =
"{\n"
+ " \"object\": \"page\",\n"
+ " \"entry\": [{\n"
+ " \"id\": \"1717527131834678\",\n"
+ " \"time\": 1475942721780,\n"
+ " \"messaging\": [{\n"
+ " \"sender\": {\n"
+ " \"id\": \"1256217357730577\"\n"
+ " },\n"
+ " \"recipient\": {\n"
+ " \"id\": \"1717527131834678\"\n"
+ " },\n"
+ " \"timestamp\": 1475942721741,\n"
+ " \"message\": {\n"
+ " \"mid\": \"mid.1475942721728:3b9e3646712f9bed52\",\n"
+ " \"seq\": 123,\n"
+ " \"text\": \"Hello Chatbot\"\n"
+ " }\n"
+ " }]\n"
+ " }]\n"
+ "}";
final Messenger messenger = Messenger.create("PAGE_ACCESS_TOKEN", "APP_SECRET", "VERIFY_TOKEN");
messenger.onReceiveEvents(
payload,
Optional.empty(),
event -> {
final String senderId = event.senderId();
if (event.isTextMessageEvent()) {
final String text = event.asTextMessageEvent().text();
final TextMessage textMessage = TextMessage.create(text);
final MessagePayload messagePayload =
MessagePayload.create(senderId, MessagingType.RESPONSE, textMessage);
try {
messenger.send(messagePayload);
} catch (MessengerApiException | MessengerIOException e) {
// Oops, something went wrong
}
}
});
== Reference === Instantiation ==== with default HTTP-Client (okHttp) [source,java,indent=0]
final Messenger messenger = Messenger.create("PAGE_ACCESS_TOKEN", "APP_SECRET", "VERIFY_TOKEN");
==== with custom HTTP-Client [source,java,indent=0]
final MyCustomMessengerHttpClient customHttpClient = new MyCustomMessengerHttpClient();
final Messenger messenger =
Messenger.create(
"PAGE_ACCESS_TOKEN", "APP_SECRET", "VERIFY_TOKEN", Optional.of(customHttpClient));
=== Webhook / Receive Events ==== helper for initial webhook verification request issued by Facebook [source,java,indent=0]
messenger.verifyWebhook(mode, verifyToken);
==== handle incoming text message [source,java,indent=0]
final String payload =
"{\"object\":\"page\",\"entry\":[{\"id\":\"1717527131834678\",\"time\":1475942721780,"
+ "\"messaging\":[{\"sender\":{\"id\":\"1256217357730577\"},\"recipient\":{\"id\":\"1717527131834678\"},"
+ "\"timestamp\":1475942721741,\"message\":{\"mid\":\"mid.1475942721728:3b9e3646712f9bed52\","
+ "\"seq\":123,\"text\":\"34wrr3wr\"}}]}]}";
final String signature = "sha1=3daa41999293ff66c3eb313e04bcf77861bb0276";
messenger.onReceiveEvents(
payload,
of(signature),
event -> {
final String senderId = event.senderId();
final Instant timestamp = event.timestamp();
if (event.isTextMessageEvent()) {
final TextMessageEvent textMessageEvent = event.asTextMessageEvent();
final String messageId = textMessageEvent.messageId();
final String text = textMessageEvent.text();
log.debug(
"Received text message from '{}' at '{}' with content: {} (mid: {})",
senderId,
timestamp,
text,
messageId);
}
});
==== handle incoming attachment message [source,java,indent=0]
final String payload =
"{\n"
+ " \"object\": \"page\",\n"
+ " \"entry\": [{\n"
+ " \"id\": \"PAGE_ID\",\n"
+ " \"time\": 1458692752478,\n"
+ " \"messaging\": [{\n"
+ " \"sender\": {\n"
+ " \"id\": \"USER_ID\"\n"
+ " },\n"
+ " \"recipient\": {\n"
+ " \"id\": \"PAGE_ID\"\n"
+ " },\n"
+ " \"timestamp\": 1458692752478,\n"
+ " \"message\": {\n"
+ " \"mid\": \"mid.1458696618141:b4ef9d19ec21086067\",\n"
+ " \"attachments\": [{\n"
+ " \"type\": \"image\",\n"
+ " \"payload\": {\n"
+ " \"url\": \"http://image.url\"\n"
+ " }\n"
+ " }, {\n"
+ " \"type\":\"fallback\",\n"
+ " \"payload\":null,\n"
+ " \"title\":\"<TITLE_OF_THE_URL_ATTACHMENT>\",\n"
+ " \"URL\":\"<URL_OF_THE_ATTACHMENT>\"\n"
+ " }, {\n"
+ " \"type\": \"location\",\n"
+ " \"payload\": {\n"
+ " \"coordinates\": {\n"
+ " \"lat\": 52.3765533,\n"
+ " \"long\": 9.7389123\n"
+ " }\n"
+ " }\n"
+ " }]\n"
+ " }\n"
+ " }]\n"
+ " }]\n"
+ "}";
messenger.onReceiveEvents(
payload,
Optional.empty(),
event -> {
final String senderId = event.senderId();
final Instant timestamp = event.timestamp();
log.debug("Received event from '{}' at '{}'", senderId, timestamp);
if (event.isAttachmentMessageEvent()) {
final AttachmentMessageEvent attachmentMessageEvent = event.asAttachmentMessageEvent();
for (Attachment attachment : attachmentMessageEvent.attachments()) {
if (attachment.isRichMediaAttachment()) {
final RichMediaAttachment richMediaAttachment = attachment.asRichMediaAttachment();
final RichMediaAttachment.Type type = richMediaAttachment.type();
final URL url = richMediaAttachment.url();
log.debug("Received rich media attachment of type '{}' with url: {}", type, url);
}
if (attachment.isLocationAttachment()) {
final LocationAttachment locationAttachment = attachment.asLocationAttachment();
final double longitude = locationAttachment.longitude();
final double latitude = locationAttachment.latitude();
log.debug("Received location information (long: {}, lat: {})", longitude, latitude);
}
}
}
});
==== more event types In addition to the event types described above the following events are also supported:
PostbackEventQuickReplyMessageEventReferralEventOptInEventAccountLinkingEventMessageDeliveredEventMessageReadEventMessageEchoEvent
=== Send API ==== send sender action [source,java,indent=0]
final String recipientId = "USER_ID";
final SenderAction senderAction = SenderAction.MARK_SEEN;
final SenderActionPayload payload = SenderActionPayload.create(recipientId, senderAction);
messenger.send(payload);
==== send text message [source,java,indent=0]
final String recipientId = "USER_ID";
final String text = "Hello Messenger Platform";
final MessagePayload payload =
MessagePayload.create(recipientId, MessagingType.RESPONSE, TextMessage.create(text));
messenger.send(payload);
==== send text message with notification type and message tag [source,java,indent=0]
final Recipient recipient = IdRecipient.create("USER_ID");
final TextMessage message = TextMessage.create("Hello Messenger Platform");
final NotificationType notificationType = NotificationType.SILENT_PUSH;
final MessageTag messageTag = MessageTag.APPLICATION_UPDATE;
final MessagePayload payload =
MessagePayl
Related Skills
gh-issues
351.2kFetch GitHub issues, spawn sub-agents to implement fixes and open PRs, then monitor and address PR review comments. Usage: /gh-issues [owner/repo] [--label bug] [--limit 5] [--milestone v1.0] [--assignee @me] [--fork user/repo] [--watch] [--interval 5] [--reviews-only] [--cron] [--dry-run] [--model glm-5] [--notify-channel -1002381931352]
oracle
351.2kBest practices for using the oracle CLI (prompt + file bundling, engines, sessions, and file attachment patterns).
taskflow-inbox-triage
351.2kname: taskflow-inbox-triage description: Example TaskFlow authoring pattern for inbox triage. Use when messages need different treatment based on intent, with some routes notifying immediately, some w
taskflow
351.2kname: taskflow description: Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layer
