Reputation: 61
I have to retrieve offline messages from Google Talk for a particular client (friend/ XMPP Client) with whom I have had a conversationn with.
Additionally, I want to retrieve the chat history.
Right now, I am using a Hash Map to keep track of the conversation and have no means of having the offline messages.
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.
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.
I have used smack-tcp version 4.0.3 and smackx 3.1.0.
Please find below what I have tried till now...
Working Implementation:
public class StartChatImpl implements startChat, MessageListener {
static XMPPConnection myXMPPConnection;
static ArrayList<String> myFriends = new ArrayList<String>();
ArrayList<Msg> messages;
HashMap<String,ArrayList> conversation = new HashMap<String, ArrayList>();
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<Msg>();
//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) && (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<Msg> 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 && 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) &&
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<Msg> 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();
}
}
}
My Main Class Implementation:
public class MainGoogleChatApp {
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);
}
}
Attempt to retrieve offline messages headers:
public class TestOfflineService {
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<OfflineMessageHeader> 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();
}
}
Upvotes: 2
Views: 1425
Reputation: 3316
OfflineMessageManager
tries to use XEP-0013 to retrieve offline messages. This XEP isn't implemented by GTalk. Also note that ever starting Hangouts means you'll never get offline messages anymore, as the Hangouts instance is never offline.
GTalk also does not have an XMPP API to retrieve chat history, like XEP-0136 or XEP-0313.
Upvotes: 2