пʼятниця, 17 липня 2009 р.

Объединяем В Контакте и Twitter в PHP

Объединяем Твиттер и В Контакте и получаем... В Контер? Нет, Твиттанте... В общем, пусть каждый называет это по-своему, потому что недавно возмутились об отсутствии структуры "а дальше читатель пусть подумает сам" в моём блоге.

А пока ты только думаешь, Смирнов уже сделал... трансляцию статуса Twitter в свой аккаунт В Контакте. Да окрестил сие чудо  "tvkontakte 0.1", да разрешил издеваться над творением своим... Во имя CTRLa, ALTa и святого DELa, Enter!

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

  1. Скрипт читает RSS ленту с Твиттера, публикует последнее сообщение В Контакт.

  2. Умный В Контакте распознаёт ссылки и делает их кликабельными, дописывая свои <a href="away.php?...

  3. Скрипт через заданный в cron промежуток времени заходит В Контакт и видит - "О Боже! Статус-то уже не такой, как последний на Твиттере, а я его до сих пор не обновил!" и быстренько обновляет.

  4. В результате и скрипту покоя нет долгими утрами, когда я сплю, (нет, это не повод оставлять его без куска хлеба над головой, просто вырвалось), и друзьям покоя тоже нет - они в "Мои новости" будут каждые n минут будут видеть мой статус как новый и им это быстро надоест, в следствии чего закидают монитор камнями. И останусь я без друзей... Так, опять не туда.


В общем, я изначально думал выполнять все действия В Контакта, чтоб составлять статус для сравнения и мне стало лень. Поэтому при обновлении скрипт в моей вариации записывает статус ещё и в отдельный файл, а потом сверяет последний в ленте со строкой в файле.

Минус такого решения очевиден (например, лишний геморрой с атрибутами файла и дополнительный пункт в настройках скрипта). Но плюс, помимо того, что не мучаю друзей, есть ещё один. Так я могу изменить статус В Контакте на свой, и пока я не напишу в Twitter что-то новое, он будет висеть, как так и надо.

