A Java Framework for Building Bots on Facebook's Messenger Platform.

Overview

Racter Logo

Racter

A Java Framework for Building Bots on Facebook's Messenger Platform.

Documentation

Installation

To add a dependency using Maven, use the following:

<dependency>
    <groupId>com.cliverngroupId>
    <artifactId>racterartifactId>
    <version>1.0.5version>
dependency>

To add a dependency using Gradle, use the following:

dependencies {
    compile 'com.clivern:racter:1.0.5'
}

To add a dependency using Scala SBT, use the following:

libraryDependencies += "com.clivern" % "racter" % "1.0.5"

Usage

After adding the package as a dependency, Please read the following steps:

Basic Configurations

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
logging_level=debug
logging_file_path=src/main/java/resources/
logging_file_format=current_date
logging_log_type=file
logging_current_date_format=yyyy-MM-dd
logging_append=true
logging_buffered=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 = new BotPlatform("config.properties");

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("logging_level", "tarce or debug or info or warning or error");
options.put("logging_file_path", "src/main/java/resources/");
options.put("logging_file_format", "current_date or app");
options.put("logging_log_type", "file or console or both");
options.put("logging_current_date_format", "yyyy-MM-dd");
options.put("logging_append", "true or false");
options.put("logging_buffered", "true or false");

BotPlatform platform = new BotPlatform(options);

Setup Webhook

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 = new BotPlatform("config.properties");

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() ){

    // Set Response to be hubChallenge value and status code is 200 like
    // response.status(200);
    // return ( hubChallenge != null ) ? hubChallenge : "";
}

// 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:

{ BotPlatform platform = new BotPlatform("config.properties"); 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() ){ response.status(200); return ( request.queryParams("hub.challenge") != null ) ? request.queryParams("hub.challenge") : ""; } response.status(403); return "Verification token mismatch"; }); } }">
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 = new BotPlatform("config.properties");
            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() ){
                response.status(200);
                return ( request.queryParams("hub.challenge") != null ) ? request.queryParams("hub.challenge") : "";
            }

            response.status(403);
            return "Verification token mismatch";
        });
    }
}

Also if we use Spring Boot Framework for our bot, Our route and callback will look like the following:

package com.racter.example;

import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.stereotype.*;
import org.springframework.web.bind.annotation.*;

import com.clivern.racter.BotPlatform;
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;
import com.mashape.unirest.http.exceptions.UnirestException;

@Controller
@EnableAutoConfiguration
public class Main {

    @RequestMapping(method = RequestMethod.GET, value = "/")
    @ResponseBody
    String verifyToken(@RequestParam(value="hub.mode", defaultValue="") String hub_mode, @RequestParam(value="hub.verify_token", defaultValue="") String hub_verify_token, @RequestParam(value="hub.challenge", defaultValue="") String hub_challenge ) throws IOException {

        BotPlatform platform = new BotPlatform("src/main/java/resources/config.properties");
        platform.getVerifyWebhook().setHubMode(hub_mode);
        platform.getVerifyWebhook().setHubVerifyToken(hub_verify_token);
        platform.getVerifyWebhook().setHubChallenge(hub_challenge);

        if( platform.getVerifyWebhook().challenge() ){
            return ( hub_challenge != "" ) ? hub_challenge : "";
        }

        return "Verification token mismatch";
    }
}

Also if we use Play Framework for our bot, Our route and callback will look like the following:

package controllers;

import play.mvc.*;
import play.mvc.Http.RequestBody;

import com.clivern.racter.BotPlatform;
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;
import com.mashape.unirest.http.exceptions.UnirestException;

/**
 * Home Controller
 */
public class HomeController extends Controller {

    protected String basePath = System.getProperty("user.dir");

    public Result verifyToken() throws IOException
    {
        BotPlatform platform = new BotPlatform(this.basePath + "/conf/racter.properties");
        platform.getVerifyWebhook().setHubMode(request().getQueryString("hub.mode"));
        platform.getVerifyWebhook().setHubVerifyToken(request().getQueryString("hub.verify_token"));
        platform.getVerifyWebhook().setHubChallenge(request().getQueryString("hub.challenge"));

        if( platform.getVerifyWebhook().challenge() ){
            return ( request().getQueryString("hub.challenge") != null ) ? ok(request().getQueryString("hub.challenge")) : ok();
        }

        return ok("Verification token mismatch");
    }
}

