Creating a Group Chat bot with Google App Engine

Hi in this post i will try to explain how to develop a chat bot for gmail actually this will work with any chat application that supports XMPP. Here i will explain how to develop a group chat application that can be used to chat with a group of people. I know you must be wondering why i would go through the trouble to make and app when gmail already supports group chats. Well the problem was that since our final year project was a 4 member group project we had a lot of online discussions but whenever someone would get disconnected they will loose the messages sent while they were offline and someone will have add that person back into the group. so one of my friends suggested me to write a app to solve this because i had written a small chat app before. Lets get started.

What is Google App Engine

I will assume that you are a bit familiar with Google App Engine. Well if you are not please take a look here to get an general understanding you only need the basic knowledge to follow this post.

Create a new Application in App Engine

Before we start you should create a new application in your App Engine account. Lets say the application name of my app is "gmailgroupchat" so the identifier of my app will be "gmailgroupchat.appspot.com". Now since we have an application id for our app lets see how to develop the app.

Setting up Google App Engine plugin in Eclipse.

Before you can start developing an application for the Google App Engine we have to set the working environment. I use eclipse as my IDE you can find the instruction to install the plugin here. There is also a plugin  available for Netbeans you can find the instructions for Netbeans here.

Creating a new project.

I assume that you have installed the App Engine plugin for Eclipse by now. to create a new project use File --> New --> Web Application Project. In the window that pops up set the name of your project this does not need to be same as the app id also untick the Google Web Toolkit box. Eclipse will generate the folder structure with some sample code.

Now to allow the App Engine to identify what this app is we have to set our app id in the "appengine-web.xml" that is located in war/WEB-INF

  <application>gmailgroupchat</application>
  <version>1</version>

Here the version indicates the version of your application App Engine gives you the ability to keep a number of versions of the same app.

NOTE: You will get and error of you try to deploy an application with a version number that already exists.

Now lets look at the Servlet code that will do all the work. I will explain what each part does step by step first lets look at the whole code.
public class GmailGroupChatServlet
    extends HttpServlet {
  
  private static final Logger LOG = 
      Logger.getLogger(GmailGroupChatServlet.class.getName());
  
  @Override
  public void doPost(HttpServletRequest req,
      HttpServletResponse resp) throws IOException {
    
    // Parse incoming message
    XMPPService xmpp = XMPPServiceFactory.getXMPPService();
    Message msg = xmpp.parseMessage(req);
    String body = msg.getBody();

     JID jid = msg.getFromJid();
     JID jid1 = new JID("email1@gmail.com");
     JID jid2 = new JID("email2@gmail.com");
     JID jid3 = new JID("email3@gmail.com");
     JID jid4 = new JID("email4@gmail.com");
    
   
    
    String response = "";
    if(jid.getId().split("/")[0].equals("email4@gmail.com")){
     response = "*Email4:* " + body;
      Message msg1 = new MessageBuilder()
         .withRecipientJids(jid1)
         .withBody(response)
         .build();
         xmpp.sendMessage(msg1);
      Message msg2 = new MessageBuilder()
         .withRecipientJids(jid2)
         .withBody(response)
         .build();
         xmpp.sendMessage(msg2);
      Message msg3 = new MessageBuilder()
         .withRecipientJids(jid3)
         .withBody(response)
         .build();
         xmpp.sendMessage(msg3);
     
     
    }else if(jid.getId().split("/")[0].equals("email3@gmail.com")){
     response = "*Email13:* " + body;
     Message msg1 = new MessageBuilder()
       .withRecipientJids(jid1)
       .withBody(response)
       .build();
       xmpp.sendMessage(msg1);
    Message msg2 = new MessageBuilder()
       .withRecipientJids(jid2)
       .withBody(response)
       .build();
       xmpp.sendMessage(msg2);
    Message msg3 = new MessageBuilder()
       .withRecipientJids(jid4)
       .withBody(response)
       .build();
       xmpp.sendMessage(msg3);
    }else if(jid.getId().split("/")[0].equals("email2@gmail.com")){
     response = "*Email2:* " + body;
     Message msg1 = new MessageBuilder()
       .withRecipientJids(jid1)
       .withBody(response)
       .build();
       xmpp.sendMessage(msg1);
    Message msg2 = new MessageBuilder()
       .withRecipientJids(jid3)
       .withBody(response)
       .build();
       xmpp.sendMessage(msg2);
    Message msg3 = new MessageBuilder()
       .withRecipientJids(jid4)
       .withBody(response)
       .build();
       xmpp.sendMessage(msg3);
    }else if(jid.getId().split("/")[0].equals("email1@gmail.com")){
     response = "*Email1:* " + body;
     Message msg1 = new MessageBuilder()
     .withRecipientJids(jid2)
     .withBody(response)
     .build();
     xmpp.sendMessage(msg1);
  Message msg2 = new MessageBuilder()
     .withRecipientJids(jid3)
     .withBody(response)
     .build();
     xmpp.sendMessage(msg2);
  Message msg3 = new MessageBuilder()
     .withRecipientJids(jid4)
     .withBody(response)
     .build();
     xmpp.sendMessage(msg3);
 
    }


  }
}

