Racter is A Java Framework for Building Bots on Facebook's Messenger Platform.
Current Version: 1.0.0
To add a dependency using Maven, use the following:
<dependency>
<groupId>com.clivern</groupId>
<artifactId>racter</artifactId>
<version>1.0.0</version>
</dependency>
To add a dependency using Gradle, use the following:
dependencies {
compile 'com.clivern:racter:1.0.0'
}
After adding the package as a dependency, Please read the following steps:
In order to cofigure the package create config.properties
file with the following data
app_id=App ID Goes Here
verify_token=Verify Token Goes Here
page_access_token=Page Access Token Goes Here
log_console_status=true or false
log_console_level=ALL, CONFIG, FINE, FINER, FINEST, INFO, SEVERE, WARNING or OFF
log_file_status=true or false
log_file_level=ALL, CONFIG, FINE, FINER, FINEST, INFO, SEVERE, WARNING or OFF
log_file_path=app.log
log_file_limit=1
log_file_count=200000
log_file_append=true or false
Then import all required classes
import com.clivern.racter.BotPlatform;
import com.clivern.racter.receivers.*;
import com.clivern.racter.receivers.webhook.*;
import com.clivern.racter.senders.*;
import com.clivern.racter.senders.templates.*;
import java.util.HashMap;
import java.util.Map;
import java.io.IOException;
then pass the config.properties
file to the bot platform instance
BotPlatform platform = BotPlatform.getInstance().loadConfigs("config.properties").configDependencies();
or Configure it manually
Map<String, String> options = new HashMap<String, String>();
options.put("app_id", "App ID Goes Here");
options.put("verify_token", "Verify Token Goes Here");
options.put("page_access_token", "Page Access Token Goes Here");
options.put("log_console_status", "true or false");
options.put("log_console_level", "ALL, CONFIG, FINE, FINER, FINEST, INFO, SEVERE, WARNING or OFF");
options.put("log_file_status", "true or false");
options.put("log_file_level", "ALL, CONFIG, FINE, FINER, FINEST, INFO, SEVERE, WARNING or OFF");
options.put("log_file_path", "app.log");
options.put("log_file_limit", "1");
options.put("log_file_count", "200000");
options.put("log_file_append", "true or false");
BotPlatform platform = BotPlatform.getInstance().loadConfigs(options).configDependencies();
Create a route to verify your verify token, Facebook will perform a GET request to this route URL with some URL parameters to make sure that verify token is correct.
BotPlatform platform = BotPlatform.getInstance().loadConfigs("config.properties").configDependencies();
String hubMode = // Get hub.mode query parameter value from the current URL
String hubVerifyToken = // Get hub.verify_token query parameter value from the current URL
String hubChallenge = // Get hub.challenge query parameter value from the current URL
platform.getVerifyWebhook().setHubMode(hubMode);
platform.getVerifyWebhook().setHubVerifyToken(hubVerifyToken);
platform.getVerifyWebhook().setHubChallenge(hubChallenge);
if( platform.getVerifyWebhook().challenge() ){
platform.finish();
// Set Response to be hubChallenge value and status code is 200 like
// response.status(200);
// return ( hubChallenge != null ) ? hubChallenge : "";
}
platform.finish();
// Set Response to be 'Verification token mismatch' and status code is 403 like
// response.status(403);
// return "Verification token mismatch";
So let's say we use Spark Java Framework for our bot, Our route and callback will look like the following:
import static spark.Spark.*;
import com.clivern.racter.BotPlatform;
import com.clivern.racter.receivers.*;
import com.clivern.racter.receivers.webhook.*;
import com.clivern.racter.senders.*;
import com.clivern.racter.senders.templates.*;
import java.util.HashMap;
import java.util.Map;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException
{
// Verify Token Route
get("/", (request, response) -> {
BotPlatform platform = BotPlatform.getInstance().loadConfigs("config.properties").configDependencies();
platform.getVerifyWebhook().setHubMode(( request.queryParams("hub.mode") != null ) ? request.queryParams("hub.mode") : "");
platform.getVerifyWebhook().setHubVerifyToken(( request.queryParams("hub.verify_token") != null ) ? request.queryParams("hub.verify_token") : "");
platform.getVerifyWebhook().setHubChallenge(( request.queryParams("hub.challenge") != null ) ? request.queryParams("hub.challenge") : "");
if( platform.getVerifyWebhook().challenge() ){
platform.finish();
response.status(200);
return ( request.queryParams("hub.challenge") != null ) ? request.queryParams("hub.challenge") : "";
}
platform.finish();
response.status(403);
return "Verification token mismatch";
});
}
}
In order to receive and parse messages, You will need to create another route that receives post requests from Facebook. Our Route should contain a code look like the following:
String body = // Get current Request Body
BotPlatform platform = BotPlatform.getInstance().loadConfigs("config.properties").configDependencies();
platform.getBaseReceiver().set(body).parse();
HashMap<String, MessageReceivedWebhook> messages = (HashMap<String, MessageReceivedWebhook>) platform.getBaseReceiver().getMessages();
for (MessageReceivedWebhook message : messages.values()) {
String user_id = (message.hasUserId()) ? message.getUserId() : "";
String page_id = (message.hasPageId()) ? message.getPageId() : "";
String message_id = (message.hasMessageId()) ? message.getMessageId() : "";
String message_text = (message.hasMessageText()) ? message.getMessageText() : "";
String quick_reply_payload = (message.hasQuickReplyPayload()) ? message.getQuickReplyPayload() : "";
Long timestamp = (message.hasTimestamp()) ? message.getTimestamp() : 0;
HashMap<String, String> attachments = (message.hasAttachment()) ? (HashMap<String, String>) message.getAttachment() : new HashMap<String, String>();
}
So let's say we use Spark Java Framework for our bot, Our route should look like the following:
import static spark.Spark.*;
import com.clivern.racter.BotPlatform;
import com.clivern.racter.receivers.*;
import com.clivern.racter.receivers.webhook.*;
import com.clivern.racter.senders.*;
import com.clivern.racter.senders.templates.*;
import java.util.HashMap;
import java.util.Map;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException
{
// Verify Token Route
get("/", (request, response) -> {
BotPlatform platform = BotPlatform.getInstance().loadConfigs("config.properties").configDependencies();
platform.getVerifyWebhook().setHubMode(( request.queryParams("hub.mode") != null ) ? request.queryParams("hub.mode") : "");
platform.getVerifyWebhook().setHubVerifyToken(( request.queryParams("hub.verify_token") != null ) ? request.queryParams("hub.verify_token") : "");
platform.getVerifyWebhook().setHubChallenge(( request.queryParams("hub.challenge") != null ) ? request.queryParams("hub.challenge") : "");
if( platform.getVerifyWebhook().challenge() ){
platform.finish();
response.status(200);
return ( request.queryParams("hub.challenge") != null ) ? request.queryParams("hub.challenge") : "";
}
platform.finish();
response.status(403);
return "Verification token mismatch";
});
post("/", (request, response) -> {
String body = request.body();
BotPlatform platform = BotPlatform.getInstance().loadConfigs("config.properties").configDependencies();
platform.getBaseReceiver().set(body).parse();
HashMap<String, MessageReceivedWebhook> messages = (HashMap<String, MessageReceivedWebhook>) platform.getBaseReceiver().getMessages();
for (MessageReceivedWebhook message : messages.values()) {
String user_id = (message.hasUserId()) ? message.getUserId() : "";
String page_id = (message.hasPageId()) ? message.getPageId() : "";
String message_id = (message.hasMessageId()) ? message.getMessageId() : "";
String message_text = (message.hasMessageText()) ? message.getMessageText() : "";
String quick_reply_payload = (message.hasQuickReplyPayload()) ? message.getQuickReplyPayload() : "";
Long timestamp = (message.hasTimestamp()) ? message.getTimestamp() : 0;
HashMap<String, String> attachments = (message.hasAttachment()) ? (HashMap<String, String>) message.getAttachment() : new HashMap<String, String>();
// Use Logger To Log Incoming Data
BotPlatform.getInstance().getLogger().info("User ID#:" + user_id);
BotPlatform.getInstance().getLogger().info("Page ID#:" + page_id);
BotPlatform.getInstance().getLogger().info("Message ID#:" + message_id);
BotPlatform.getInstance().getLogger().info("Message Text#:" + message_text);
BotPlatform.getInstance().getLogger().info("Quick Reply Payload#:" + quick_reply_payload);
for (String attachment : attachments.values()) {
BotPlatform.getInstance().getLogger().info("Attachment#:" + attachment);
}
return "ok";
}
// ..
// Other Receive Webhooks Goes Here
// ..
return "No Messages";
});
}
}
Let's create an empty message first and fill it with the required data. We can get a new message container from Bot Platform Instance:
MessageTemplate message_tpl = BotPlatform.getInstance().getBaseSender().getMessageTemplate();
// Let's start to fill the required data here
// ..
Here's some of the usage cases:
// get the message.getUserId() from the message received
// To send a seen mark
message_tpl.setRecipientId(message.getUserId());
message_tpl.setSenderAction("mark_seen");
BotPlatform.getInstance().getBaseSender().send(message_tpl);
// To send a typing on
message_tpl.setRecipientId(message.getUserId());
message_tpl.setSenderAction("typing_on");
BotPlatform.getInstance().getBaseSender().send(message_tpl);
// To send a typing off
message_tpl.setRecipientId(message.getUserId());
message_tpl.setSenderAction("typing_off");
BotPlatform.getInstance().getBaseSender().send(message_tpl);
// To send text message
message_tpl.setRecipientId(message.getUserId());
message_tpl.setMessageText("Hello World");
message_tpl.setNotificationType("REGULAR");
BotPlatform.getInstance().getBaseSender().send(message_tpl);
// To send an image
message_tpl.setRecipientId(message.getUserId());
message_tpl.setAttachment("image", "https://techslides.com/demos/samples/sample.jpg", false);
message_tpl.setNotificationType("SILENT_PUSH");
BotPlatform.getInstance().getBaseSender().send(message_tpl);
// To send file attachment
message_tpl.setRecipientId(message.getUserId());
message_tpl.setAttachment("file", "https://techslides.com/demos/samples/sample.pdf", false);
message_tpl.setNotificationType("NO_PUSH");
BotPlatform.getInstance().getBaseSender().send(message_tpl);
// To send a video
message_tpl.setRecipientId(message.getUserId());
message_tpl.setAttachment("video", "https://techslides.com/demos/samples/sample.mp4", false);
BotPlatform.getInstance().getBaseSender().send(message_tpl);
// To send an audio
message_tpl.setRecipientId(message.getUserId());
message_tpl.setAttachment("audio", "https://techslides.com/demos/samples/sample.mp3", false);
BotPlatform.getInstance().getBaseSender().send(message_tpl);
// To send a quick text reply with payload buttons
message_tpl.setRecipientId(message.getUserId());
message_tpl.setMessageText("Select a Color!");
message_tpl.setQuickReply("text", "Red", "text_reply_red_click", "");
message_tpl.setQuickReply("text", "Green", "text_reply_green_click", "");
message_tpl.setQuickReply("text", "Black", "text_reply_black_click", "");
BotPlatform.getInstance().getBaseSender().send(message_tpl);
// To send a quick text reply with payload buttons (Button with images)
message_tpl.setRecipientId(message.getUserId());
message_tpl.setMessageText("Select a Color!");
message_tpl.setQuickReply("text", "Red", "text_reply_red_click", "https://static.wixstatic.com/media/f0a6df_9ae4c70963244e16ba0d89d021407335.png");
message_tpl.setQuickReply("text", "Green", "text_reply_green_click", "https://static.wixstatic.com/media/f0a6df_9ae4c70963244e16ba0d89d021407335.png");
message_tpl.setQuickReply("text", "Black", "text_reply_black_click", "https://static.wixstatic.com/media/f0a6df_9ae4c70963244e16ba0d89d021407335.png");
BotPlatform.getInstance().getBaseSender().send(message_tpl);
// To send location reply
message_tpl.setRecipientId(message.getUserId());
message_tpl.setMessageText("Please share your location!");
message_tpl.setQuickReply("location", "", "", "");
BotPlatform.getInstance().getBaseSender().send(message_tpl);
Please note that to respond to custom payloads, Please do the following:
// To get the payload value, Use this code
// String quick_reply_payload = (message.hasQuickReplyPayload()) ? message.getQuickReplyPayload() : "";
// as shown before
if( quick_reply_payload.equals("text_reply_red_click") ){
message_tpl.setRecipientId(message.getUserId());
message_tpl.setMessageText("Red Clicked");
BotPlatform.getInstance().getBaseSender().send(message_tpl);
}else if( quick_reply_payload.equals("text_reply_green_click") ){
message_tpl.setRecipientId(message.getUserId());
message_tpl.setMessageText("Green Clicked");
BotPlatform.getInstance().getBaseSender().send(message_tpl);
}else if( quick_reply_payload.equals("text_reply_black_click") ){
message_tpl.setRecipientId(message.getUserId());
message_tpl.setMessageText("Black Clicked");
BotPlatform.getInstance().getBaseSender().send(message_tpl);
}
Let's create an empty message first and fill it with the required data. We can get a new message container from Bot Platform Instance:
ButtonTemplate button_message_tpl = BotPlatform.getInstance().getBaseSender().getButtonTemplate();
// Let's start to fill the required data here
// ..
Here's some of the usage cases:
// get the message.getUserId() from the message received
// To send a web url button
button_message_tpl.setRecipientId(message.getUserId());
button_message_tpl.setMessageText("Click Below!");
button_message_tpl.setButton("web_url", "Take the Hat Quiz", "https://m.me/petershats?ref=take_quiz", "");
BotPlatform.getInstance().getBaseSender().send(button_message_tpl);
// To send a postback button
button_message_tpl.setRecipientId(message.getUserId());
button_message_tpl.setMessageText("Click Below!");
button_message_tpl.setButton("postback", "Bookmark Item", "", "DEVELOPER_DEFINED_PAYLOAD");
BotPlatform.getInstance().getBaseSender().send(button_message_tpl);
// To send a phone number button
button_message_tpl.setRecipientId(message.getUserId());
button_message_tpl.setMessageText("Click Below!");
button_message_tpl.setButton("phone_number", "Call Representative", "", "+15105551234");
BotPlatform.getInstance().getBaseSender().send(button_message_tpl);
// To send account link button
button_message_tpl.setRecipientId(message.getUserId());
button_message_tpl.setMessageText("Click Below!");
button_message_tpl.setButton("account_link", "", "https://www.example.com/authorize", "");
BotPlatform.getInstance().getBaseSender().send(button_message_tpl);
// To send account unlink button
button_message_tpl.setRecipientId(message.getUserId());
button_message_tpl.setMessageText("Click Below!");
button_message_tpl.setButton("account_unlink", "", "", "");
BotPlatform.getInstance().getBaseSender().send(button_message_tpl);
Let's create an empty receipt message first and fill it with the required data. We can get a new receipt message container from Bot Platform Instance:
ReceiptTemplate receipt_message_tpl = BotPlatform.getInstance().getBaseSender().getReceiptTemplate();
// Let's start to fill the required data here
// ..
Here's some of the usage cases:
// get the message.getUserId() from the message received
// To send a receipt message
receipt_message_tpl.setRecipientId(message.getUserId());
receipt_message_tpl.setRecipientName("Stephane Crozatier");
receipt_message_tpl.setOrderNumber("12345678902");
receipt_message_tpl.setCurrency("USD");
receipt_message_tpl.setPaymentMethod("Visa 2345");
receipt_message_tpl.setOrderUrl("https://petersapparel.parseapp.com/order?order_id=123456");
receipt_message_tpl.setTimestamp("1428444852");
receipt_message_tpl.setElement("Classic White T-Shirt", "100% Soft and Luxurious Cotton", "2", "50", "USD", "https://image.spreadshirtmedia.com/image-server/v1/products/1001491830/views/1,width=800,height=800,appearanceId=2,version=1473664654/black-rap-nation-t-shirt-men-s-premium-t-shirt.png");
receipt_message_tpl.setElement("Classic Gray T-Shirt", "100% Soft and Luxurious Cotton", "2", "50", "USD", "https://static1.squarespace.com/static/57a088e05016e13b82b0beac/t/584fe89720099e4b5211c624/1481631899763/darts-is-my-religion-ally-pally-is-my-church-t-shirt-maenner-maenner-t-shirt.png");
receipt_message_tpl.setAddress("1 Hacker Way", "", "Menlo Park", "94025", "CA", "US");
receipt_message_tpl.setSummary("75.00", "4.95", "6.19", "56.14");
receipt_message_tpl.setAdjustment("New Customer Discount", "20");
receipt_message_tpl.setAdjustment("$10 Off Coupon", "10");
BotPlatform.getInstance().getBaseSender().send(receipt_message_tpl);
For almost all supported features you can take a look at
examples/
folder for working examples.
I am still working on the following:
- Building Your Messenger Chat Bot with Racter & SparkJava Framework.
- Building Your Messenger Chat Bot with Racter & Spring Framework.
- Building Your Messenger Chat Bot with Racter & Java Servlets.
- Building Your Messenger Chat Bot with Racter & Play Framework.
Version 1.0.0:
Initial Release
© 2017, Clivern. Released under the MIT License.
Racter is authored and maintained by @clivern.