Message Received

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:

messages = (HashMap ) 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 attachments = (message.hasAttachment()) ? (HashMap ) message.getAttachment() : new HashMap (); }">
String body = // Get current Request Body
BotPlatform platform = new BotPlatform("config.properties");
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:

{ BotPlatform platform = new BotPlatform("config.properties"); 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() ){ response.status(200); return ( request.queryParams("hub.challenge") != null ) ? request.queryParams("hub.challenge") : ""; } response.status(403); return "Verification token mismatch"; }); post("/", (request, response) -> { String body = request.body(); BotPlatform platform = new BotPlatform("config.properties"); platform.getBaseReceiver().set(body).parse(); HashMap messages = (HashMap ) 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 attachments = (message.hasAttachment()) ? (HashMap ) message.getAttachment() : new HashMap (); // Use Logger To Log Incoming Data Logger.info("User ID#:" + user_id); Logger.info("Page ID#:" + page_id); Logger.info("Message ID#:" + message_id); Logger.info("Message Text#:" + message_text); Logger.info("Quick Reply Payload#:" + quick_reply_payload); for (String attachment : attachments.values()) { Logger.info("Attachment#:" + attachment); } return "ok"; } // .. // Other Receive Webhooks Goes Here // .. return "No Messages"; }); } }">
import static spark.Spark.*;
import org.pmw.tinylog.Logger;

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 = new BotPlatform("config.properties");
            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() ){
                response.status(200);
                return ( request.queryParams("hub.challenge") != null ) ? request.queryParams("hub.challenge") : "";
            }

            response.status(403);
            return "Verification token mismatch";
        });

        post("/", (request, response) -> {
            String body = request.body();
            BotPlatform platform = new BotPlatform("config.properties");
            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
                Logger.info("User ID#:" + user_id);
                Logger.info("Page ID#:" + page_id);
                Logger.info("Message ID#:" + message_id);
                Logger.info("Message Text#:" + message_text);
                Logger.info("Quick Reply Payload#:" + quick_reply_payload);

                for (String attachment : attachments.values()) {
                    Logger.info("Attachment#:" + attachment);
                }

                return "ok";
            }

            // ..
            // Other Receive Webhooks Goes Here
            // ..

            return "No Messages";
        });
    }
}

Also if we use Spring Boot Framework for our bot, Our route and callback will look like the following:

messages = (HashMap ) 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 attachments = (message.hasAttachment()) ? (HashMap ) message.getAttachment() : new HashMap (); // Use Logger To Log Incoming Data Logger.info("User ID#:" + user_id); Logger.info("Page ID#:" + page_id); Logger.info("Message ID#:" + message_id); Logger.info("Message Text#:" + message_text); Logger.info("Quick Reply Payload#:" + quick_reply_payload); for (String attachment : attachments.values()) { Logger.info("Attachment#:" + attachment); } return "ok"; } // .. // Other Receive Webhooks Goes Here // .. return "No Messages"; } }">
package com.racter.example;

import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.stereotype.*;
import org.springframework.web.bind.annotation.*;
import org.pmw.tinylog.Logger;

import com.clivern.racter.BotPlatform;
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;
import com.mashape.unirest.http.exceptions.UnirestException;

@Controller
@EnableAutoConfiguration
public class Main {

    @RequestMapping(method = RequestMethod.GET, value = "/")
    @ResponseBody
    String verifyToken(@RequestParam(value="hub.mode", defaultValue="") String hub_mode, @RequestParam(value="hub.verify_token", defaultValue="") String hub_verify_token, @RequestParam(value="hub.challenge", defaultValue="") String hub_challenge ) throws IOException {

        BotPlatform platform = new BotPlatform("src/main/java/resources/config.properties");
        platform.getVerifyWebhook().setHubMode(hub_mode);
        platform.getVerifyWebhook().setHubVerifyToken(hub_verify_token);
        platform.getVerifyWebhook().setHubChallenge(hub_challenge);

        if( platform.getVerifyWebhook().challenge() ){
            return ( hub_challenge != "" ) ? hub_challenge : "";
        }
        return "Verification token mismatch";
    }