В общем, хватит лирического отступления. Вот код vtweet.php.
< ?
/*
tvkontakte 0.1i
vkontakte.ru status updater from twitter
made by Vladimir Smirnoff
http://orl.sumy.ua
mail@smirnoff.sumy.ua
improved by Kichrum
http://Kichrum.org.ua
*/
# Конфигурация - ОТРЕДАКТИРУЙ!
define ('TWITTER_USERNAME','MyLogin'); // MyLogin заменить на свой Логин в Twitter
define ('VKONTAKTE_LOGIN','user@mail.ua'); // user@mail.ua заменить на свой E-mail на Vkontakte.ru
define ('VKONTAKTE_PASSWORD','gfhjkm'); // gfhjkm заменить на свой Пароль на Vkontakte.ru
define ('PREPEND_WORD','Twitter.com/Kichrum '); // Twitter.com/Kichrum заменить на Слово, которое будет перед статусом: максимальная длинна: 20 символов с пробелами = 160 во vkontakte - 140 в twitter
# Конфигурация выполнена.
# Дальше можно не читать :)
# Объявляем Дуровский UserAPI
class vkuserapi {
private $curlh = null;
public $uid = null;
private $sid = null;
public function __construct ($login,$password) {
$this->curlh = curl_init();
$request = 'http://login.userapi.com/auth?site=2&login=force&pass='.urlencode($password).'&email='.urlencode($login);
curl_setopt($this->curlh, CURLOPT_URL,$request);
curl_setopt($this->curlh, CURLOPT_FAILONERROR, true);
curl_setopt($this->curlh, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($this->curlh, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->curlh, CURLOPT_POST, false);
curl_setopt($this->curlh, CURLOPT_HEADER, true);
$auth_result = curl_exec($this->curlh);
if (preg_match("/remixmid=(\d+)/", $auth_result, $matches)) $this->uid = $matches[1];
if (preg_match("/.*;sid=(\w*)/", $auth_result, $matches)) $this->sid = $matches[1];
}
public function call ($func,$params) {
curl_setopt($this->curlh, CURLOPT_HEADER, false);
$request = 'http://userapi.com/data?act='.$func.'&'.http_build_query ($params).'&sid='.$this->sid;
curl_setopt($this->curlh, CURLOPT_URL,$request);
$result = curl_exec($this->curlh);
return json_decode($result);
}
public function __destruct () {
$request = 'http://login.userapi.com/auth?login=logout&site=2&sid='.$this->sid;
curl_setopt($this->curlh, CURLOPT_URL,$request);
curl_exec($this->curlh);
curl_close ($this->curlh);
}
}
# Берем статус со своей RSS-ленты на Twitter.com
$rss = simplexml_load_file('http://twitter.com/statuses/user_timeline/'.TWITTER_USERNAME.'.rss');
# Убираем лишнюю информацию
foreach ($rss->channel->item as $status) {
if (strpos($status->title,'@')) continue; // Фильтр реплаев в Twitter
$last_status_twitter = str_replace (TWITTER_USERNAME.': ','',$status->title); break;
}
# Читаем последний обновлённый статус из файла vtweet.txt
$f=fopen(dirname(__FILE__).'/vtweet.txt','r');
$last_status_vkontakte = fread($f,512);
fclose($f);
# Если последний статус ещё не опубликован во В Контакте, публикуем и помечаем его как обновлённый
if (($last_status_vkontakte != $last_status_twitter) && ($last_status_twitter != NULL)) {
$vkontakte = new vkuserapi (VKONTAKTE_LOGIN,VKONTAKTE_PASSWORD); // Логинимся
$vkontakte->call ('set_activity',array('ts'=>time(),'text'=>PREPEND_WORD.$last_status_twitter)); // Обновляем статус
unset ($vkontakte); // Выходим из Vkontakte.ru
$f=fopen(dirname(__FILE__).'/vtweet.txt','w');
fwrite($f,$last_status_twitter); // "Помечаем" статус как уже обновлённый
fclose($f);
echo 'Updatetd.';
}
else echo 'No update needed.'; // Если последний уже помечен, выводим внутреннюю ошибку.
# Завершаем работу программы.
?>

Плюс требуется создать файл vtweet.txt, положить его в папку со скриптом и прописать для него chmod 777. И в завершении всего прописать в crontab новою задачу, где указать адрес файла .php и периодичность, с которой требуется обновлять статус. Например, я себе поставил */15 * * * *, что означает запуск скрипта каждые 15 минут.

Скачать всё архивом: tvkontakte 0.1i (не забудь отредактировать нужные поля в vtweet.php).

Нюансы, которые моя вариация перенимает у оригинала: версия установленного PHP должна быть не ниже 5.1, должны быть подключены lib_curl, simple_xml и allow_url_fopen (за этим обращайся к хостинг-провайдеру), Twitter-профиль не должен быть приватным, хостинг-провайдер не должен быть забаненным В Контакте. Последнее случается, если хостинг имеет бесплатные/дешёвые тарифы или на нём хостился какой-нибудь горе-автор какого-нибудь сервиса для ВКонтакта. Например, такое такое горе случилось с masterhost.ru, когда на нём оказался зарегистрированным сайт vtwittere.ru.

Исходная версия скрипта от Владимира Смирнова: Трансляция статуса твиттера в контакт (сам код).

Выбирай и пользуйся :)

UPD: Исправил пару недочётов :)

UPD (18.07): Через форму обратной связи (см. справа) можно присылать мне свои логины к Твиттеру и мыло/пароль к В Контакте - я пропишу у себя на сервере и будет у тебя всегда свежий статус В Контакте. Только поспеши, предложение не вечно!

UPD (10.02.2011): Появился первый бесплатный веб-сервис для автоматического кросспостинга статусов из Твиттера во ВКонтакте! Пиши в обратную связь или комменты, а я на мыло отправлю ссылку.

UPD (18.02.2011): Сервис теперь публичный! Сегодня (или даже вчера) открылся веб-сервис с удобным интерфейсом, названный как ТуВконтакте.ру и призванный объединить аккаунты пользователей Twitter и ВКонтакте. Теперь не нужно разбираться с хостингами, PHP и Crontab.

UPD (12.08.2011): С недавнего времени скрипт не работает на иностранных хостингах! Поддерживаются только хостинги стран СНГ. (В Контакте так борется со спамом и вирусами).

UPD (11.11.2011): Увидела свет новая версия данного скрипта - с разворачивающимися ссылками. Качать по желанию.

UPD (26.03.2012): По всей видимости, ООО "ВКонтакте" отключило поддержку UserAPI. На всегда или нет - не известно, как и то, будет ли работа восстановлена позже. Но если работа сайта durov.ru не возобновится (на его основе и работает скрипт), то скорее всего шансов не останется... ТуВконтакте.ру аналогично не работает.

78 коментарів:

MrGALL сказав...

Щоб не прописувати вручну папку до скрипта — краще писати ось так:
$file=dirname(__FILE__)."/vtweet.txt" );

А щодо цього ідеї поєднувати Твіттер та Вконтактє — ІМХО це дуже потрібно (як і Вконтактє загалом) :)

Kichrum сказав...

