пятница, 11 ноября 2011 г.

Разворачивание сокращенных ссылок из Твиттера

С появлением у Твиттера новой сокращалки ссылок t.co, меня, как соавтора Кросспостера из Твиттера во ВКонтакте, заспамили просьбами сделать развертывание этих ссылок, чтоб В Контакт публиковался чистый полный URL. Но я не видел в этом большой проблемы, пока супербезопасный ВКонтакте не начал считать все эти ссылки фишинговыми. Долго терпел, но теперь наконец набросал развертывание этих ссылок за каких-то минут пять.

Сперва хотел делать переход по ссылке, смотреть, куда переадресовывается. Но быстро откинул эту идею. Правильней же будет использовать API сокращалки. Но времени тратить на изучение ненужного в дальнейшем API не хотелось. К тому же у каждой сокращалки свой API, а не плохо было бы расшифровывать все сокращенные ссылки. Поэтому вместо сайта dev.twitter.com я полез в гугл и нашел прекрасный untiny.me - готовый сервис развертывания сокращенных URL. Ссылки "API" на нем я не заметил (хотя она есть), а полез сразу в исходники страницы - но и там всё достаточно просто и понятно.

Решено было не изобретать велосипед, а использовать их базу сокращалок. И вот первая и главная строчка решения проблемы готова:
$response = simplexml_load_file('http://untiny.me/api/1.0/extract/?url='.$short_url);

Теперь в переменной $response->org_url хранится длинная ссылка, полученная из короткой $short_url.

Дальше - просто отключим вывод ошибок (собачкой, на всякий пожарный - вдруг Untiny грохнется), обернем это в функцию и дело в шляпе.

Ах да, у многих же сохранилась привычка со времен "Твиттера без t.co" резать ссылки через сторонние bit.ly, goo.gl и прочие. Вместе с t.co получается, что ссылка сокращается не один раз, а два и даже больше. Некоторые спаммеры пропускают свою вредоносную ссылку через одну, вторую, третью резалку и только потом публикуют ее в Тви (который, наконец, пропускает уже сокращенную ссылку через свой t.co). Поэтому запустим рекурсию, пока Untiny не начнет выдавать ошибки вместо ссылок:
function untiny($short_url) {
$response = @simplexml_load_file('http://untiny.me/api/1.0/extract/?url='.$short_url);
$result = $response->org_url;
if(strstr($result, 'http://'))
return untiny($result);
else
return $short_url;
}

Со ссылкой разобрались, но нам же надо не просто её развернуть, а и найти её в сообщении, а потом заменить на "правильную" ссылку. Пишем вторую функцию.

На вход подаем сообщение, на выход - тоже сообщение, но с измененной ссылкой. Используем о ужас регулярки. =) Примерно так найдем t.co-ссылку:
preg_match("#http:\/\/t\.co\/(\w+)#", $message, $regex)

а потом заменим её на развернутую:
preg_replace("#http:\/\/t\.co\/(\w+)#", untiny($regex[0]), $message)

Почему именно t.co? А всё равно твиттер по своим API и RSS (как в случае с моим кросспостером) отдает все ссылки именно так.

А что же будет с сообщением, содержащим больше одной ссылки? Всё поломается - все ссылки будут развернуты так же, как первая. Это плохо. Добавляем в preg_replace последний параметр лимит и запускаем в цикл пока ссылки на t.co есть:
while(preg_match("#http:\/\/t\.co\/(\w+)#",$message, $regex)) {
$short_url = $regex[0];
$message = preg_replace("#http:\/\/t\.co\/(\w+)#", untiny($short_url), $message, 1);
}

Чтоб не страдать от отсутствия доступа в Untiny, искусственно лимитируем использование функции untiny() десятью запусками, и оборачиваем для удобства в функцию:
function untiny_message($message) {
if(strstr($message, 'http://')) {
$i = 10;
while(preg_match("#http:\/\/t\.co\/(\w+)#",$message, $regex) && $i--) {
$short_url = $regex[0];
$message = preg_replace("#http:\/\/t\.co\/(\w+)#", untiny($short_url), $message, 1);
}
}
return $message;
}