    @RequestMapping(method = RequestMethod.POST, value = "/")
    @ResponseBody
    String webHook(@RequestBody String body) throws IOException, UnirestException {
        BotPlatform platform = new BotPlatform("config.properties");
        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
            Logger.info("User ID#:" + user_id);
            Logger.info("Page ID#:" + page_id);
            Logger.info("Message ID#:" + message_id);
            Logger.info("Message Text#:" + message_text);
            Logger.info("Quick Reply Payload#:" + quick_reply_payload);

            for (String attachment : attachments.values()) {
                Logger.info("Attachment#:" + attachment);
            }

            return "ok";
        }

        // ..
        // Other Receive Webhooks Goes Here
        // ..

        return "No Messages";
    }
}

Also if we use Play Framework for our bot, Our route and callback will look like the following:

messages = (HashMap ) 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 attachments = (message.hasAttachment()) ? (HashMap ) message.getAttachment() : new HashMap (); Logger.info("User ID#:" + user_id); Logger.info("Page ID#:" + page_id); Logger.info("Message ID#:" + message_id); Logger.info("Message Text#:" + message_text); Logger.info("Quick Reply Payload#:" + quick_reply_payload); for (String attachment : attachments.values()) { Logger.info("Attachment#:" + attachment); } return ok("ok"); } // .. // Other Receive Webhooks Goes Here // .. return ok("No Messages"); } }">
package controllers;

import play.mvc.*;
import play.mvc.Http.RequestBody;
import org.pmw.tinylog.Logger;

import com.clivern.racter.BotPlatform;
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;
import com.mashape.unirest.http.exceptions.UnirestException;

/**
 * Home Controller
 */
public class HomeController extends Controller {

    protected String basePath = System.getProperty("user.dir");

    public Result verifyToken() throws IOException
    {
        BotPlatform platform = new BotPlatform(this.basePath + "/conf/racter.properties");
        platform.getVerifyWebhook().setHubMode(request().getQueryString("hub.mode"));
        platform.getVerifyWebhook().setHubVerifyToken(request().getQueryString("hub.verify_token"));
        platform.getVerifyWebhook().setHubChallenge(request().getQueryString("hub.challenge"));

        if( platform.getVerifyWebhook().challenge() ){
            return ( request().getQueryString("hub.challenge") != null ) ? ok(request().getQueryString("hub.challenge")) : ok();
        }
        return ok("Verification token mismatch");
    }

    public Result webHook()  throws IOException, UnirestException
    {
        String body = request().body().asJson().toString();
        BotPlatform platform = new BotPlatform(this.basePath + "/conf/racter.properties");
        platform.getBaseReceiver().set(body.asText()).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>();

            Logger.info("User ID#:" + user_id);
            Logger.info("Page ID#:" + page_id);
            Logger.info("Message ID#:" + message_id);
            Logger.info("Message Text#:" + message_text);
            Logger.info("Quick Reply Payload#:" + quick_reply_payload);

            for (String attachment : attachments.values()) {
                Logger.info("Attachment#:" + attachment);
            }

            return ok("ok");
        }
        // ..
        // Other Receive Webhooks Goes Here
        // ..


        return ok("No Messages");
    }
}

Send API

Sending Message

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 = platform.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");
platform.getBaseSender().send(message_tpl);


// To send a typing on
message_tpl.setRecipientId(message.getUserId());
message_tpl.setSenderAction("typing_on");
platform.getBaseSender().send(message_tpl);


// To send a typing off
message_tpl.setRecipientId(message.getUserId());
message_tpl.setSenderAction("typing_off");
platform.getBaseSender().send(message_tpl);


// To send text message
message_tpl.setRecipientId(message.getUserId());
message_tpl.setMessageText("Hello World");
message_tpl.setNotificationType("REGULAR");
platform.getBaseSender().send(message_tpl);