Да, точно, спасибо. Я просто думал, что крон __FILE__ тоже проигнорирует или поставит свой. Ну раз работает, обновил. :)

Kichrum сказав...

Кстати, кто не имеет своего сервера или кому лень что-то делать самому - пишите через форму обратной связи Твиттер-логин, имейл/пароль ко В Контакте - я сделаю автообновление через свой сервак. Только мест ограничено (боюсь бана), так что поспешите. =)

Kichrum сказав...

Так... Объявилась ещё проблема. В Twitter есть ограничение на подключения к RSS-фидам с одного IP (150 раз в час). У меня эта проблема проявилась (нет, не данный скрипт подключался так часто, просто на моём сервере другими пользователями расположены ещё некоторые программы для Твиттера). В следствии этого вместо обычной ленты получаем ошибку, скрипт распознаёт как новый статус - пустое значение, отсюда несходство с последним обновлённым и скрипт срабатывает. В общем, к условию выполнения скрипта предусматриваем значение NULL.

Находим это:
# Если последний статус ещё не опубликован во В Контакте, публикуем и помечаем его как обновлённый
Чуть ниже это:
if ($last_status_vkontakte != $last_status_twitter) {
заменяем на вот это:
if (($last_status_vkontakte != $last_status_twitter) && ($last_status_twitter != NULL)) {

Мне помогло, архив обновил. :)

Николай сказав...

Заметил что при обновлении статуса вконтакте через юзерапи друзья не получают уведомлений

Kichrum сказав...

Спасибо за новость, Николай. Не исключено и такое, но лично не проверял. А правило хорошего тона - не дёргать часто В Контакт - в любом случае поможет в сохранении IP твоего сервера от бана.

WeRteR :) сказав...

Жестячно, але трошки незручно ;)

Краще зробити форму для введення статусу і вже її опрацьовувати.

Kichrum сказав...

Тобто замахнутися на сотні дуже зручних Твіттер-клієнтів зі своєю формою, яка має лише один "+" в тому, що може оновлювати статус не тільки на Твіттері, а й В Контакті? Ні, от це вже дійсно було б безґлуздо, я гадаю! Хоча й зробити це дуже легко, я віддаватиму перевагу ТвіттерГаджету в iGoogle перед власною розробкою.

Чи може я не вірно зрозумів твій комент, Вертере?

Тарас сказав...

Я обледенил ваш вариант и Radmus’a. Можете взглянуть здесь http://www.taras.pro/2009/08/avtomaticheskoe-obnovlenie-statusa-v-kontakte-pri-pomoshhi-twitter-%E2%80%93-twitter-2-v-kontakte/

Kichrum сказав...

Спасибо, Тарас. У меня было такое же желание, но решил, что меньше кода = меньше проблем. Чего-то о скорости не подумал...

Kenjik сказав...

А можно ли как-то тоже самое, но в Новости группы запихивать? Именно в Новости, а не на Стену.

Kichrum сказав...

К сожалению, нет. UserAPI сейчас ещё не умеет работать с группами.

Iriska сказав...

А таким образом проставленные статусы видны в ленте друзей?

Kichrum сказав...

Если верить Николаю, то нет. Лично я не проверял, но по-моему, тоже нет. Да и кто в ту ленту друзей подписывается на статусы? Это ж сколько мусора будет, если друзей хотя бы 100 =)

Kichrum сказав...

Я только-что перешел на версию Тараса. Одобрянус! :) С API я могу позволить себе большее (выставил запуск скрипта ежеминутно, хотя хостер не позволяет. Так что если блог уйдет в оффлайн...... ;))

Была проблема с 267-й строкой твиттер-классов. Исправляется тупо закомментированием:
// curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);

DPolyakov сказав...

Спасибо за скриптик. Перешел на него со скрипта radmus.net, тот почему то поломался )))
Ваш работает - спасибо. Дам ссылочку в твиттере ))

Kichrum сказав...

DPolyakov, спасибо. Ретвитну :)

Юлий сказав...

Хороший скрипт. Сейчас как раз изучаю возможности этой платформы. Так что думаю что пригодится.

Аббат_Кальне сказав...

спасибо, с меня наверно постовой )))

Сергей сказав...

Прикольный скриптец! Попробую его в действии.

Kichrum сказав...

ВКонтакте стал поддерживать связь в обратную сторону (экспорт статусов с ВКонтакте в Твиттер): ВКонтакте - Мои настройки - Мобильные сервисы - Экспорт статуса.
Конфликтов со скриптом не обнаружено! Прекрасно работает связь в обе стороны: можно обновлять статус ВКонтакте и он скопируется в Твиттер, и наоборот: написав новый твит, он станет статусом ВКонтакте.

