从 Java 中的 Google Talk 中检索离线消息和聊天历史记录

Posted

技术标签:

【中文标题】从 Java 中的 Google Talk 中检索离线消息和聊天历史记录【英文标题】:Retrieve Offline Messages and Chat History From Google Talk in Java 【发布时间】:2014-08-29 07:00:54 【问题描述】:

我必须从 Google Talk 中检索与我有过对话的特定客户(朋友/XMPP 客户)的离线消息。

另外,我想找回聊天记录。

现在,我正在使用 Hash Map 来跟踪对话并且无法获得离线消息。

我已与“talk.google.com”建立了 XMPP 连接。我目前能够通过我的控制台向客户端发送消息。我已经实现了消息侦听器接口,因此可以在我的控制台本身中接收消息。

我有另一个实现(使用 OfflineMessageManager),我尝试提取离线消息头作为开始,不幸的是,它失败并出现 Null 异常。

我使用过 smack-tcp 版本 4.0.3 和 smackx 3.1.0。

请在下面找到我到目前为止尝试过的内容...

工作实施:

公共类 StartChatImpl 实现 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();
    


我的主类实现:

公共类 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);

尝试检索离线消息标头:

公共类 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();


【问题讨论】:

【参考方案1】:

OfflineMessageManager 尝试使用XEP-0013 检索离线消息。这个 XEP 不是由 GTalk 实现的。另请注意,启动环聊意味着您将永远不会再收到离线消息,因为环聊实例永远不会离线。

GTalk 也没有用于检索聊天记录的 XMPP API,例如 XEP-0136 或 XEP-0313。

【讨论】:

以上是关于从 Java 中的 Google Talk 中检索离线消息和聊天历史记录的主要内容,如果未能解决你的问题,请参考以下文章

从 Google App Engine 设置 Google Talk 状态(带身份验证)

从 Android 以编程方式更改 Google Talk 在线状态

如何使用 smack API 从 Google Talk 获取我的个人资料图片?

Python 中的 Google Talk/XMPP 音频支持

使用 smack 连接到 Google Talk

构建 Google Talk(又名 WebRTC)PeerConnection 示例