// To send an image
message_tpl.setRecipientId(message.getUserId());
message_tpl.setAttachment("image", "http://techslides.com/demos/samples/sample.jpg", false);
message_tpl.setNotificationType("SILENT_PUSH");
platform.getBaseSender().send(message_tpl);


// To send file attachment
message_tpl.setRecipientId(message.getUserId());
message_tpl.setAttachment("file", "http://techslides.com/demos/samples/sample.pdf", false);
message_tpl.setNotificationType("NO_PUSH");
platform.getBaseSender().send(message_tpl);


// To send a video
message_tpl.setRecipientId(message.getUserId());
message_tpl.setAttachment("video", "http://techslides.com/demos/samples/sample.mp4", false);
platform.getBaseSender().send(message_tpl);


// To send an audio
message_tpl.setRecipientId(message.getUserId());
message_tpl.setAttachment("audio", "http://techslides.com/demos/samples/sample.mp3", false);
platform.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", "");
platform.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", "http://static.wixstatic.com/media/f0a6df_9ae4c70963244e16ba0d89d021407335.png");
message_tpl.setQuickReply("text", "Green", "text_reply_green_click", "http://static.wixstatic.com/media/f0a6df_9ae4c70963244e16ba0d89d021407335.png");
message_tpl.setQuickReply("text", "Black", "text_reply_black_click", "http://static.wixstatic.com/media/f0a6df_9ae4c70963244e16ba0d89d021407335.png");
platform.getBaseSender().send(message_tpl);


// To send location reply
message_tpl.setRecipientId(message.getUserId());
message_tpl.setMessageText("Please share your location!");
message_tpl.setQuickReply("location", "", "", "");
platform.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");
    platform.getBaseSender().send(message_tpl);

}else if( quick_reply_payload.equals("text_reply_green_click") ){

    message_tpl.setRecipientId(message.getUserId());
    message_tpl.setMessageText("Green Clicked");
    platform.getBaseSender().send(message_tpl);

}else if( quick_reply_payload.equals("text_reply_black_click") ){

    message_tpl.setRecipientId(message.getUserId());
    message_tpl.setMessageText("Black Clicked");
    platform.getBaseSender().send(message_tpl);

}

Sending Button Message

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 = platform.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", "", "");
platform.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", "");
platform.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", "");
platform.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", "", "");
platform.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", "", "", "", "");
platform.getBaseSender().send(button_message_tpl);

Sending List Message

Let's create an empty list message first and fill it with the required data. We can get a new list message container from Bot Platform Instance:

ListTemplate list_message_tpl = platform.getBaseSender().getListTemplate();

// Let's start to fill the required data here
// ..

Sending Generic Message

Let's create an empty generic message first and fill it with the required data. We can get a new generic message container from Bot Platform Instance:

GenericTemplate generic_message_tpl = platform.getBaseSender().getGenericTemplate();

// Let's start to fill the required data here
// ..

Sending Receipt Message

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 = platform.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("http://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");
platform.getBaseSender().send(receipt_message_tpl);

Tutorials & Examples

For almost all supported features you can take a look at examples/ folder for working examples.

Also check the following tutorials:

  1. Building Your Messenger Chat Bot with Racter & SparkJava Framework.

Versioning

For transparency into our release cycle and in striving to maintain backward compatibility, Racter is maintained under the Semantic Versioning guidelines and release process is predictable and business-friendly.

See the Releases section of our GitHub project for changelogs for each release version of Racter. It contains summaries of the most noteworthy changes made in each release.

Bug tracker

If you have any suggestions, bug reports, or annoyances please report them to our issue tracker at https://github.com/clivern/racter/issues

Security Issues

If you discover a security vulnerability within Racter, please send an email to [email protected]

Contributing

We are an open source, community-driven project so please feel free to join us. see the contributing guidelines for more details.

License

Β© 2019, Clivern. Released under Apache License, Version 2.0.

Racter is authored and maintained by @Clivern.

