すべての人に良い一日を!
ジャバー用のボットを作成する主題は非常に広範囲です。 しかし、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として指定する必要はありません。ニックネームだけで十分です。 ログインをまったく書かないか、他に書かないと、すべてうまくいきます