Отображение статусов ICQ, Jabber, Skype и MRA на сайте в произвольном виде



Бывает необходимо добавить на сайт отображение текущего сетевого статуса контактов различных сервисов обмена сообщениями. Чаще всего это можно встретить на сайтах-визитках или для отображения доступности оператора онлайн-поддержки. Можно использовать для этого официальные сервисы или неофициальные, которые, как правило, предоставляют больше возможностей по оформлению, разные темы с картинками. Но что делать, если у нас оригинальный сайт и дефолтные изображения не вписываются в его стиль? Придётся либо изобретать свой велосипед, который вряд ли будет лучше существующих, либо позаимствовать идеи из уже готовых решений и приспособить под наши нужды. Мы пойдём вторым путём.

Для начала определим наши задачи:
— по возможности использовать официальные сервисы определения статуса
— в случае их отсутствия можно прибегнуть к посторонним
— способ должен быть как можно проще, без излишков (всегда можно будет его потом расширить)
— чтобы прорисовка страницы не висла на время запроса, сделаем буфер

Рассмотрим 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 адрес отдаваемой картинки будет принимать значения:

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-хэшу. В примере удет использоваться как раз второй вариант.

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.


Разные способы отображения статусов я находил на разных ресурсах, вспомнить уже точно не смогу. Тем более встречаются одни и те же описания много раз. Если известен первоисточник, добавлю в пост. Если есть замечания/предложения, с удовольствием выслушаю.
Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 34

    +2
    С ICQ когда эксперементировал, то как ни бился, статусы редко когда адекватно отображались. Стал парсить страницу профиля — icq и на это стало палки в колёса вставлять. Оставил эту идею.
      0
      Интересно, думаю кому нибудь пригодится. А статусы в соц. сетях? :)
        0
        Я знаю что есть API, просто можно было бы собрать все в единую библиотеку.
      • UFO just landed and posted this here
          –4
          Вот теперь пусть автор топика организует весь этот код в отдельный класс и выложит его в комментариях, мне кажется будет много полезней, нежели сам топик.
            +1
            И все же, такое-себе API — интересная идея. Только вряд ли мне понадобится что-то подобное:

            } catch (Exception $e){}
            
              +5
              Вот теперь пусть автор этого комментария организует весь этот код в отдельный класс и выложит его в комментариях, мне кажется будет много полезней, нежели сам комментарий.
                0
                Вот вам и «организует». Наминусовалина.
                0
                Спасибо, чуть изменил и добавил в пост.
                +3
                статус ICQ периодически ОЧЕНЬ сильно увеличивает время загрузки страницы…
                  0
                  В моём случае задержка была в основном из-за скайпа. По это причине и убрал все функции определения статусов из кода страницы.
                    0
                    По крону запускаете апдейт чтоль? Или типа того?
                      +2
                      Совершенно верно, прописал выполнение каждые пять минут.
                      0
                      Можно же ajax-ом статусы дергать со старницы
                      0
                      Тоже с этим сталкивался.

                      Поэтому стал кешировать статусы раз в 3 минуты (мне этого с головой хватало) по крону.
                        0
                        Загружайте асинхронно.
                      • UFO just landed and posted this here
                          0
                          Я так думаю, если человеку интересно узнать текущий статус, то он в любом случае обновит страницу. Это уже на подсознании.
                            –1
                            А если очень интересно, то он посмотрит статус в самом клиенте (icq, skype, ...) :)
                          –1
                          И чем же определение картинки по хешу принципиально лучше, чем по размеру? :D
                            0
                            Первоначально на просторах интернета я не нашёл простой функции определения размера файла на удалённом сервере, всегда попадались сложные + уверения, что так просто это невозможно. И как-то успокоился, оставив способ с хэшем. Но хорошо, что Вы задали вопрос, опять начал искать и нашёл способ через strlen.

                            try {
                                $a = strlen(file_get_contents("http://status.mail.ru/?АДРЕС_ПОЧТЫ"));
                                switch($a) {
                                    case '349': $mrastatus = 'Online'; break;
                                    case '568': $mrastatus = 'Away'; break;
                                    case '570': $mrastatus = 'Offline'; break;
                                    default: $mrastatus = 'N/A'; break;
                                }
                            } catch (Exception $e){}
                            
                            –1
                            Не понял фишку про 5 минут.

                            Зачем зависимость от крона, разве нельзя определять статус на момент загрузки страницы?
                            Вроде можно.
                              0
                              Можно конечно. Но если функции определения статусов будут перед тем местом, где их нужно вывести, то страница будет притормаживать, пока идут запросы. Если поместить функции вниз страницы, чтобы они не мешали загрузке, то тогда не получится вывести статусы, т.к. переменные будут запрашиваться до того, как они они определятся.

                              Я понимаю, что есть возможность реализовать этот вариант оптимальным способом, но вряд ли он будет проще и удобнее. Временной интервал погоды не делает, 3-5 минут вполне подходящие значения. Вряд ли Вы сразу после захода в сеть получите много сообщений. Обычно сначала читаешь оффлайновые лички. Как раз нескольких минут хватит. Вопрос предпочтений конечно.
                              +1
                              Скайп свои картинки статуса на выбор предоставляет(там ссылка на конфигуратор кнопок еще есть). У google talk пока еще работает даже чат встроить можно и тоже показывает статус. Да и думаю у многих других сервисов есть подобные странички.
                                +1
                                Про Google Talk я имел ввиду это, а «пока еще работает», к тому что скоро этот функционал уйдет в небытие. Вроде в 2013.
                                  0
                                  Да и думаю у многих других сервисов есть подобные странички.

                                  Всё верно. В тексте упоминается, что есть официальные сервисы. Статья призвана помочь сделать оригинальное представление статуса, не ограниченное несколькими заготовками.
                                • UFO just landed and posted this here
                                    0
                                    Решил не резать сильно. Может кто-то захочет при неработающем сервисе показывать «N/A».
                                    0
                                    Два способа получения статуса ICQ номера
                                      0
                                      >>> UPD: учёл изменения на сайте ICQ и добавил альтернативный вариант для Jabber.
                                        0
                                        На счет Skype и javascript — напрямую получить данные от //mystatus.skype.com/ сейчас нельзя (из-за Access-Control-Allow-Origin), но есть такой способ:

                                        // Sourse from: <https://gist.github.com/mattes/5253271>
                                        var getSkypeStatus = function(user, callback) {
                                              if(!user) throw new Error('missing user');
                                              var query = 'select * from skype.user.status where user="' + user + '";';
                                              $.getJSON('//query.yahooapis.com/v1/public/yql?q=' + encodeURI(query + '&format=json&env=store://datatables.org/alltableswithkeys&callback=?'), 
                                              function(data){
                                                if(data.query.count > 0) {
                                                  if(callback) return callback.call(null, data.query.results.result);
                                                } else {
                                                  if(callback) return callback.call(null, false); 
                                                }
                                              });
                                            };
                                        
                                        getSkypeStatus('trololo', function(status){
                                          // Offline (1), Online (2), Away (3), Do not disturb (3)
                                          console.log(status);
                                        });
                                        
                                          0
                                          http://status.icq.com/online.gif?icq=ТУТ_ВАШ_UIN
                                          кажется больше не работает!
                                          Что делать?
                                            0
                                            Закопать…
                                            0
                                            Ответили из службы поддержки аськи:
                                            На текущий момент такой функционал отсутствует.
                                            Ваши пожелания будут переданы администрации проекта.
                                            Спасибо за сотрудничество.
                                            С уважением.
                                            Служба поддержки пользователей ICQ

                                            Only users with full accounts can post comments. Log in, please.