Smack APIを使用したJava XMPPボット

画像



すべての人に良い一日を!

ジャバー用のボットを作成する主題は非常に広範囲です。 しかし、habrでは、OpenFireサーバー用にボットが記述された記事が1つだけ見つかりました。 そして、最初のコメントは、サーバーに結び付けられていないユニバーサルボットの作成について読むのがいいと言っています。 そこで、この記事を書くことにしました。 また、Googleトークのボットと、このボットに関連する1つのニュアンスについても説明します。





ジャバー用ボット


上記の記事のように、OpenFireサーバーを持っているので、独自のライブラリーを使用することにしました(これは、ボットが私のサーバーでのみ動作するという意味ではありません)。 ボットの実装には多くの例がありますが、次のコードが非常に新しいものになることはほとんどありません。



public class Main { public static void main(String[] args) { try { String botNick = "nickname"; String botPassword = "password"; String botDomain = "jabber.org"; String botServer = "jabber.org"; int botPort = 5222; JabberBot bot = new JabberBot(botNick, botPassword, botDomain, botServer, botPort); Thread botThread = new Thread(bot); botThread.start(); } catch(Exception e) { System.out.printLn(e.getMessage()); } } } /** * ,      . *   Runnable,        *   ,   .<hr> * *   smack.jar  smackx.jar:<br> * org.jivesoftware.smack<hr> * * @author esin * */ public class JabberBot implements Runnable { private String nick; private String password; private String domain; private String server; private int port; private ConnectionConfiguration connConfig; private XMPPConnection connection; /** *     ,     - * @param nick -  * @param password -  * @param domain -  * @param server -  * @param port -  */ public JabberBot (String nick, String password, String domain, String server, int port) { this.nick = nick; this.password = password; this.domain = domain; this.server = server; this.port = port; } @Override public void run() { connConfig = new ConnectionConfiguration(server, port, domain); connection = new XMPPConnection(connConfig); try { int priority = 10; SASLAuthentication.supportSASLMechanism("PLAIN", 0); connection.connect(); connection.login(nick, password); Presence presence = new Presence(Presence.Type.available); presence.setStatus(" "); connection.sendPacket(presence); presence.setPriority(priority); PacketFilter filter = new AndFilter(new PacketTypeFilter(Message.class)); PacketListener myListener = new PacketListener() { public void processPacket(Packet packet) { if (packet instanceof Message) { Message message = (Message) packet; //    processMessage(message); } } }; connection.addPacketListener(myListener, filter); //      ,     while(connection.isConnected()) { Thread.sleep(60000); } } catch (Exception e) { System.out.printLn(e.getMessage()); } } /** *   <hr> * @param message   */ private void processMessage(Message message) { String messageBody = message.getBody(); String JID = message.getFrom(); //  .     :) //     - sendMessage(JID, messageBody); } /** *   <hr> * @param to JID ,    <br> * @param message  */ private void sendMessage(String to, String message) { if(!message.equals("")) { ChatManager chatmanager = connection.getChatManager(); Chat newChat = chatmanager.createChat(to, null); try { newChat.sendMessage(message); } catch (XMPPException e) { System.out.printLn(e.getMessage()); } } } }
      
      







以上です。 なぜ別のスレッドでボットを選択したのですか? 流れが良くないことを理解しています。 しかし、ボットの初期化を実行した後、このスレッドはほとんど常にスリープ状態になります。 接続を確認するために、彼は1分間に1回だけウェイクアップします。 そして、それも不要ですが、削除することは不可能でした。 そうでない場合、ボットはすぐに起動およびシャットダウンします。 着信メッセージの処理と発信の送信はすべて、Smackライブラリによって作成されたフローで実行されます。



GoogleTalkのボット


このボットのコードは実質的に違いはありません。 わずかな違いがあります。



 public class Main { public static void main(String[] args) { try { String botNick = "nickname"; String botPassword = "password"; String botDomain = "gmail.com"; //        String botServer = "talk.google.com"; int botPort = 5222; GoogleTalkBot bot = new GoogleTalkBot(botNick, botPassword, botDomain, botServer, botPort); Thread botThread = new Thread(bot); botThread.start(); } catch(Exception e) { System.out.printLn(e.getMessage()); } } } /** * ,       . *   Runnable,        *   ,   .<hr> * *   smack.jar  smackx.jar:<br> * org.jivesoftware.smack<hr> * * @author esin * */ public class GoogleTalkBot implements Runnable { private String nick; private String password; private String domain; private String server; private int port; private ConnectionConfiguration connConfig; private XMPPConnection connection; /** *     ,      * @param nick -  * @param password -  * @param domain -  * @param server -  * @param port -  */ public GoogleTalkBot (String nick, String password, String domain, String server, int port) { this.nick = nick; this.password = password; this.domain = domain; this.server = server; this.port = port; } @Override public void run() { connConfig = new ConnectionConfiguration(server, port, domain); connection = new XMPPConnection(connConfig); try { int priority = 10; SASLAuthentication.supportSASLMechanism("PLAIN", 0); connection.connect(); connection.login(nick + "@" + domain, password); //         nickname@gmail.com Presence presence = new Presence(Presence.Type.available); presence.setStatus(" "); connection.sendPacket(presence); presence.setPriority(priority); PacketFilter filter = new AndFilter(new PacketTypeFilter(Message.class)); PacketListener myListener = new PacketListener() { public void processPacket(Packet packet) { if (packet instanceof Message) { Message message = (Message) packet; if(message.getType() == Type.chat) //    ,       { // Process message processMessage(message); } } } }; // Register the listener. connection.addPacketListener(myListener, filter); while(connection.isConnected()) { Thread.sleep(60000); } } catch (Exception e) { System.out.printLn(e.getMessage()); } } /** *   <hr> * @param message -   */ private void processMessage(Message message) { String messageBody = message.getBody(); String JID = message.getFrom(); sendMessage(JID, messageBody); } /** *   <hr> * @param to - JID ,    <br> * @param message -  */ private void sendMessage(String to, String message) { if(!message.equals("")) { ChatManager chatmanager = connection.getChatManager(); Chat newChat = chatmanager.createChat(to, null); try { newChat.sendMessage(message); } catch (XMPPException e) { System.out.printLn(e.getMessage()); } } } }
      
      







一般的に、すべてがほぼ同じです。

次に、現在のGoogleのボットに関連付けられているニュアンスについて説明します(エラにはそのようなニュアンスはありません)。 ボットをテストしたときに、ボットからエコー応答のテキストをフォームで送信しました

<送信者>:<送信者>

つまり テキストは、送信者の識別子(JID)を明確に示していました。 エラは完全に機能し、不具合はありませんでした。 ちょうど10件のメッセージが応答を送信しなくなった後、Googleは現在の状態になりました。 Googleのログインに関連していることを、多くの苦痛の末に発見しました。 さらに、nickname @ gmail.comとして指定する必要はありません。ニックネームだけで十分です。 ログインをまったく書かないか、他に書かないと、すべてうまくいきます



All Articles