Astri сказав...

спарились таки ))

Ольга сказав...

Мне кажется экспорт статуса рано или поздно в Твиттере могут вычислить, что чревато баном

Kichrum сказав...

Ольга, это не против правил вообще-то...

Ольга сказав...

Я имела в виду что с Твиттером надо аккуратно, модеры банят, с любым подозрением на ссылочный спам. А если держать ак в твиттере не ради обратных ссылок, то это простое время провождение. Вывод, тогда лучше поддерживать еще и ручками.

fm сказав...

А есть такой скрип который бы транслировал статусы из твитера в вконтакт? Причем работающий)

hexkey сказав...

Дык а зачем такие сложности? Все на много проще можно реализовать... оО

fm сказав...

hexkey как? просвятите пожалуйста

Юра сказав...

актуальный скрипт *ссылка удалена, объяснение - ниже*, работает с новой стеной. сам использую.

Kichrum сказав...

Грамотно написанные скрипты не приходится переделывать столь часто. Этот скрипт работал во все времена и работает до сих пор, с июля 2009 года. Пережил уже несколько обновлений API Твиттера (которые на него никак не влияют) и глобальные перестройки вконтакта.
А твой сайт всех спамерами обзывает - комент оставить невозможно, посему я удалил ссылку из твоего комента.

Марат сказав...

Можно ли как-то добавить поддержку приватных акков?

Kichrum сказав...

Марат, приватные аккаунты в Twitter данный скрипт действительно не поддерживает. В комментарии #9 Тарас выставлял ссылку. Так вот, там реализация с Twitter API, а следовательно, приватные поддерживались. Но в данный момент тот скрипт не работает...

fox сказав...

в отчете крона сваливается просто сам код скрипта, на хостинге все перечисленные параметры открыты... куда копать, подскажите?

allmoney сказав...

А ретвиты он в контакт отправляет?

Kichrum сказав...

Нет, но это легко исправить с минимальными знаниями PHP. Там есть комментарий.

Grawl сказав...

Всё равно этот способ — фигня. Вэб-сервис нужен, не у всех ведь есть хостинг с кроном.

Kichrum сказав...

Grawl, а ты чем читаешь? Последнюю строчку статьи особенно.

Тупиков Александр сказав...

Что за волшебный и бесплатный сервис для синхронизации? Дай сцылку! )

Kichrum сказав...

Александр, отправил на имейл! Пользуйся на здоровье :)

Twitter to vkontakte « sandalov.org сказав...

[...] kichrum.org.ua [...]

DPolyakov сказав...

А можно всё тоже самое, но только чтобы постил на стену страницы а не юзера?
А то сам бьюсь - никак не выходит.

Kichrum сказав...

DPolyakov, этим скриптом нельзя. Необходимо написать с нуля: под VK Api вместо UserAPI.

gregox сказав...

как код то получить? или сервис не работает уже?

Kichrum сказав...

gregox, приглашение выслал на мыло.

andy сказав...

invite плз)

stolb сказав...

invite плз)

Anna сказав...

invite плз)

Александр сказав...

Скрипт продолжает работать? У меня несколько дней как перестал.

$vkontakte = new vkuserapi (VKONTAKTE_LOGIN,VKONTAKTE_PASSWORD);
отрабатывает, $vkontakte->uid есть, но

$vkontakte->call ('set_activity',array('ts'=>time(),'text'=>PREPEND_WORD.$last_status_twitter));
перестал работать и ->call ничего не возвращает.

На http://2vkontakte.ru/ всё нормально? invite плз

Kichrum сказав...

Выслал пригласительный код на мыло.
ТуВконтактик работает по тому же принципу, что и скрипт, так что проблемы, видимо, в тебе. Может быть, хостинг иностранный? Они вроде бороться с этим начинают активней :(

klisanor сказав...

QUOTE: "Скрипт продолжает работать? У меня несколько дней как перестал."

У меня тоже, переехал на другой сервак, заработало. Раньше было на иностранном хостинге.

Kichrum сказав...

Да, совершенно верно, нужен только хостинг в СНГ теперь. Причем на сайте можно вводить 4 цифры телефона и все ок, а для юзерапи отрезали намертво. С американских айпи например даже не заходит на их же дуров.ру (который сделан по тому же апи, что и этот скрипт).

Тима сказав...

У меня перестали импортироваться твитты через сервис, что произошло?

Kichrum сказав...

Хз. Реплайни в твиттер на @2vkontakte, и укажи имейл наверн. Только предварительно почитай этот твиттер - авось и решение проблемы найдется...

tim сказав...

У меня такая же проблема, как в 52 комменте. Email, на который оставил этот комментарий

Не могу написать твитт (не хочу публично его указывать email, а DM не написать, потому что @2vkontakte никого не фолловит). Суть проблемы - сначала вот эта была: http://feedback.2vkontakte.ru/?ia=192967 потому сменил пароль, думал заработает и, видимо теперь эта проблема: http://feedback.2vkontakte.ru/?ia=194753

poltavtcev сказав...

можно приглашение на 2вконтакте?
Спасибо

tim сказав...

ну так что с сервисом случилось? когда заработает? или больше не стоит рассчитывать?

ivg сказав...

Отличный скрипт и респект за комментирование кода! Но.. У меня американский хостинг, а на работе стремно оставлять - пароль то в открытом виде.. Так что прошу инвайт на 2vkontakte :)