Comments
  • Update dependency gradle to v6.5

    Update dependency gradle to v6.5

    This PR contains the following updates:

    | Package | Update | Change | |---|---|---| | gradle (source) | minor | 6.4.1 -> 6.5 |


    Renovate configuration

    :date: Schedule: At any time (no schedule defined).

    :vertical_traffic_light: Automerge: Disabled by config. Please merge this manually once you are satisfied.

    :recycle: Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    :no_bell: Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, check this box

    This PR has been generated by WhiteSource Renovate. View repository job log here.

    merge 
    opened by renovate[bot] 2
  • Update dependency com.diffplug.gradle.spotless:com.diffplug.gradle.spotless.gradle.plugin to v4.1.0

    Update dependency com.diffplug.gradle.spotless:com.diffplug.gradle.spotless.gradle.plugin to v4.1.0

    This PR contains the following updates:

    | Package | Update | Change | |---|---|---| | com.diffplug.gradle.spotless:com.diffplug.gradle.spotless.gradle.plugin | minor | 4.0.1 -> 4.1.0 |


    Renovate configuration

    :date: Schedule: At any time (no schedule defined).

    :vertical_traffic_light: Automerge: Disabled by config. Please merge this manually once you are satisfied.

    :recycle: Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    :no_bell: Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, check this box

    This PR has been generated by WhiteSource Renovate. View repository job log here.

    merge 
    opened by renovate[bot] 2
  • Update dependency com.squareup.okhttp3:okhttp to v4.10.0

    Update dependency com.squareup.okhttp3:okhttp to v4.10.0

    Mend Renovate

    This PR contains the following updates:

    | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | com.squareup.okhttp3:okhttp (source) | 4.9.3 -> 4.10.0 | age | adoption | passing | confidence |


    Configuration

    πŸ“… Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by Mend Renovate. View repository job log here.

    opened by renovate[bot] 1
  • Update dependency org.json:json to v20220320

    Update dependency org.json:json to v20220320

    WhiteSource Renovate

    This PR contains the following updates:

    | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | org.json:json | 20211205 -> 20220320 | age | adoption | passing | confidence |


    Release Notes

    douglascrockford/JSON-java

    v20220320

    Compare Source

    | Pull Request | Description | |---------------|--------------| | #​660 | Wrap StackOverflow with JSONException |


    Configuration

    πŸ“… Schedule: At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by WhiteSource Renovate. View repository job log here.

    opened by renovate[bot] 1
  • Update actions/setup-java action to v3

    Update actions/setup-java action to v3

    WhiteSource Renovate

    This PR contains the following updates:

    | Package | Type | Update | Change | |---|---|---|---| | actions/setup-java | action | major | v1 -> v3 |


    Release Notes

    actions/setup-java

    v3

    Compare Source

    v2

    Compare Source


    Configuration

    πŸ“… Schedule: At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by WhiteSource Renovate. View repository job log here.

    opened by renovate[bot] 1
  • Update dependency gradle to v6.9.2

    Update dependency gradle to v6.9.2

    WhiteSource Renovate

    This PR contains the following updates:

    | Package | Update | Change | |---|---|---| | gradle (source) | patch | 6.9.1 -> 6.9.2 |


    Release Notes

    gradle/gradle

    v6.9.2

    This is a patch release for Gradle 6.9, containing backported bugfixes in Gradle 7.2 to Gradle 6.x.

    It fixes the following issues:

    • #​18163 Fix excludes for substituted dependencies
    • #​18164 POSIX shell scripts improvements
    • #​18697 Fix corrupted resolution result from replacement / capability conflict
    • #​19328 Mitigations for log4j vulnerability in Gradle builds
    • #​19372 Multiple transformed artifacts selected

    We recommend users upgrade to 6.9.2 instead of 6.9.

    Given the context of the Log4Shell vulnerability, make sure you take a look at our blog post on this topic.

    Upgrade Instructions

    Switch your build to use Gradle 6.9.2 by updating your wrapper:

    ./gradlew wrapper --gradle-version=6.9.2
    

    See the Gradle 6.x upgrade guide to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.9.2.

    Reporting Problems

    If you find a problem with this release, please file a bug on GitHub Issues adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the forum.


    Configuration

    πŸ“… Schedule: At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by WhiteSource Renovate. View repository job log here.

    opened by renovate[bot] 1
  • Update dependency org.json:json to v20211205

    Update dependency org.json:json to v20211205

    WhiteSource Renovate

    This PR contains the following updates:

    | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | org.json:json | 20210307 -> 20211205 | age | adoption | passing | confidence |


    Release Notes

    douglascrockford/JSON-java

    v20211205

    Compare Source

    | Pull Request | Description | |---------------|--------------| | #​651 | IdentityHashSet for JSONObject cycle detection | | #​646 | XMLParserConfiguration defined json arrays option | | #​645 | Handle circular references in Java beans | | #​640 | Unit tests for multiple backslashes in JSONPointer | | #​637 | Reorganized README.md | | #​634 | Update README with Unix examples | | #​631 | Refactor JSONPointerTest | | #​626 | Add CODE_OF_CONDUCT.md | | #​622 | Clean up readme.md | | #​621 | Clean up comments | | #​617 | JSONObject.similar() numeric compare bug fix | | #​613 | JsonObject.similar() number entry check bug fix | | #​610 | optJSONObject() add default value | | #​607 | Add Security.md policy page | | #​606 | Clean up comments, add suppressWarning annotation | | #​604 | Fixed incorrect cast getting float from array | | #​601 | Added Examples.md for new users | | #​594 | JSONStringer.java: fix max nesting level in javadoc |


    Configuration

    πŸ“… Schedule: At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by WhiteSource Renovate. View repository job log here.

    opened by renovate[bot] 1
  • Update dependency com.squareup.okhttp3:okhttp to v4.9.3

    Update dependency com.squareup.okhttp3:okhttp to v4.9.3

    WhiteSource Renovate

    This PR contains the following updates:

    | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | com.squareup.okhttp3:okhttp (source) | 4.9.2 -> 4.9.3 | age | adoption | passing | confidence |


    Release Notes

    square/okhttp

    v4.9.3

    2021-11-21

    • Fix: Don't fail HTTP/2 responses if they complete before a RST_STREAM is sent.

    Configuration

    πŸ“… Schedule: At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by WhiteSource Renovate. View repository job log here.

    opened by renovate[bot] 1
  • Update plugin com.diffplug.gradle.spotless to v6

    Update plugin com.diffplug.gradle.spotless to v6

    WhiteSource Renovate

    This PR contains the following updates:

    | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | com.diffplug.gradle.spotless | 4.5.1 -> 6.0.4 | age | adoption | passing | confidence |


    Configuration

    πŸ“… Schedule: At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by WhiteSource Renovate. View repository job log here.

    opened by renovate[bot] 1
  • Update plugin com.diffplug.gradle.spotless to v5

    Update plugin com.diffplug.gradle.spotless to v5

    WhiteSource Renovate

    This PR contains the following updates:

    | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | com.diffplug.gradle.spotless | 4.5.1 -> 5.17.0 | age | adoption | passing | confidence |


    Configuration

    πŸ“… Schedule: At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by WhiteSource Renovate. View repository job log here.

    opened by renovate[bot] 1
  • Update dependency gradle to v6.9.1

    Update dependency gradle to v6.9.1

    WhiteSource Renovate

    This PR contains the following updates:

    | Package | Update | Change | |---|---|---| | gradle (source) | patch | 6.9 -> 6.9.1 |


    Release Notes

    gradle/gradle

    v6.9.1

    This is a patch release for Gradle 6.9, containing backported bugfixes in Gradle 7.2 to Gradle 6.x.

    It fixes the following issues:

    • #​18089 Deprecate jcenter() repository
    • #​17950 Renaming and recreating the project directory causes Gradle to lose track of changes on Windows
    • #​17949 Gradle's up-to-date checks do not work on Windows FAT drives

    We recommend users upgrade to 6.9.1 instead of 6.9.

    Upgrade Instructions

    Switch your build to use Gradle 6.9.1 by updating your wrapper:

    ./gradlew wrapper --gradle-version=6.9.1
    

    See the Gradle 6.x upgrade guide to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.9.1.

    Reporting Problems

    If you find a problem with this release, please file a bug on GitHub Issues adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the forum.


    Configuration

    πŸ“… Schedule: At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, check this box.

    This PR has been generated by WhiteSource Renovate. View repository job log here.

    opened by renovate[bot] 1
  • Update dependency gradle to v6.9.3

    Update dependency gradle to v6.9.3

    Mend Renovate

    This PR contains the following updates:

    | Package | Update | Change | |---|---|---| | gradle (source) | patch | 6.9.2 -> 6.9.3 |


    Release Notes

    gradle/gradle

    v6.9.3: 6.9.3

    This is a patch release for Gradle 6.9, containing backported bugfixes in Gradle 7.x to Gradle 6.x.

    It fixes the following issues:

    • #​19523 Fix buffer overflow error in KryoBackedDecoder [Backport 6.x]
    • #​20189 Support constraints without version in GMM [Backport 6.9.x]
    • #​22358 Missing exclude rule merging optimizations

    We recommend users upgrade to 6.9.3 instead of 6.9.

    Upgrade Instructions

    Switch your build to use Gradle 6.9.3 by updating your wrapper:

    ./gradlew wrapper --gradle-version=6.9.3
    

    See the Gradle 6.x upgrade guide to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.9.3.

    Reporting Problems

    If you find a problem with this release, please file a bug on GitHub Issues adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the forum.


    Configuration

    πŸ“… Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, check this box

    This PR has been generated by Mend Renovate. View repository job log here.

    opened by renovate[bot] 0
  • Update dependency org.json:json to v20220924

    Update dependency org.json:json to v20220924

    Mend Renovate

    This PR contains the following updates:

    | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | org.json:json | 20220320 -> 20220924 | age | adoption | passing | confidence |


    Release Notes

    douglascrockford/JSON-java

    v20220924

    Compare Source

    | Pull Request | Description | |---------------|--------------| | #​688 | Update copyright to Public Domain | | #​687 | Fix a typo | | #​685 | JSONObject map type unit tests | | #​684 | Remove v7 build from pipeline | | #​682 | JSONString similarity | | #​675 | https://github.com/stleary/JSON-java/pull/675 |


    Configuration

    πŸ“… Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    β™» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    πŸ”• Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, check this box

    This PR has been generated by Mend Renovate. View repository job log here.

    opened by renovate[bot] 0
  • Dependency Dashboard

    Dependency Dashboard

    This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

    Open

    These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

    Ignored or Blocked

    These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

    Detected dependencies

    github-actions
    .github/workflows/ci.yml
    • actions/setup-java v1
    gradle
    maven-push.gradle
    settings.gradle
    build.gradle
    • com.diffplug.gradle.spotless 4.5.1
    • junit:junit 4.13.2
    • com.squareup.okhttp3:okhttp 4.10.0
    • org.json:json 20220320
    • org.tinylog:tinylog 1.3.6
    gradle-wrapper
    gradle/wrapper/gradle-wrapper.properties
    • gradle 6.9.2

    • [ ] Check this box to trigger a request for Renovate to run again on this repository
    opened by renovate[bot] 0
  • Response is not deliverd if there is a newline character in the

    Response is not deliverd if there is a newline character in the "text" response

    Describe the bug The response is not delivered if there is a newline character in the "text" response

    To Reproduce Steps to reproduce the behaviour: If we set the MessageTemplate to send a text reply where the text has a newline character, the response is not delivered.

    INFO: curl -X POST -H "Content-Type: application/json" -d '{"recipient": {"id": "1234567890"},"message": {"text": "Reply with image answer. This is line number 1. The next line is a new line (Line number 2 is empty line).
    
    This is line number 3."},"notification_type":"REGULAR"}
    

    Expected behaviour The response should be submitted with a new line for every newline character.

    opened by lcbasu 1