Теперь, достаточно передать в функцию untiny_message() сообщение из Твиттера и сохранить сообщение с развернутыми ссылками, которое вернет эта функция. Например, так:
$message = untiny_message($message);

Получилось местами не очень гуманно, но быстро в реализации, просто и понятно.

Кросспостер с этой функцией можно скачать здесь: tvkontakte 0.2i (инструкция тут).

Предыдущая версия по прежнему тут: tvkontakte 0.1i.

Приятного использования!

UPD: Реализовано и на ТуВконтакте.ру.
Инвайты:

  • XHpJinnz3tOgAlq2g22dK6ZkmWz0eX4Y

  • IWVjMEcs72owV0bt93InH9GUfv58tIO4

  • V31kIrOnlFGlbe8fqMB1aOSVz1ZYyH8m

  • 4G9JBZi1b78LI3L6rZQHohS9oKI5AXxn

  • gSo4jVNw7CkdIL6Dt2ltta5iqbjqqdRM




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

44 комментария:

Тагрим комментирует...

Чтобы обрабатывать все ссылки исползуй цикл foreach.

foreach (preg_match(...)) {
$message = preg_replace(...);
}

Window комментирует...

Позновательно но за чем разваричивать ссылки и так не плохо.

Kichrum комментирует...

Тагрим, о_О че-то ты какой-то бредок написал =) Тогда уже preg_match_all("#http:\/\/t\.co\/\w+#",$message, $regex); и foreach($regex[0]) {...}
Только тогда всплывают новые вопросы - как быть, если untiny.me недоступен, например? Тогда первая ссылка заменится на последнюю. В общем, лучше не заморачиваться, а оставить кривое, но работающее =)

Антон комментирует...

Буду пользоваться. Не пойму, зачем вообще ссылки посокращали.

Артем комментирует...

По моему это вообще полный бред! Кому от этого легче?

crusader комментирует...

Действительно полезно. Надо тоже такое заумтить

wudwan комментирует...

А я твиттером давно не пользуюсь, не вижу никакого смысла в этом.

Катя комментирует...

Я тоже не вижу в этом смысла...

Роман комментирует...

Мне и так скорочиные ссылки нравиться.

Алина комментирует...

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

DmitrySandalov комментирует...

Прикрутить untiny раньше и в голову не приходило: пусть мучаются контактовцы ))
2i пашет. Линки кросспостятся в контакт отлично.
По скачиванию архива сразу же "rm index.php" ))

Сделал WhiteList для некоторых твитов с @:

foreach ($rss->channel->item as $status) {
if ((strpos($status->title,'@')) and
( (strpos($status->title,'[pic]')) or
(strpos($status->title,"I'm at")) or
(strpos($status->title,"YouTube"))
)
)
{ $last_status_twitter = str_replace (TWITTER_USERNAME.': ','',$status->title); break; }
if (strpos($status->title,'@')) continue; // Фильтр реплаев в Twitter
$last_status_twitter = str_replace (TWITTER_USERNAME.': ','',$status->title); break;
}


Пока вайтлистятся твиты из 4square и YouTube, но при желании можно добавить всё, что требуется.

Думаю о добавлени в скрипт кросспоста в Google+:
http://360percents.com/posts/first-google-google-plus-status-update-bot-in-php/
Чел пишет, что у него работает, я у себя пока не смог завести, нет времени дебажить )
(ЗЫ: одноклассников тоже неплохо было бы добавить, но мыслей пока нет.. Сам туда 1р/мес захожу, но кросспост всё-тки хочется)

Kichrum комментирует...

DmitrySandalov, лично я себе давно сделал так (вместо строчки 54 тут):
if( (strpos($stext, '@') === 0 && !strstr($stext, '#vk')) || strstr($stext, '#novk') ) continue;
То есть, реплаи без хештега #vk и любые сообщения с хештегом #novk не кросспостятся. Этого достаточно, поскольку твиты с собачкой считаются реплаями только если ты начинаешь сообщение с @, остальные - ты просто называешь имя, это уже вполне читаемый автономный твит.

