Бывает необходимо добавить на сайт отображение текущего сетевого статуса контактов различных сервисов обмена сообщениями. Чаще всего это можно встретить на сайтах-визитках или для отображения доступности оператора онлайн-поддержки. Можно использовать для этого официальные сервисы или неофициальные, которые, как правило, предоставляют больше возможностей по оформлению, разные темы с картинками. Но что делать, если у нас оригинальный сайт и дефолтные изображения не вписываются в его стиль? Придётся либо изобретать свой велосипед, который вряд ли будет лучше существующих, либо позаимствовать идеи из уже готовых решений и приспособить под наши нужды. Мы пойдём вторым путём.
Для начала определим наши задачи:
— по возможности использовать официальные сервисы определения статуса
— в случае их отсутствия можно прибегнуть к посторонним
— способ должен быть как можно проще, без излишков (всегда можно будет его потом расширить)
— чтобы прорисовка страницы не висла на время запроса, сделаем буфер
Рассмотрим 4 основных способа на примере ICQ, Jabber, Skype и MRA. Остальные можно сделать аналогично.
Проверка будет осуществляться при помощи php. Создадим файл «status.php» и добавим его выполнение в планировщик каждые 5 минут. Статус будет сохраняться в отдельный файл.
В моём случае для каждого протокола свой файл, например «icq.s». Т.к. у меня сохраняется не только текст статуса, но и картинка, то записывается часть html-кода в две строки. Чтобы потом на странице сайта не выдирать по абзацам, я решил просто вставлять нужный кусок в определённом месте страницы:
<? include('icq.s'); ?>
Можно будет записывать сколь угодно большие и сложные конструкции.
Статус ICQ
Будем использовать официальный сервис проверки статуса. В нём тоже есть свои минусы, работает странно. Например, статус «Away» он отдаёт только тогда, когда у контакта стоит статус «Invisible». В остальных случаях, кроме оффлайна, контакт всегда отображается «Online». Поэтому, если Вы поставите статус «Away» в клиенте, он всё равно будет показываться как «Online». Но это не повод отказываться, будем использовать официальный сервис, как и было заявлено в задачах.
Не забудьте в клиенте разрешить отображение статуса на сайтах. Есть много способов определения статуса, но используют они один и тот же адрес для проверки:
http://status.icq.com/online.gif?icq=ТУТ_ВАШ_UIN
В зависимости от текущего статуса ICQ адрес отдаваемой картинки будет принимать значения:
http://status.icq.com/0/online0.gif - Away
http://status.icq.com/0/online1.gif - Online и все остальные
http://status.icq.com/0/online2.gif - Offline
В зависимости от цифры в имени картинки и будет определяться статус. Мы будем получать заголовок «Location» из ответа сервера и захватывать оттуда эту цифру. А уже потом с помощью switch зададим, что будет отдаваться как статус. Конструкция такая:
try {
$a = @get_headers('http://status.icq.com/online.gif?icq=ТУТ_ВАШ_UIN');
foreach($a as $Header) { if (is_int(strpos($Header, 'Location'))) { $Status = substr($Header, -5, 1); } }
switch ($Status){
case '0': $icqstatus = '<img src="icq-away.png" alt=""/>'; break;
case '1': $icqstatus = '<img src="icq-online.png" alt=""/>'; break;
case '2': $icqstatus = '<img src="icq-offline.png" alt=""/>'; break;
default: $icqstatus = '<img src="icq-offline.png" alt=""/>'; break;
}
} catch (Exception $e){}
Переменная «icqstatus» хранит текущий статус. Если сервис не будет работать, то отдаётся статус «Offline». Теперь запишем это статус в файл-буфер:
$f=fopen('/home/mysite/icq.s','w');
fwrite($f,$icqstatus);
fclose($f);
Обратите внимание, что нужно указать полный путь к файлу на сервере.
Как я уже писал выше, для отображения статуса в нужном месте страницы вставляем:
<? include('icq.s'); ?>
UPD: изменения на сайте ICQ
Теперь вместо трёх вариантов остались только «онлайн» или «оффлайн». Изменим код следующим образом:
Посмотреть рабочий вариант
В зависимости от текущего статуса ICQ адрес отдаваемой картинки будет принимать значения:
Все остальные значения будут означать Offline. Так и запишем:
Остальное как обычно.
http://status.icq.com/0/online1.gif - Online
Все остальные значения будут означать Offline. Так и запишем:
try {
$a = @get_headers('http://status.icq.com/online.gif?icq=ТУТ_ВАШ_UIN');
foreach($a as $Header) { if (is_int(strpos($Header, 'Location'))) { $Status = substr($Header, -5, 1); } }
switch ($Status){
case '1': $icqstatus = '<img src="icq-online.png" alt=""/>'; break;
default: $icqstatus = '<img src="icq-offline.png" alt=""/>'; break;
}
} catch (Exception $e){}
Остальное как обычно.
Статус Skype
Здесь есть официальный сервис проверки статуса Skype. В отличие от ICQ у нас есть шикарная возможность получить ответ в виде текста статуса. Используем для этого такую ссылку:
http://mystatus.skype.com/ВАШ_НИК.txt
Не забудьте в клиенте разрешить отображение статуса на сайтах. В зависимости от текущего статуса Skype мы получим следующие значения:
Online
Away
Do Not Disturb
Offline
Нам всего-то и остаётся как получить содержимое текстового файла без каких-либо дополнительных телодвижений, он уже кошерный и ничего лишнего не содержит.
try {
$a = @file_get_contents("http://mystatus.skype.com/ВАШ_НИК.txt");
switch($a) {
case 'Online': $skypestatus = '<img src="skype-online.png" alt=""/>'; break;
case 'Away': case 'Do Not Disturb': $skypestatus = '<img src="skype-away.png" alt=""/>'; break;
case 'Offline': $skypestatus = '<img src="skype-offline.png" alt=""/>'; break;
default: $skypestatus = '<img src="skype-offline.png" alt=""/>'; break;
}
} catch (Exception $e){}
И по традиции запишем полученный статус из переменной «skypestatus» в файл:
$f=fopen('/home/mysite/skype.s','w');
fwrite($f,$skypestatus);
fclose($f);
В нужном месте сайта выведем:
<? include('skype.s'); ?>
Статус Jabber
Это как раз тот случай, когда без использования сторонних сервисов нам не обойтись. Штатных способов определения сетевого статуса Jabber нет. Зато есть добрые люди. Правда и способ посложнее.
Сначала я использовал этот сервис http://web-apps.ru/jabber-presence/ и долгое время он работал отлично. Но недавно ушёл в офлайн на неделю и пришлось искать альтернативы, одной из которых был http://presence.jabberfr.org/. Его и будем использовать.
Идём на страницу французского сервиса, пишем свой JID и внизу выбираем «Your status (text)». Ещё чуть ниже появится сгенерированный адрес, по которому и будет определяться статус.
http://presence.jabberfr.org/ТУТ_ДЛИННЫЙ_ХЭШ_НАШЕГО_JID/text-en.txt
Теперь нам нужно добавить в ростер сервис presence.jabberfr.org. Он появится в списке контактов и будет иметь такой же статус, как у Вас. Чтобы включить отображение статуса по сгенерированной выше ссылке, отправим боту сообщение с текстом «visible» без кавычек.
В зависимости от текущего статуса Jabber мы имеем такие значения:
Available
Away
Not available
Do not disturb
Free for chat
Offline
При статусе «Invisible» будет показываться последний используемый статус перед скрытием.
Реализуем показ полученного статуса у нас на сайте. Также, как и в случае со Skype, получаем просто текстовый файл. В нём кроме статуса больше ничего не содержится.
try {
$a = @file_get_contents('http://presence.jabberfr.org/ТУТ_ДЛИННЫЙ_ХЭШ_НАШЕГО_JID/text-en.txt');
switch ($a){
case 'Available': case 'Free for chat': $jabberstatus = '<img src="jabber-online.png" alt=""/>'; break;
case 'Away': case 'Not available': case 'Do not disturb': $jabberstatus = '<img src="jabber-away.png" alt=""/>'; break;
case 'Offline': $jabberstatus = '<img src="jabber-offline.png" alt=""/>'; break;
default: $jabberstatus = '<img src="jabber-offline.png" alt=""/>'; break;
}
} catch (Exception $e){}
В переменной «jabberstatus» содержится текущий статус. Запишем его в файл «jabber.s»:
$f=fopen('/home/mysite/jabber.s','w');
fwrite($f,$jabberstatus);
fclose($f);
В нужном месте сайта выведем статус:
<? include('jabber.s'); ?>
UPD: альтернативный вариант
Т.к. теперь французский сервис упал, решил, что лучше написать альтернативу, т.е. http://web-apps.ru/jabber-presence/. Наш отечественный товарищ. Какой-то один из них будет работать.
Посмотреть рабочий вариант
Идём на страницу http://web-apps.ru/jabber-presence/ и читаем описание. Для ленивых напишу всё по шагам.
Добавляем себе в ростер web-apps-presence@jabber.ru. После добавления придёт сообщения с краткой справочкой. Нам необходимо будет запомнить содержимое пунктов «html-строка»: первый по адресу jabber, второй по его md5-хэшу. В примере удет использоваться как раз второй вариант.
Теперь пишем в личку боту сообщение, содержащие только цифру 1. Получим ответ, что отображение статусов включено.
Далее зададим вид отображаемого статуса, нам нужен только текст. Для этого отправим в личку боту такое сообщение:
В зависимости от текущего статуса Jabber мы имеем такие значения:
При статусе «Invisible» будет показываться последний используемый статус перед скрытием. Все остальные случаи приравниваем к оффлайну.
Реализуем показ полученного статуса у нас на сайте.
Остальное как обычно.
Добавляем себе в ростер web-apps-presence@jabber.ru. После добавления придёт сообщения с краткой справочкой. Нам необходимо будет запомнить содержимое пунктов «html-строка»: первый по адресу jabber, второй по его md5-хэшу. В примере удет использоваться как раз второй вариант.
http://web-apps.ru/jabber-presence/html/xid/ТУТ_ДЛИННЫЙ_ХЭШ_НАШЕГО_JID
Теперь пишем в личку боту сообщение, содержащие только цифру 1. Получим ответ, что отображение статусов включено.
Далее зададим вид отображаемого статуса, нам нужен только текст. Для этого отправим в личку боту такое сообщение:
set html=%{status}
В зависимости от текущего статуса Jabber мы имеем такие значения:
available
away
xa
dnd
chat
При статусе «Invisible» будет показываться последний используемый статус перед скрытием. Все остальные случаи приравниваем к оффлайну.
Реализуем показ полученного статуса у нас на сайте.
try {
$a = @file_get_contents('http://web-apps.ru/jabber-presence/html/xid/ТУТ_ДЛИННЫЙ_ХЭШ_НАШЕГО_JID');
switch ($a){
case 'available': case 'chat': $jabberstatus = '<img src="jabber-online.png" alt=""/>'; break;
case 'away': case 'xa': case 'dnd': $jabberstatus = '<img src="jabber-away.png" alt=""/>'; break;
default: $jabberstatus = '<img src="jabber-offline.png" alt=""/>'; break;
}
} catch (Exception $e){}
Остальное как обычно.
Статус MRA
Это Mail.ru Агент. Опять будем использовать официальный сервис проверки статуса Mail.ru Агента. Как и ICQ, нам предоставляют возможность отображать лишь картинку, без текста статуса:
http://status.mail.ru/?АДРЕС_ПОЧТЫ
Т.к. все изображения имеют один адрес и все одного размера, придётся придумать что-то другое. Можно узнать их вес, но это не лучший способ. Сделаем ход конём, то бишь просто будем определять md5-хэш изображения. Получаем также три разновидности статусов:
0318014f28082ac7f2806171029266ef - Online, Free for chat, Do not disturb
89d1bfcdbf238e7faa6aeb278c27b676 - Away
a46f044e175e9b1b28c8d9a9f66f4495 - Offline, Invisible
После определения хэша уже знакомой конструкцией задаём статус:
try {
$a = @md5(file_get_contents("http://status.mail.ru/?АДРЕС_ПОЧТЫ"));
switch($a) {
case '0318014f28082ac7f2806171029266ef': $mrastatus = '<img src="mra-online.png" alt=""/>'; break;
case '89d1bfcdbf238e7faa6aeb278c27b676': $mrastatus = '<img src="mra-away.png" alt=""/>'; break;
case 'a46f044e175e9b1b28c8d9a9f66f4495': $mrastatus = '<img src="mra-offline.png" alt=""/>'; break;
default: $mrastatus = '<img src="mra-offline.png" alt=""/>'; break;
}
} catch (Exception $e){}
Записываем полученный статус MRA в файл:
$f=fopen('/home/mysite/mra.s','w');
fwrite($f,$mrastatus);
fclose($f);
И в нужном месте выведем статус:
<? include('mra.s'); ?>
Проверить, как это работает, можно здесь http://damaks.me/. Работы много, постараюсь оставаться в сети подольше, чтобы можно было воочию наблюдать сие действие.
Другие протоколы
Аналогично мы можем сделать проверку текущего сетевого статуса других протоколов. Если есть официальный сервис, то использовать его, если нет, то пользоваться альтернативными. Здесь рассмотрены 4 разных способа, как минимум один из которых подойдёт для других протоколов.
Статус Вконтакте
Получаем статус (можно использовать как числовой id, так и псевдоним):
Записываем его в файл:
И где нужно выведем:
try {
$ch = curl_init('https://api.vkontakte.ru/method/getProfiles?uids=ТУТ_ВАШ_ID&fields=online');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
$a = substr($result, -4, 1);
switch ($a){
case '1': $vkstatus = '<img src="vk-online.png" alt=""/>'; break;
case '0': $vkstatus = '<img src="vk-offline.png" alt=""/>'; break;
default: $vkstatus = '<img src="vk-offline.png" alt=""/>'; break;
}
} catch (Exception $e){}
Записываем его в файл:
$f=fopen('/home/mysite/vk.s','w');
fwrite($f,$vkstatus);
fclose($f);
И где нужно выведем:
<? include('vk.s'); ?>
P.S.
Разные способы отображения статусов я находил на разных ресурсах, вспомнить уже точно не смогу. Тем более встречаются одни и те же описания много раз. Если известен первоисточник, добавлю в пост. Если есть замечания/предложения, с удовольствием выслушаю.