Releases(v1.0.5)
Owner
Ahmed
Ahmed
A server-state reactive Java web framework for building real-time user interfaces and UI components.

RSP About Maven Code examples HTTP requests routing HTML markup Java DSL Page state model Single-page application Navigation bar URL path UI Component

Vadim Vashkevich 33 Jul 13, 2022
An evolving set of open source web components for building mobile and desktop web applications in modern browsers.

Vaadin components Vaadin components is an evolving set of high-quality user interface web components commonly needed in modern mobile and desktop busi

Vaadin 519 Dec 31, 2022
CUBA Platform is a high level framework for enterprise applications development

Java RAD framework for enterprise web applications Website | Online Demo | Documentation | Guides | Forum CUBA Platform is a high level framework for

CUBA Platform 1.3k Jan 1, 2023
Bootique is a minimally opinionated platform for modern runnable Java apps.

Bootique is a minimally opinionated java launcher and integration technology. It is intended for building container-less runnable Java applications. W

Bootique Project 1.4k Dec 29, 2022
Vaadin 6, 7, 8 is a Java framework for modern Java web applications.

Vaadin Framework Vaadin allows you to build modern web apps efficiently in plain Java, without touching low level web technologies. This repository co

Vaadin 1.7k Jan 5, 2023
Ninja is a full stack web framework for Java. Rock solid, fast and super productive.