Владимир комментирует...

А зачем разворачивать ссылки, вроде и так нормально)

Toha комментирует...

Да и сокращённые норм!

Алексей комментирует...

Ну не знаю, не знаю, я лично понимаю, что Твитет это очень важно, но вот я его не понимаю, мне вообще не нравиться подача информации на этом ресурсе. Меня даже это раздражает ))

Sashsa комментирует...

Как по мне так и сокращенные нормально) на вкус и цвет как говорится...

Роман комментирует...

Что не делается все к лучшему

wiki-biz комментирует...

Я бы не разворачивал ссылки. Всё компактно и красиво. Хотя может кому и пригодится.

Днепропетровск комментирует...

В твиттере же ограничение по символам для поста, потому хорошо, что ссылки компактные получаются
минут тут такой, что название сайта не светится и не запоминается

Kichrum комментирует...

Ну вот, спамеры, вы начинаете понимать... Осталось еще учесть, что в Контакте это ограничение не такое жесткое, поэтому ссылки и надо разворачивать, чтоб домен сайта был виден =)

Den комментирует...

мне понравилось попробую

Дмитрий комментирует...

А толку от разворачивания, я не понимаю.

Маша комментирует...

А мне от того, что они разворачиваются или нет все равно! Прикольно просто смотрится когда ссылка сокращенная и все)))

kyzja комментирует...

спасибо, может, пригодится!)

Влад комментирует...

Отлично, спасибо больше)

combatx007 комментирует...

не соглашусь, твиттер сегодня имеет, как большое социальное значение, так и коммерческое, достаточно посмотреть там список организаций

Иван комментирует...

Во дела. Впрочем, вконтакт всегда все блокировал, так что вы проделали отличную работу, пусть она и была за 5-ть минут :)

Вебмастера комментирует...

Хм спасибо ! За статью

Katia комментирует...

А кроме как улучшить индексацию твиттер ещё для чего-нибудь нужен?

WebWed комментирует...

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

Money5 комментирует...

Для твиттера ссылки лучше сворачивать так как там ограничение на длину тектса и url может не поместиться или занять много места, а вконтакте понятно смысла нет в сворачивании

Інфопортал комментирует...

Спасибо за статью.
Могу добавить, что TwitterFox умеет «разворачивать» ссылки некоторых сервисов коротких адресов. Полный адрес отображается в подсказке при наведении мыши.

slava комментирует...

не понял проблеммы.. эти сервисы не просто так придуманы. как я информирован - они увеличивают вес сайта путем сокращения ссыл..
но воля ваша

Kichrum комментирует...

вес сайта - вконтакта и твиттера разве что ;)

wasiliy комментирует...

Спасибо долго искал решение этой проблемы. А на вопрос зачем это надо отвечу за автора,- да чтоб трафу больше было на сайте за счет поднятия веса ссылочной массой, вот как то так.

Юся Рысёнок комментирует...

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

Дмитрий комментирует...

В твите ограничение 140 символов, поэтому лучше писать сокращенную ссылку, ну или очень маленькое описание

potter062 комментирует...

Да уж поучительная статейка, может и я когда нибудь смогу так же програмировать

vitaly комментирует...

Хороший учебный материал для желающих научиться

Александр комментирует...

Наконец то нашел) спасибо автору, надела эта проблемс в твиттере)

bloodwit комментирует...

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

punkWJ комментирует...

Смею возразить по поводу untiny.me. Для чего Вам сторонний сервис разворачивания урлов? Напрвалю Ваc на другой путь - всё отлично реализуется с помощью cUrl и пишется в несколько строчек кода.

Kichrum комментирует...

punkWJ, и ходить по различным серверам сокращалок самостоятельно? Нет уж. Лучше ходить только к одному проверенному сервису с удобным API.

александр комментирует...

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