Евгения сказав...

Установила скрипт.
При проверке считывает вроде правильно, статус в твит.тхт меняется, сообщение выдается первый раз "updated", а потом "no update need"
Ошибок никаких не выдает.
Но на стене ничего не появляется.
Хостинг на 1gb.ua, вроде украинский.
Что еще может быть неправильно?
Еще пользуюсь хостингом на ukrhosting.com, но там выдает ошибку
Warning: simplexml_load_file(): URL file-access is disabled in the server configuration
Скорее всего выключен allow_url_fopen
Если не сложно, поделитесь инвайтом для вебсервиса.

Kichrum сказав...

Привет, Евгения. Проверил, твой IP украинский, сервера хостинга вроде бы тоже в Украине. Очевидных проблем не замечено. Попробуй сделать следующее:
1. Установи на свой сайт любой бесплатный php-анонимайзер желательно последней версии (phpProxy).
2. Зайди через него (в режиме поддержки javascript & cookies) на сайт vkontakte.ru (возможно уже на этом этапе ты увидишь, в чем проблема - если хостинг забанен вконтактом).
3. При надобности введи последние цифры своего мобильного.
4. Напиши новый твит и запусти скрипт заново.
Возможно, это поможет. Если нет, то у меня пока других идей нету. Знаю что вот ua-hosting.com.ua точно ещё не забанен на серверах ВКонтакте (я сам для скрипта использую его).
ну и если что, инвайт выслал на мыло.

Марк сказав...

Якщо можна то я би хотів отримати інвайт)

Kichrum сказав...

Марк, відправив тобі на мило.

Magi сказав...

Пришлите пожалуйста инвайт на 2vkontakte!

Kichrum сказав...

Magi, рад бы, да вот сервис только для пользователей из Украины =(

Magi сказав...

А можно ли модифицировать скрипт так, чтобы он слал все твиты с момента обновления. Т.е. я выкладываю 5 твитов за раз, а вконтакт уходит только последний. К сожалению php практически не владею...

Kichrum сказав...

Magi, эт не сложно, могу тебе сделать так, платно. Пиши в обратную связь ;)

ЗЫ. В данном скрипте постится только один твит во избежание спама и чтоб люди думали, что это вы действительно их так любите и бережно пишете в контакт сообщения вручную.

Nbarannik сказав...

Добрый день!

Каким образом получить инвайт на Ваш сервис http://2vkontakte.ru/ пожалуйста?

Kichrum сказав...

Nbarannik, для России не работает вроде, но все равно выслал, вдруг пригодится. =)

Иван сказав...

Ребят, презентуйте инвайт, пожалуйста!

[e-mail затерт автором блога во избежание спама]

Kichrum сказав...

Иван, отправил инвайт.

Мыло можно не писать в сообщении, достаточно только указать его под ником.

Иван сказав...

Спасибо, огромное! Буду рекомендовать вас всем знакомым. Ваш сервис - просто блестящая идея. Процветания вам и успехов!

Vujko сказав...

Большое спасибо. Очень полезный плагин. Вышлите, пожалуйста, инвайт.
Насколько я понял, плагин публикует в статус. А возможно автоматическое оформление как новости в группу. Как на реализовано здесь http://habrahabr.ru/blogs/social_networks/115658/

Kichrum сказав...

Vujko, нет. Инвайт выслал.

ASLok сказав...

Пришлите инвайт пожалуйста )

Kichrum сказав...

ASLok, отправил тебе на мыло.

sterxx сказав...

Можно попросить инвайт?

Kichrum сказав...

sterxx, отправил.

aparserok сказав...

Привет, статья отличная, жаль устарело.
А тувконтакт работает? Поделись, пожалуйста, инвайтом.
Спасибо

Kichrum сказав...

aparserok, к сожалению, не работает уже ничего =(