_______ .___ _______ ____. _____ \ \ | |\ \ | | / _ \ / | \| |/ | \ | |/ /_\ \ / | \

Ninja Web Framework 1.9k Jan 5, 2023
The modular web framework for Java and Kotlin

∞ do more, more easily Jooby is a modern, performant and easy to use web framework for Java and Kotlin built on top of your favorite web server. Java:

jooby 1.5k Dec 16, 2022
Apache Wicket - Component-based Java web framework

What is Apache Wicket? Apache Wicket is an open source, java, component based, web application framework. With proper mark-up/logic separation, a POJO

The Apache Software Foundation 657 Dec 31, 2022
Micro Java Web Framework

Micro Java Web Framework It's an open source (Apache License) micro web framework in Java, with minimal dependencies and a quick learning curve. The g

Pippo 769 Dec 19, 2022
True Object-Oriented Java Web Framework

Project architect: @paulodamaso Takes is a true object-oriented and immutable Java8 web development framework. Its key benefits, comparing to all othe

Yegor Bugayenko 748 Dec 23, 2022
An Intuitive, Lightweight, High Performance Full Stack Java Web Framework.

mangoo I/O mangoo I/O is a Modern, Intuitive, Lightweight, High Performance Full Stack Java Web Framework. It is a classic MVC-Framework. The foundati