The following lines will parse the input message and save the string. Since we are developing a group chat what we have to do is simply forward the message to all the other members.
    XMPPService xmpp = XMPPServiceFactory.getXMPPService();
    Message msg = xmpp.parseMessage(req);
    String body = msg.getBody();

In the Follwing lines we define the id's of the users of the group chat. since this is made to be used with the 4 members of our group the id's are hard-coded. the created JID's will later be used to send the incoming messages to the other members.In the first line we capture the id of the message sender.

  
     JID jid = msg.getFromJid();
     JID jid1 = new JID("email1@gmail.com");
     JID jid2 = new JID("email2@gmail.com");
     JID jid3 = new JID("email3@gmail.com");
     JID jid4 = new JID("email4@gmail.com");

Then what we need to do is to make sure the sender does not get his own message back. The if conditions check the id of the message sender and makes sure that the sender does not get his own message. The String split is used because JID will contain additional information other than the email. The message is sent by this code.Here "withRecipientJids" sets the JID of the recipient of the message.
  
    Message msg1 = new MessageBuilder()
     .withRecipientJids(jid2)
     .withBody(response)
     .build();
     xmpp.sendMessage(msg1);

NOTE: The Servlet uses the doPost method because XMPP expects a post call.

Now to add the magic code that allows your Servlet to receive chat messages sent by users. Your "web.xml" should contain this code fragment that binds the Servlet to the magic URL pattern
  
   <servlet>
  <servlet-name>GmailGroupChatServlet</servlet-name>
  <servlet-class>com.appengine.capp.GmailGroupChatServlet</servlet-class>
 </servlet>
 <servlet-mapping>
  <servlet-name>GmailGroupChatServlet</servlet-name>
  <url-pattern>/_ah/xmpp/message/chat/</url-pattern>
 </servlet-mapping>

"/_ah/xmpp/message/chat/" is the magic URL pattern.Before we can deploy the application there is one more insertion we need to do in to the "appengine-web.xml" to enable XMPP for the java app. The following code fragment should be included.
  
  <inbound-services>
    <service>xmpp_message</service>
  </inbound-services>

Now you can deploy the application in to the App Engine to do this right click on the project select Google --> Deploy to App Engine. You will have to authenticate your self if you are doing it for the first time.

How to use the app.

In order to use this chat application each user has to send a invitation to the app requesting to chat in this example the chat id of the application will be "gmailgroupchat@appspot.com" because the identifier was 
"gmailgroupchat.appspot.com".

My first chat bot was a dictionary application that uses a Google API to reply with the meaning and pronunciation of the word entered to the chat bot . If someone is intersted you can use it by sending a chat request to "chatdictionary@appspot.com".

For further information on XMPP support in App Engine go here

Comments

  1. thanks for writing such a nice post !!
    it will be kind of you ..if u can share code of chatdictionary@appspot.com ..

    ReplyDelete
    Replies
    1. Hi Anil
      Thanks for your feedback. i would have loved to share the code of my chat dictionary but unfortunately i have lost the code. and no longer have it with me :( sorry.

      Delete
  2. Hi, i created a simple echo bot, but it isnt replying. wen i try to access the servlet in google app engine thers an error. please help

    http://stackoverflow.com/questions/11383078/chat-bot-using-google-app-engine-is-not-replying

    ReplyDelete
  3. hi, one more help :D

    http://stackoverflow.com/questions/11412174/how-does-one-send-chat-message-from-chat-bot-to-clients

    ReplyDelete
    Replies
    1. please have a look at it, i have updated the question. thank you.

      Delete
  4. how to display the chat sent by one user to other after parsing the chat msg?
    how to access through /_ah/xmpp/message/chat?

    Thanks

    ReplyDelete
    Replies
    1. Hi Davesh
      Sorry for the late reply i am pretty sure that u mush have solved the problem by now. If not can u explain the question a bit more i didn't clearly understand what your question is :).

      Delete
  5. Hey! I am very interested in if you have a lot of traffic on this weblog?

    ReplyDelete
    Replies
    1. Hi
      I just post a article now and then when i am free. Well i don't get that much of traffic around 1000 hits per month or so :). may i ask why you are interested if i have a lot of traffic :) ?

      Delete

Post a Comment

Popular posts from this blog

Writing Unit Tests to test JMS Queue listener code with ActiveMQ

Reading and Writing Binary files in java - Converting Endianness ( between Big-endian byte order and Little-endian byte order)

Setting up Heron Cluster with Apache Aurora Locally