Jabber-бот в роли дворецкого

Закончил в режиме фриланса один проект, связанный с написанием автоматизированного Jabber-чата. Решил использовать приобретенный опыт в личных целях. Написал бота, который выполняет на моем шлюзе (где запущен среди прочего Openfire) некоторые команды: включить/выключить музыку, вывести output несложных bash-команд. При написании использовано API Smack и Apache Felix. Исходники под катом. Пояснения выложу попозже, т.к требуется экскурс в технологию OSGI, а это не пятиминутное дело.



package ru.yababay.chat.server;

import java.io.File;
import java.io.FileInputStream;

import java.util.Enumeration;
import java.util.Properties;
import java.util.HashMap;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;

import net.sf.lab3f.osgi.Groovyable;

public class Main implements Runnable, ChatManagerListener, MessageListener {

 private XMPPConnection connection;
 private Thread checkThread;
 private Thread pingThread = new Thread(new Runnable(){
   public void run(){
    while(true){	   
     try{
      Thread.sleep(600000);
      checkConnection();
      Chat cht = connection.getChatManager().getThreadChat(chatId);
      if(cht != null)cht.sendMessage(props.getProperty("pingMessage"));
     }
     catch(InterruptedException ex){}
     catch(XMPPException ex){}
    } 
   }	   
  });
 private Properties props = new Properties();
 private Chat chat;
 private String chatId;
 private Groovyable groovy;
 private Object groovyObj;
 private HashMap <String, java.lang.reflect.Method> methods = new HashMap <String, java.lang.reflect.Method> ();
 private boolean haveGreeting;

 public void run(){
  while(true){
   try{checkConnection();Thread.sleep(120000);}
   catch(InterruptedException ex){}
   catch(XMPPException ex){}
  }	  
 } 	 

 public void processMessage(Chat cht, Message msg){	 
  String cmd = msg.getBody().trim();
  String t = cmd.indexOf(':') > 0 ?  cmd.substring(0, cmd.indexOf(':')) : cmd;
  try{
   if(props.getProperty("cmd." + t) == null){
    if(haveGreeting)cht.sendMessage(props.getProperty("notRecognized"));	   
    else haveGreeting = true; 
    return;
   }	  
   chat.sendMessage(props.getProperty("botReplay1") + '\n' + methods.get(t).invoke(groovyObj, cmd) + "====================\n" + props.getProperty("botReplay2"));
  }   
  catch(XMPPException ex){System.out.println(ex);}
  catch(IllegalAccessException ex){System.out.println(ex);}
  catch(java.lang.reflect.InvocationTargetException ex){System.out.println(ex);}
 }	 

 public void chatCreated(Chat cht, boolean local){
  String s = cht.getParticipant();
  if(s.indexOf('/') > 0)s = s.substring(0, s.lastIndexOf('/'));
  if(!s.equals(props.getProperty("adminJid")))return;
  if(chatId == null){
   chatId = cht.getThreadID();
   chat   = connection.getChatManager().getThreadChat(chatId);
   try{chat.sendMessage(props.getProperty("botGreeting"));}catch(XMPPException ex){System.err.println(ex);}
   pingThread.start();
  } 
  cht.addMessageListener(this);
 }	 

 public final void start() throws Exception {
  props.load(new FileInputStream("conf/jabberbot.properties"));	 
  ConnectionConfiguration connConfig = new ConnectionConfiguration(props.getProperty("host"), new Integer(props.getProperty("port", "5222")));
  connConfig.setSelfSignedCertificateEnabled(true);
  connection   = new XMPPConnection(connConfig);
  checkThread  = new Thread(this);
  checkThread.start();
  groovyObj = groovy.eval(new File(props.getProperty("path2Script")));
  Class grClass = groovyObj.getClass();
  Enumeration en = props.propertyNames();
  while(en.hasMoreElements()){
   String s = ((String)en.nextElement()).trim();
   if(!s.startsWith("cmd."))continue;
   s = s.substring(s.indexOf('.') + 1); //, grClass.getMethod(s, String.class));
   methods.put(s, grClass.getMethod(s, String.class));
  }	  
  System.out.println("[INFO] Jabber bot started.");
 }

 private synchronized void checkConnection() throws XMPPException {
  if(connection.isConnected())return;
  connection.connect();
  if(!connection.isAuthenticated())connection.login(props.getProperty("botLogin"), props.getProperty("botPasswd"));
  ChatManager chatMan = connection.getChatManager();
  if(chatMan.getChatListeners().size() == 0)chatMan.addChatListener(this);
 }	 

 public final void stop() throws Exception {
  pingThread.interrupt();	 
  checkThread.interrupt();	 
  if(connection.isConnected())connection.disconnect();	 
 }
}
  • +10
  • 05 сентября 2010, 15:32
  • yababay

Комментарии (3)

RSS свернуть / развернуть
+
0
Фундаментально!
Монументально !
avatar

Markony

  • 05 сентября 2010, 17:00
+
0
Забавно )))
только как этот код прикрутить и куда?
avatar

Sergei_T

  • 05 сентября 2010, 17:02
+
0
Об этом наш следующий репортаж
avatar

yababay

  • 05 сентября 2010, 22:02

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.