Дорогой дневник,
IRC отмирает, — кто-то уходит в социальные сети с концами, кто-то сменяет IRC на Jabber. На протяжении 6 лет моим хобби было написание mIRC бота (это как Emacs, только чат, но с таким же потенциалом для обвешивания его разным функционалом), но каналы опустели и теперь стало писать не для кого.
А писал я, позвольте похвастаться, многое — реализации HTTP, FTP, IRC серверов, Feed агрегатор, игры для IRC, и просто различные утилиты, которые выполняли рутинную задачу и делали жизнь легче. Все это — на чистом mIRC Scripting Language.
С потерей популярности IRC я не хочу отказываться от чатов и тоже перешел на Jabber, но в конференциях без своего бота, который предоставляет кучу полезных фич и развлекает посетителей — совсем не то. Поэтому я решил написать реализацию XMPP клиента, и для тех, кому это тоже может быть полезно — сделал шпаргалку, с описанием основных команд. По ней вы, используя любой любимый ЯП, в котором нет библиотек для XMPP, — да даже просто используя telnet, сможете сидеть в Jabber'е. Сравнивать я буду с IRC.
Подключение (USER)
При открытии сокета с IRC сервером клиент сразу «регистрируется», указывая ник, идент и имя. При наличии пароля на сервере — нужно указать и его, но команда PASS не обязательна.
PASS password
USER username * * :realname
NICK nickname
Ничего сложного нет и в XMPP, только здесь все описано XML-тегами, а суть остается одна и та же. Подключаться нужно к серверу, на котором у вас предварительно создан Jabber-аккаунт, указывая логин, пароль и ресурс (например название клиента или места, откуда вы подключаетесь). Так же, просто меняя имя ресурса, с одного аккаунта можно иметь несколько подключений одновременно.
<stream:stream xmlns:stream='http://etherx.jabber.org/streams' to='server' xmlns='jabber:client'>
<iq type='set'>
<query xmlns='jabber:iq:auth'>
<username>username</username>
<password>password</password>
<resource>resource</resource>
</query>
</iq>
server, username, password, resource — замените на свое. Некоторые серверы умеют в шифрование пароля, т.е. если вы подключаетесь не через SSL/TLS, то лучше оберните пароль в md5, но я например использую сервер talk.google.com:5223 и не беспокоюсь об этом.
После чего — добро пожаловать в мир Jabber, здесь нет обязательного PING как в IRC, и вы уже можете на свой аккаунт написать что-нибудь из любого клиента, и увидите это на трафике (если используете telnet или типа того).
Заходим на канал (JOIN)
В IRC это выглядило как просто JOIN #channel password, в XMPP чуть больше текста, но суть не меняется.
<presence to='channel@conference.server/nickname'>
<x xmlns='http://jabber.org/protocol/muc#user'>
<password />
</x>
</presence>
channel, server, nickname — заменить на свое, password опционален и может быть включен в тег <password>password</password>
И вот вы уже в конференции, испугались большого количества полученного XML, но это всего-лишь
- Список пользователей, аналог команды NAMES #channel в IRC (вы так же получаете их при заходе на канал).
- Последние несколько сообщений, которые написали перед вашим заходом. В IRC такого нет.
- Тема конференции, аналог TOPIC
- И все остальное — уже живой чат в реальном времени, все похоже на IRC.
Отправка сообщений (PRIVMSG)
Аналог PRIVMSG #channel/nickname : сообщение, только здесь оно определяется типом groupchat (в канал) или chat (пользователю), и в зависимости от того, кому направлено сообщение — нужно правильно указать адрес (to).
<message to='channel@conference.server' type='groupchat'>
<body>message</body>
</message>
Заодно добавлю, что смена темы (команда TOPIC в IRC) конференции делается просто заменой тега body на тег subject. А еще, не забудьте, чтобы содержимое вашего сообщение было валидным для XML, то есть замените все < на <, > на >, & на & и т.д.
И это пожалуй самый минимум, который необходим, — находиться в чате, парсить сообщения и отвечать на них. Далее, изучая протокол сами вы без труда сможете написать полноценный клиент для себя или любую другую простую его реализацию, моей же задачей было вернуть бота из IRC в Jabber.
Покинуть канал (PART)
Вы отправляете обновление присутствия самому себе на канале, обязательно указывая тип unavailable и таким образом покидаете канал. При необходимости можно указать сообщение выхода.
<presence to='channel@conference.server/nickname' type='unavailable'>
<status>message</status>
</presence>
Сменить ник (NICK)
<presence to='channel@conference.server/newnickname'/>
Пригласить пользователя (INVITE)
Так же как и в IRC, указав Jabber-аккаунт пользователя (jid), можно пригласить его в конференцию.
<message to='channel@conference.server'>
<x xmlns='http://jabber.org/protocol/muc#user'>
<invite to='jid'>
<reason>message</reason>
</invite>
</x>
</message>
Забанить пользователя (MODE #channel +b)
<iq id='id' to='channel@conference.server' type='set'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item affiliation='outcast' jid='jid'>
<reason>message</reason>
</item>
</query>
</iq>
Кикнуть пользователя (KICK)
<iq id='id' to='channel@conference.server' type='set'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item nick='nickname' role='none'>
<reason>message</reason>
</item>
</query>
</iq>
И пожалуй на первый раз этого достаточно, чтобы пользоваться Jabber'ом как обычным IRC'ом.
В завершение
Закрываем соединение
</stream>
У XMPP поистине большие возможности и возможности протокола постоянно расширяются, за чем следить вы можете в официальной документации к протоколу: xmpp.org/xmpp-protocols/xmpp-extensions/
В ней очень подробно расписываются описания команд с примерами, но нужно учитывать, что в большинстве клиентов и серверов может быть не 100% реализация протокола, и команды внезапно могут не работать. Чтож, пишите тогда свой сервер и клиент.
Мне же с переходом на Linux стало проблематично поддерживать mIRC бота и я переписываю его на чистом Bash, который будет одинакого работать в IRC и XMPP. Почему Bash? — Он есть везде, у него низкий порог вхождения, много вкусных фич, хотя и недостатки тоже имеются. Мне он нравится как и mIRC Scripting Language.
Параллельно переписываю функционал из mIRC и на данный момент уже реализовал удобную работу с сокетами, и в качестве примера приведу скрипт уже рабочего «бота» для IRC
sockname=$RANDOM
sockopen $sockname "irc.ixx.ru" 9996
if [ $? = 0 ]; then
sockwrite $sockname "NICK Voglea"
sockwrite $sockname "USER robot * * :The Goddess of Darkness"
else
exit 1
fi
while true; do
sockread $sockname i
i=${i/%[$'r'$'n']/}
case "${i%% *}" in
"PING")
sockwrite $sockname "PONG ${i#*:}"
;;
*)
;;
esac
echo $i
done
Команды sockopen, sockread, sockwrite, sockclose — полные аналоги mIRC, их я написал всего за вечер, с использованием /dev/tcp bash для обычных сокетов и openssl для SSL подключений. И затем, переписав большинство необходимого функционала mIRC на Bash, я возьмусь писать XMPP реализацию бота.
Но расскажу обо всем подробнее и поделюсь сорцами уже в другой статье.
Удачи с написанием XMPP бота, если вам таковой необходим.
Автор: Spoofing