All Downloads are FREE. Search and download functionalities are using the official Maven repository.

lyn.canaveral.0.1.source-code.RocketChatBot Maven / Gradle / Ivy

/*
 * Copyright 2017 Davide Riva [email protected]
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for any purpose and without fee is hereby
 * granted, provided that the above copyright notice appear in all
 * copies and that both that the copyright notice and this
 * permission notice and warranty disclaimer appear in supporting
 * documentation, and that the name of the author not be used in
 * advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.
 *
 * The author disclaim all warranties with regard to this
 * software, including all implied warranties of merchantability
 * and fitness.  In no event shall the author be liable for any
 * special, indirect or consequential damages or any damages
 * whatsoever resulting from loss of use, data or profits, whether
 * in an action of contract, negligence or other tortious action,
 * arising out of or in connection with the use or performance of
 * this software.
 */

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.URI;
import java.util.Date;
import java.util.Optional;

public abstract class RocketChatBot extends WebSocketClient implements AutoCloseable {
    private final String username;
    private final String password;
    private int idCounter = 1;
    private int msgIdCounter = 1; // Find a way to keep this number
    private boolean isLogged = false;
    private String token;
    private String loginId = "-1";

    public RocketChatBot(final URI serverURI,
                         final String username, final String password)
            throws RocketChatException {
        super(serverURI);

        this.username = username;
        this.password = password;

        try {
            setSocket(SSLSocketFactory.getDefault().createSocket(serverURI.getHost(), 443));
            super.connectBlocking();
        } catch (IOException | InterruptedException e) {
            throw new RocketChatException("Failed to connect to " + serverURI.toString(), e);
        }
    }

    public boolean isLogged() {
        return isLogged;
    }

    private String getNextId() {
        return new Date().getTime() + "-" + Integer.toString(idCounter++);
    }

    private String getNextMsgId() {
        return new Date().getTime() + "-" + Integer.toString(msgIdCounter++);
    }

    private JSONObject generateMethodCall(final String method, final JSONArray params) {
        final JSONObject methodCall = generateCall("method");
        methodCall.put("method", method);
        methodCall.put("params", params);

        return methodCall;
    }

    private JSONObject generateSubscriptionCall(final String name, final JSONArray params) {
        final JSONObject subscriptionCall = generateCall("sub");
        subscriptionCall.put("id", getNextId());
        subscriptionCall.put("name", name);
        subscriptionCall.put("params", params);

        return subscriptionCall;
    }

    private JSONObject generateCall(final String msg) {
        final JSONObject call = new JSONObject();
        call.put("msg", msg);
        call.put("id", getNextId());
        return call;
    }

    @Override
    public void onOpen(ServerHandshake serverHandshake) {
        connectMessage();
    }

    private void connectMessage() {
        final JSONObject connect = new JSONObject();
        connect.put("msg", "connect");
        connect.put("version", "1");

        final JSONArray support = new JSONArray();
        support.add("1");
        connect.put("support", support);

        super.send(connect.toString());
    }

    private JSONObject generateMessageObject(final String text,
                                             final String msgId, final String roomId,
                                             final Optional alias) {
        final JSONObject message = new JSONObject();
        message.put("_id", msgId);
        message.put("rid", roomId);
        message.put("msg", text);
        alias.ifPresent(a -> message.put("alias", a));

        return message;
    }

    public String sendMessage(final String text, final String roomId,
                              final Optional alias) {
        final String msgId = getNextMsgId();

        final JSONArray params = new JSONArray();
        params.add(generateMessageObject(text, msgId, roomId, alias));
        final JSONObject sendMessage = generateMethodCall("sendMessage", params);

        super.send(sendMessage.toString());
        return msgId;
    }

    public void updateMessage(final String text, final String msgId, final String roomId) {
        final JSONArray params = new JSONArray();
        params.add(generateMessageObject(text, msgId, roomId, Optional.empty()));
        final JSONObject updateMessage = generateMethodCall("updateMessage", params);
        super.send(updateMessage.toString());
    }

    private void loginMethod() {
        final JSONObject loginParams = new JSONObject();

        final JSONObject user = new JSONObject();
        user.put("username", username);
        loginParams.put("user", user);
        loginParams.put("password", password);

        final JSONArray params = new JSONArray();
        params.add(loginParams);

        final JSONObject loginMethod = generateMethodCall("login", params);
        loginId = (String) loginMethod.get("id");
        super.send(loginMethod.toString());
    }

    @Override
    public void onMessage(String s) {
        try {
            final JSONObject message = (JSONObject) new JSONParser().parse(s);
            System.out.println("Message: " + message.toString());

            final String msgKey = "msg";
            if (message.containsKey(msgKey)) {
                final String msg = (String) message.get(msgKey);
                if ("error".equals(msg))
                    System.err.println("Error: " + message.toString());
                else if ("ping".equals(msg)) {
                    final JSONObject pong = new JSONObject();
                    pong.put("msg", "pong");
                    super.send(pong.toString());
                } else if ("connected".equals(msg))
                    loginMethod();
                else if ("changed".equals(msg)) {
                    if (message.containsKey("collection")) {
                        final JSONObject fields = (JSONObject) message.get("fields");
                        final JSONArray args = (JSONArray) fields.get("args");
                        for (int i = 0; i < args.size(); i++) {
                            manageMessageReceived((JSONObject) args.get(i));
                        }
                    }
                } else if (message.containsKey("id")) {
                    if (message.get("id").equals(loginId))
                        manageLogin(message);
                }
            }
        } catch (ParseException e) {
            System.err.println("Message received is not a valid JSON: ");
            e.printStackTrace();
        }
    }

    private void manageMessageReceived(final JSONObject message) {
        final RocketChatMessage rcMsg = RocketChatMessage.parse(message);
        // It is an edited message
        if (message.containsKey("editedBy"))
            onMessageEdited(rcMsg);
        else
            onMessageReceived(rcMsg);
    }

    protected abstract void onMessageReceived(final RocketChatMessage message);

    protected abstract void onMessageEdited(final RocketChatMessage message);

    private void manageLogin(JSONObject message) {
        final JSONObject result = (JSONObject) message.get("result");

        final String tokenKey = "token";
        if (result.containsKey(tokenKey)) {
            token = (String) result.get(tokenKey);
            isLogged = true;
        }
    }

    @Override
    public void onClose(int i, String s, boolean b) {
        isLogged = false;
    }

    @Override
    public void onError(Exception e) {
        e.printStackTrace();
    }

    public void addRoom(final String roomId) {
        final JSONArray params = new JSONArray();
        params.add(roomId);
        params.add(false);
        final JSONObject stream = generateSubscriptionCall("stream-room-messages", params);
        super.send(stream.toString());
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy