title: Retrieve Offline Messages and Chat History From Google Talk in Java
body: <p>I have to retrieve offline messages from Google Talk for a particular client (friend/ XMPP Client) with whom I have had a conversationn with.</p>
  
  <p>Additionally, I want to retrieve the chat history.</p>
  
  <p>Right now, I am using a Hash Map to keep track of the conversation and have no means of having the offline messages.</p>
  
  <p>I have made an XMPP connection to "talk.google.com". I am currently able to send messages to the client via my console. I have implemented the Message Listener Interface and hence can receive messages in my console itself. </p>
  
  <p>I have another implementaion(made use of OfflineMessageManager) where I try to extract the offline messages headers as a start, unfortunately, it fails with Null Exception.</p>
  
  <p>I have used smack-tcp version 4.0.3 and smackx 3.1.0.</p>
  
  <p>Please find below what I have tried till now...</p>
  
  <p>Working Implementation: </p>
  
  <p>public class StartChatImpl implements startChat, MessageListener {</p>
  
  <pre><code>static XMPPConnection myXMPPConnection;
  static ArrayList&lt;String&gt; myFriends = new ArrayList&lt;String&gt;();
  ArrayList&lt;Msg&gt; messages;
  HashMap&lt;String,ArrayList&gt; conversation = new HashMap&lt;String, ArrayList&gt;();
  
  OfflineMessageManager offlineMessages;
  
  
  @Override
  public void engageChat(ChatRequest chatRequest) throws XMPPException {
  
  
      ConnectionConfiguration config = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
      //config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
      config.setSendPresence(true);
      myXMPPConnection = new XMPPTCPConnection(config);
  
  
      try{
  
          System.out.println("Connecting to talk.google.com");
          myXMPPConnection.connect();
  
          System.out.println("Logging you in...");
          myXMPPConnection.login(chatRequest.getUsername(),chatRequest.getPassword());
  
          Presence pres = new Presence(Presence.Type.unavailable);
  
          myXMPPConnection.sendPacket(pres);
  
          offlineMessages = new OfflineMessageManager(myXMPPConnection);
  
          System.out.println("You have been successfully connected.");
  
      } catch (SmackException e) {
          e.printStackTrace();
      } catch (IOException e) {
          e.printStackTrace();
      }
  
  
  }
  
  public void send (String message, String to) throws XMPPException
  {
      Chat chat = ChatManager.getInstanceFor(myXMPPConnection).createChat(to, this);
      //System.out.println("********************************************");
      //System.out.println("CHAT ID: "+ chat.getThreadID());
      //System.out.println("Participant: "+chat.getParticipant());
      //System.out.println("********************************************");
  
      try {
          chat.sendMessage(message);
  
          String friendName = myXMPPConnection.getRoster().getEntry(chat.getParticipant()).getName();
  
          if(conversation.containsKey(friendName))
          {
  
              messages = conversation.get(friendName);
              Calendar calendar = Calendar.getInstance();
              java.util.Date now = calendar.getTime();
              java.sql.Timestamp currentTimestamp = new java.sql.Timestamp(now.getTime());
              message = "bot says: "+message;
              Msg actualMsg = new Msg(currentTimestamp,message,"bot");
              messages.add(actualMsg);
              //messages.add("bot says: "+message);
  
          }
          else
          {
              messages = new ArrayList&lt;Msg&gt;();
              //messages.add("Bot initiated the conversation on: "+new Date());
              //messages.add("bot says: "+message);
              Calendar calendar = Calendar.getInstance();
              java.util.Date now = calendar.getTime();
              java.sql.Timestamp currentTimestamp = new java.sql.Timestamp(now.getTime());
              message = "bot says: "+message;
              Msg actualMsg = new Msg(currentTimestamp,message,"bot");
              messages.add(actualMsg);
              conversation.put(friendName,messages);
          }
      } catch (SmackException.NotConnectedException e) {
          e.printStackTrace();
      }
  
      System.out.println("You said "+"'"+message+"'"+" to "+myXMPPConnection.getRoster().getEntry(chat.getParticipant()).getName());
  
  }
  
  PacketListener myPacketListener = new PacketListener() {
      @Override
      public void processPacket(Packet p) {
          if (p instanceof Message) {
              Message msg = (Message) p;
          }
      }
  
  
  };
  
  public void displayMyFriends()
  {
      Roster roster = myXMPPConnection.getRoster();
      Collection entries = roster.getEntries();
      System.out.println("You currently have: "+entries.size()+" friends available to chat.");
  
      int counter = 0;
      Iterator i = entries.iterator();
  
      while(i.hasNext())
      {
          RosterEntry r = (RosterEntry) i.next();
          Presence.Type entryPresence;
          entryPresence = roster.getPresence(r.getUser()).getType();
          System.out.println((counter+1)+" . "+r.getName() +" is "+entryPresence);
          //System.out.println("id:..."+r.getUser());
          myFriends.add(r.getUser());
          counter++;
      }
  }
  
  public void disconnectMe()
  {
      try {
          System.out.println("Disconnection in progress...");
          myXMPPConnection.disconnect();
          System.out.println("You have been successfully disconnected.");
      } catch (SmackException.NotConnectedException e) {
          e.printStackTrace();
      }
  }
  
  
  @Override
  public void processMessage(Chat chat, Message message)
  {
      if((message.getType() == Message.Type.chat) &amp;&amp; (message.getBody()!= null)) {
  
  
          System.out.println(myXMPPConnection.getRoster().getEntry(chat.getParticipant()).getName() + " says: " + message.getBody());
  
          String myMsg = myXMPPConnection.getRoster().getEntry(chat.getParticipant()).getName() + " says: " + message.getBody();
  
          Calendar calendar = Calendar.getInstance();
          java.util.Date now = calendar.getTime();
          java.sql.Timestamp currentTimestamp = new java.sql.Timestamp(now.getTime());
  
          Msg actualMsg = new Msg(currentTimestamp,myMsg,"customer");
  
          conversation.get(myXMPPConnection.getRoster().getEntry(chat.getParticipant()).getName()).
                  add(actualMsg);
  
      }
  
  }
  
  public void receiveMessage(){
  
      myXMPPConnection.addPacketListener(myPacketListener, null);
  }
  
  public void retrieveUnservicedMessagesForSpecificPerson(String clientName)
  {
      ArrayList&lt;Msg&gt; myMessages = conversation.get(clientName);
      Calendar calendar = Calendar.getInstance();
      java.util.Date now = calendar.getTime();
      java.sql.Timestamp currentTimestamp = new java.sql.Timestamp(now.getTime());
  
      System.out.println("Unserviced messages from: "+ clientName);
      if(!myMessages.isEmpty())
      {
  
          int counter = myMessages.size()-1;
          System.out.println("Size of array list: "+counter);
          boolean found = false;
          java.sql.Timestamp lastBotTimestamp = null;
  
  
          while (counter != 0 &amp;&amp; found == false){
  
              if(myMessages.get(counter).getOwner()=="bot")
              {
                  lastBotTimestamp = myMessages.get(counter).getTimestamp();
                  found = true;
              }
              else
              {
                  counter = counter-1;
              }
  
          }
  
          for(Msg msg:myMessages)
          {
              if(msg.getTimestamp().before(currentTimestamp) &amp;&amp;
                      msg.getTimestamp().after(lastBotTimestamp)){
  
                      System.out.println("---------------------------");
                      System.out.println("-"+msg.getActualMessage());
                      System.out.println("-"+msg.getTimestamp());
                      System.out.println("---------------------------");
              }
  
          }
      }
  }
  
  
  public void returnConversation(String name) {
  
      System.out.println("Name of participant entered: "+ name);
      System.out.println("Conversation history is: ");
      ArrayList&lt;Msg&gt; m = conversation.get(name);
  
      for(Msg msg:m){
  
          System.out.println(msg.getActualMessage());
          System.out.println("on: "+msg.getTimestamp());
  
      }
  
  }
  
  public void returnAllUnservicedMessagesHistory()
  {
  
      for(String name: conversation.keySet())
      {
          System.out.println("History of unserviced messages for: "+ name);
          retrieveUnservicedMessagesForSpecificPerson(name);
      }
  
  }
  
  
  public void getOfflineMessagesCount(){
  
      try {
          System.out.println("Number of offline messages: "+ offlineMessages.getMessageCount());
      } catch (XMPPException e) {
          e.printStackTrace();
      }
  
  }
  </code></pre>
  
  <p>}</p>
  
  <p>My Main Class Implementation:</p>
  
  <p>public class MainGoogleChatApp {</p>
  
  <pre><code>public static void main(String[] args)
  {
  
      //Step 1: need to make a chat request with your username and password.
  
      Scanner input  = new Scanner(System.in);
  
      System.out.println("Please enter your username to start: ");
      String myUsername = input.next();
  
      System.out.println("Please enter your password to continue: ");
      String myPassword = input.next();
  
      ChatRequest myChatRequest = new ChatRequest();
  
      myChatRequest.setUsername(myUsername);
      myChatRequest.setPassword(myPassword);
  
      //Step 2: Need to initiate a connection to talk.google.com
  
      StartChatImpl convo = new StartChatImpl();
  
      try {
          convo.engageChat(myChatRequest);
      } catch (XMPPException e) {
          e.printStackTrace();
      }
  
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
      String myMessage;
  
      System.out.println("Friend list.");
  
      convo.displayMyFriends();
  
  
  
      convo.receiveMessage();
  
      try {
          while(true)
          {
              System.out.println("Input Which friend you want to chat with '0 to sign out' : ");
              int num = input.nextInt() -1;
              if (num == -1){
                  break;
              }
              String chatWith = StartChatImpl.myFriends.get(num);
  
              System.out.print("Type your message: ");
  
              myMessage=br.readLine();
  
  
              try {
                  convo.send(myMessage,chatWith);
  
  
  
              } catch (XMPPException e) {
                  e.printStackTrace();
              }
              convo.displayMyFriends();
  
          }
      } catch (IOException e) {
          e.printStackTrace();
      }
  
      System.out.println("Enter participant name to get specific chat...");
      String yourName = null;
      try {
          yourName = br.readLine();
      } catch (IOException e) {
          e.printStackTrace();
      }
      System.out.println("/./././././././././././././..//.");
      if(yourName!=null){
          System.out.println("Your name is not null...ok");
          convo.returnConversation(yourName);
      }
  
      System.out.println("Enter another participant's name to get specific chat...");
      String yourName1 = null;
      try {
          yourName1 = br.readLine();
      } catch (IOException e) {
          e.printStackTrace();
      }
      System.out.println("/./././././././././././././..//.");
      if(yourName1!=null){
          System.out.println("Your name is not null...ok");
          convo.returnConversation(yourName1);
      }
  
      System.out.println("Select a client name for whom you want to view unserviced messages: ");
      String yourClientName = null;
      try {
          yourClientName = br.readLine();
      } catch (IOException e) {
          e.printStackTrace();
      }
      if(yourClientName!=null){
          System.out.println("...........................................");
          convo.retrieveUnservicedMessagesForSpecificPerson(yourClientName);
      }
  
      System.out.println("...........................................");
  
      convo.returnAllUnservicedMessagesHistory();
  
  
  
      System.out.println("You have chosen to disconnect yourself from talk.google.com");
      convo.disconnectMe();
      System.exit(0);
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Attempt to retrieve offline messages headers:</p>
  
  <p>public class TestOfflineService {</p>
  
  <pre><code>XMPPConnection xmppConnection = null;
  //OfflineMessageManager offlineMessageManager = null;
  
  public void makeConnection()
  {
      ConnectionConfiguration config = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
      //config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
      config.setSendPresence(true);
      xmppConnection = new XMPPTCPConnection(config);
  
  
      try{
  
          System.out.println("Connecting to talk.google.com");
          xmppConnection.connect();
  
          System.out.println("Logging you in...");
          xmppConnection.login("*******.*@***.com", "*****");
  
          System.out.println("You have been successfully connected.");
  
      } catch (SmackException e) {
          e.printStackTrace();
      } catch (IOException e) {
          e.printStackTrace();
      } catch (XMPPException e) {
          e.printStackTrace();
      }
  
  }
  
  public void makeMeUnavailable()
  {
      try {
          xmppConnection.sendPacket(new Presence(Presence.Type.unavailable));
      } catch (SmackException.NotConnectedException e) {
          e.printStackTrace();
      }
  }
  
  public void getOfflineMessages()
  {
      OfflineMessageManager offlineMessageManager1 = new OfflineMessageManager(xmppConnection);
      try {
          Iterator&lt;OfflineMessageHeader&gt; headers = offlineMessageManager1.getHeaders();
  
          if(headers.hasNext())
          {
              System.out.println("Messages found");
          }
      } catch (XMPPException e) {
          e.printStackTrace();
      }
  
  }
  
  public static void main(String[] args)
  {
      TestOfflineService test = new TestOfflineService();
      test.makeConnection();
      test.makeMeUnavailable();
      System.out.println("Enter messages");
      try {
          Thread.sleep(1000);
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
      System.out.println("Getting offline messages.....");
      test.getOfflineMessages();
  
  }
  </code></pre>
  
  <p>}</p>