Еще пара слов о переходе на Jabber или ICQ бот
26-02-2009Сам, как приверженец свободных технологий, я давненько завел себе jabber аккаунт, но он долго пустовал, т.к. никто из асечного контактлиста не поддавался на уговоры перейти на jabber. Тут, в свете недавних проблем с AOL и нескольких хабратопиков о XMPP клиентах и способах переманивания людей на них, меня постигла идея поставить на мой UIN бота. Пускай он умеет немного говорить и отсылать всех разговорчивых в нужном направлении. Поискав на тему предмета разговора в интернете, ничего стоящего не удалось найти. Зато наткнулся на страницу с набором классов на PHP, реализующих минимальную функциональность ICQ протокола.
Недолго думая, скачал и попробовал на деле. Работает!!!
и спустя 30 минут написал следующее:
icqbot.php
Copy Source | Copy HTML
- #!/usr/bin/php
- include('icq.php');
-
- //подключение zendloader
- require 'Zend/Loader.php';
- Zend_Loader::registerAutoload();
-
- //чтение конфига
- $config = new Zend_Config_Xml('config.xml',NULL,true);
-
- //подключение к БД
- $db = Zend_Db::factory($config->dbadapter,$config->db->toarray());
- $db->query('SET CHARACTER SET "'.$config->dbcharset.'"');
-
- //аськоклиент
- $icq = new WebIcqLite();
-
- log_write("ICQ Bot started");
-
- //коннектимся
- if (!$icq->connect($config->icq->login,$config->icq->password))
- {
- log_write($icq->error);
- exit();
- }
-
- log_write("Connected ok");
-
- while($icq->is_connected())
- {
- //читаем входящее сообщение
- $msg = $icq->read_message();
- if($msg)
- {
- //список админских комманд
- if ($msg['message']=="icqbotoff")
- {
- $icq->disconnect();
- log_write("Exit by admin's command.");
- exit();
- }
-
- log_write(" Message '".$msg['message']."' from ".$msg['from']);
-
- //режем все лишние символы
- $msg['message'] = str_replace(array('(',')','/',':','.',',','?','!','@','#','$','%','^','&','*','-','_','=','+','~','`',';','|','\\','\'','"'),'',$msg['message']);
-
- //ищем ответ
- $ans = $db->select()->from('messages')->where('q LIKE ?',trim($msg['message']))->where('LENGTH(a)>0')->order('RAND()')->query()->fetch();
-
- if ($ans)
- {
- //точное совпадение
- log_write(" Message '".$ans['a']."' sent to ".$msg['from']);
- }
- else
- {
- //нет совпадений. ищем полнотекстово.
- $db->insert('messages',array('q'=>$msg['message'],'a'=>'','from'=>$msg['from']));
- $query = "SELECT *, MATCH q AGAINST ('".$msg['message']."') as relev FROM messages WHERE LENGTH(a)>0 ORDER BY relev DESC LIMIT 1";
- $ans = $db->query($query)->fetch();
- if ($ans['relev']>0)
- {
- //нашли ответ
- log_write("Message (fulltext search) '".$ans['a']."' sent to ".$msg['from']);
- }
- else
- {
- //нет совпадений. выдаем сообщение по умолчанию.
- $ans = $db->select()->from('messages')->where('q LIKE ?','default')->query()->fetch();
- log_write("Message 'DEFAULT' sent to ".$msg['from']);
- }
- }
- $icq->send_message($msg['from'], $ans['a']);//собственно отправка сообщения получателю
- }
- //спим секунду
- flush();
- sleep(1);
- }
-
- //уходим
- log_write("Disconnected by unknown reason.");
- $icq->disconnect();
-
-
-
-
- //----------------------------------------------------------------------------------------//
- //вспомогательные функции//
-
- function log_write($str)
- {
- echo date('Y.m.d H.i.s',time())." ".$str."\n";
- }
config.xml
Copy Source | Copy HTML
- xml version="1.0" encoding="UTF-8"?>
- <configdata>
- <debug>0debug>
- <db>
- <host>localhosthost>
- <username>rootusername>
- <password>dbpasspassword>
- <dbname>icqbotdbname>db>
- <dbcharset>CP1251dbcharset>
- <dbadapter>Pdo_Mysqldbadapter>
- <icq>
- <login>UINlogin>
- <password>PASSWORDpassword>
- icq>
dump.sql
Copy Source | Copy HTML
- CREATE TABLE IF NOT EXISTS `messages` (
- `id` int(11) NOT NULL auto_increment,
- `q` text NOT NULL,
- `a` text NOT NULL,
- `from` varchar(16) NOT NULL,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `q` (`q`)
- ) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=43 ;
-
- INSERT INTO `messages` (`id`, `q`, `a`, `from`) VALUES
- (1, 'default', 'В данный момент вы говорите с роботом.
- Если вы хотите говорить с моим хозяином, вам необходимо зарегистрироваться на одном из Jabber серверов, т.к. в ICQ он больше не появится.
- Чтобы узнать подробности о Jabber-е, введите 1.
- Чтобы узнать Jabber адрес хозяина, напишите, сколько будет 2плюспять.
- Чтобы узнать почтовый адрес хозяина, введите цифры от 1 до 7 без пробелов.', ''),
- (2, '1234567', 'My@mail.ri', ''),
- (3, '7', 'My@jabber.ru', ''),
- (4, '1', 'Один из популярных Jabber серверов - jabber.ru
- http://www.jabber.ru/node/247 - это адрес страницы с инструкцией по регистрации подключению к нему.
- Чтобы узнать Jabber адрес хозяина, напишите, сколько будет дваплюс5.', ''),
- (5, 'привет', 'Привет )', ''),
- (6, 'как дела', 'Нормально )', '');
И не забыть положить в папочку с ботом ZendFramework
Не буду что-то комментировать, т.к. все достаточно тривиально.
Отмечу лишь то, что не ставил задачу сделать что-то серьезное, а только отсылалку по адресу (хотя уже набрал достаточно диалогов и бот с некоторыми знакомыми уже говорил цепочками сообщений в 5-10 штук без вываливания дефолтного сообщения). Бот не работает с сообщениями в формате RTF, но в классе реализована эта возможность(можно доделать). Можно было конечно прикрутить и беседу с отдельными UIN в отдельные потоки. Но это дело другое. Главное идея )
Сие творение уже 4 дня в полете. Людей по 1-2 человека в день в jabber контактлисте прибавляется.
Вот такое вот чудо получилось.
Warning: count(): Parameter must be an array or an object that implements Countable in /var/www/cramen.ru/library/Zend/Db/Table/Abstract.php on line 1259
Оставить комментарий