Sven Kubiak 52 Oct 31, 2022
A simple expressive web framework for java. Spark has a kotlin DSL https://github.com/perwendel/spark-kotlin

Spark - a tiny web framework for Java 8 Spark 2.9.3 is out!! Changeset <dependency> <groupId>com.sparkjava</groupId> <artifactId>spark-core</a

Per Wendel 9.4k Dec 29, 2022
A web MVC action-based framework, on top of CDI, for fast and maintainable Java development.

A web MVC action-based framework, on top of CDI, for fast and maintainable Java development. Downloading For a quick start, you can use this snippet i

Caelum 347 Nov 15, 2022
This is a Playwright Java Framework written in POM

Playwright Java Framework Main Objective of this Framework is to Build an Automation Framework that can be scalable, Easily Configurable and Ready to

AutoInfra 11 Oct 17, 2022
Javalin - A simple web framework for Java and Kotlin

Javalin is a very lightweight web framework for Kotlin and Java which supports WebSockets, HTTP2 and async requests. Javalin’s main goals are simplicity, a great developer experience, and first class interoperability between Kotlin and Java.

David (javalin.io) 6.2k Jan 6, 2023
Spring Framework

Spring Framework This is the home of the Spring Framework: the foundation for all Spring projects. Collectively the Spring Framework and the family of

Spring 50.4k Jan 9, 2023
Play Framework

Play Framework - The High Velocity Web Framework The Play Framework combines productivity and performance making it easy to build scalable web applica

Play Framework 12.3k Dec 29, 2022
:rocket: Lightning fast and elegant mvc framework for Java8

Based on Java8 + Netty4 to create a lightweight, high-performance, simple and elegant Web framework ?? Spend 1 hour to learn it to do something intere

Blade Framework 5.7k Dec 28, 2022
The Grails Web Application Framework

Build Status Slack Signup Slack Signup Grails Grails is a framework used to build web applications with the Groovy programming language. The core fram

grails 2.7k Jan 5, 2023