Автоматизация отправки сообщений между социальными сетями
Уже больше месяца активно использую IFTTT для кросс-публикаций в социальных сетях. Хочу поделиться тем, как к этому пришёл и на какие уловки пошёл, чтобы добиться кросс-постинга, близкого к тому, который мне нужен.
Я пишу в социальных сетях для себя, а не для работы. И мне удобно писать из того места, где я провожу время, поэтому программное обеспечение для SMM мне не подходило: оно дорогое, да и требует писать из другого места.
В основном я провожу время в Twitter и Telegram, фотографии размещаю в Instagram, а недавно ещё начал вести подкаст на Anchor. Некоторые сообщения удобнее писать в одной сети, некоторые — в другой. К тому же хочется иметь хоть какой-то контроль над своими сообщениями, чтобы не потерять их в один момент из-за решения какой-то корпорации. Поэтому я также присоединился к децентрализованной социальной сети Fediverse и завел себе личную Friendica, куда просто дублирую свои посты из других соцсетей.
При выборе решения для присоединения к Fediverse остановился на Friendica, потому что она написана на PHP, с которым работаю каждый день на работе, при необходимости могу модифицировать движок под себя и развернуть на виртуальном хостинге. Friendica не устраивает лишь тем, что не позволяет гостям оставлять комментарии, но поскольку это в большей степени решение для резервного копирования, то это не критическая проблема. В других приложениях, которые я попробовал или просмотрел, было больше критических недостатков для меня.
Многие люди переходят на децентрализованные социальные сети, потому что не хотят, чтобы корпорации следили за ними, анализировали их и знали о них всё. Меня это не очень беспокоит, с этим я смирился, но меня больше беспокоит то, что корпорация в любой момент может удалить все мои сообщения, всю мою историю.
Копировать сообщения вручную мне лень и дорого тратить на это время, поэтому я начал подробно изучать решения для автоматического архивирования сообщений в социальных сетях.
Последние несколько лет я пользовался бесплатным тарифом IFTTT, который позволял использовать готовые апплеты и создавать три собственных, в которых можно было объединить только два звена. Этого хватало, чтобы автоматически публиковать посты из Instagram и Twitter в Telegram, иногда не в том формате, который мне нужен. И этого хватало даже для дублирования всего этого в Friendica, но хотелось большего контроля. Хотелось, чтобы можно было задавать формат для всех пересылаемых сообщений, а также было желание делать более длинные посты в Telegram, которые будут обрезаться и отправляться в Twitter без возврата обратно в Telegram, создавая дублирование. Для этого бесплатного тарифа IFTTT было недостаточно, поэтому я начал искать альтернативы.
Сначала присмотрелся к отечественному ApiX-Drive, который ориентирован на бизнес-клиентов. У них много классных интеграций, необходимых для бизнеса, но пока нет интеграции с Twitter. Как я уже говорил, для бизнеса есть масса SMM-решений, которые публикуют посты в нужные соцсети как надо, поэтому обычно сервисы автоматизации не очень ориентируются на соцсети, так как их клиентам это меньше нужно от них. Да и я пока не готов платить 19 долларов в месяц за кросспостинг сообщений в личные микроблоги. Поэтому ApiX-Drive пришлось отложить.
Затем я начал подробно изучать n8n, который мне порекомендовал коллега по работе. Сам сервис с открытым исходным кодом, и его можно бесплатно запустить у себя, если есть навыки и компьютер для этого. Сначала попробовал облачную версию сервиса, которая стоит 20 долларов в месяц, но первый месяц предоставляется бесплатно. Необходимые интеграции у сервиса есть, и он очень гибкий, позволяет гибко реализовывать сложные задачи в автоматизации. Но почти сразу столкнулся с тем, что из Twitter получаются только обрезанные сообщения до 140 символов. Теоретически в API-запросе можно передать параметр, который заставит возвращать полные сообщения, или изменить версию API, что ещё сложнее. Но для этого нужно модифицировать исходный код, поэтому облачная версия не подходила, и пришлось запускать сервис на локальном компьютере.
У меня не получилось запустить локально на Windows 10 сервис, написанный на Node.js. Если бы я профессионально работал с Node.js или использовал UNIX-подобную операционную систему, то, возможно, у меня это получилось бы. Да и на Windows у меня это получилось бы после многих часов копания в руководствах и поиска советов на форумах, но я не хотел тратить на это кучу времени. Держать такой сервис на локальной машине — не вариант, нужно арендовать сервер, на котором разместить приложение на Node.js, а это снова часы или дни на изучение того, как хостить что-то подобное. Попробовал покопаться в бесплатных сервисах хостинга Node.js, но там вообще всё как-то сложно, а тратить кучу времени было дорого, да и желания не было, поэтому отказался от n8n.
Стоит отметить, что только в n8n я увидел возможность превратить цепочку твитов из Twitter в одно сообщение и уже этим одним сообщением отправить его в другие места. Функционал классный, поэтому со временем я ещё вернусь к n8n. Возможно, что-то изменится, что позволит использовать его дешевле и проще для получения полных сообщений из Twitter. Ещё в n8n есть локальное хранилище, что упрощает контроль дублирования и зацикливания пересылки сообщений между несколькими сетями.
Также попробовал Integromat, но у него на бесплатном тарифе Twitter не было, а 9 долларов в месяц — это тоже немало, и платить сразу, не попробовав, не хотелось. Посмотрел Zapier, который использую на работе для резервного копирования сообщений из Slack в Evernote, но у него не оказалось интеграции с Telegram. Хотя о Zapier ещё скажу в конце — их бесплатный тариф иногда очень выручает.
В результате я вернулся к IFTTT, посмотрел их платный тарифный план и рискнул его оплатить.
IFTTT существует на рынке уже довольно давно, и с самого начала они ориентировались на отдельных энтузиастов, а не на бизнес, поэтому интеграция с Twitter у них хорошо налажена. Я не особо следил за сервисом, знаю, что новые тарифы они ввели прошлой осенью, а до этого были более доступными, но тогда сложная автоматическая пересылка мне не была особо нужна. Сначала они установили стоимость тарифа в 10 долларов в месяц, но сейчас минимальный тариф составляет 4 доллара, что с натяжкой устраивает для личного блоггинга.
Pro-план IFTTT позволил создавать апплеты, которые позволяют выполнять несколько действий, то есть отправлять данные в несколько сервисов по одному триггеру. Ещё платный тариф позволяет фильтровать данные, поступающие с триггера, и делать запросы на получение дополнительных сопутствующих данных. Но IFTTT не хватает дополнительного хранилища данных, чтобы контролировать, что уже было отправлено или получено, поэтому приходится прибегать к обходным путям.
Нужно было как-то контролировать, чтобы сообщение, которое мы получаем из Twitter, не было ранее отправлено через IFTTT туда же. Для этого могла бы помочь возможность дополнительно получать из Telegram последние сообщения, которую предоставляет платный тариф. Но это подходит только для текстовых сообщений. Если в Twitter было отправлено изображение или ссылка, то из Twitter они придут уже в виде сокращённых ссылок на t.co, и в случае отсутствия текста произойдёт повторная отправка сообщения в Telegram, которое до этого было переслано из Telegram в Twitter.
Чтобы избежать дублирования сообщений при кросс-постинге, пришлось использовать хак в виде невидимого символа нулевой длины, zero-width non-joiner (ZWNJ). Я просто начал добавлять этот символ в конец всех твитов, отправляемых через IFTTT, а затем игнорирую твиты, содержащие этот символ. Знаю, что этот символ имеет другое назначение, но я не пишу сообщения на языках, использующих этот символ, поэтому для меня он подходит. А для ретвитов просто не выполняю эту проверку.
Возможность ручной обработки пересылаемых сообщений позволила мне более аккуратно обрезать длинные сообщения, которые не помещаются в один твит. Автоматически они просто обрезались по последнему допустимому символу, и символ многоточия просто обрывал слово на середине. Вручную же мне удалось реализовать поиск начала последнего промежутка с небуквенными символами перед достижением лимита и уже вместо первого из них ставить многоточие.
Нужно ещё учитывать, что длина сокращённых ссылок в Twitter составляет 23 символа, а с пробелом и невидимым символом это уже 25 дополнительных символов, поэтому если текст обрезается, а за ним следует ссылка на другую сеть, то лимит становится 255 символов вместо 280.
Фильтрация сообщений осуществляется на языке TypeScript, на котором можно без особых проблем писать тем, кто программирует на JavaScript. Для меня проблема заключалась лишь в том, что отсутствуют некоторые функции, присутствующие в последних версиях JS.
Далее я подробно рассмотрю логику каждого из фильтров и приведу их код, который я написал.
В первую очередь я настроил пересылку сообщений из Telegram в Twitter и Friendica. Здесь всё довольно просто. Добавление невидимого символа и обрезка длинного сообщения после слова, а не посреди слова, о чём я говорил выше.
Если сообщение достаточно короткое, то я не хочу раздражать читателей в Twitter ссылкой на оригинал сообщения в Telegram, поэтому просто пересылаю сообщение. Если же сообщение не помещается в лимит 280 символов, то тогда уже обрезаю текст до лимита в 255 символов и далее размещаю ссылку на оригинал сообщения в Telegram.
В начале идёт ещё один хак для сообщений, состоящих только из ссылки без текста. Просто невидимый символ перед такими ссылками нельзя добавить, потому что Telegram его удалит, поэтому сначала перед первой ссылкой добавляю невидимый символ и пробел, а затем заменяю комбинацию «невидимый символ-пробел» на «невидимый символ-пробел», чтобы не было двух пробелов, если перед ссылкой был какой-то текст.
Далее идёт пересылка фотографий из Telegram в Twitter и Friendica. IFTTT не очень хорошо работает с альбомами. Каждая фотография из альбома будет отправлена отдельным сообщением, а комментарий к альбому будет добавлен только к первому изображению. Пока что приходится помнить, чтобы не публиковать альбомы в канале Telegram, и внимательнее присматриваться к n8n. Хотя с помощью дополнительного запроса к Telegram можно реализовать игнорирование остальных изображений в альбоме. Но хотелось бы иметь возможность отправлять альбомы в другие места, хотя и не очень сильно — не часто это требуется.
При отправке изображения в Twitter нужно учитывать, что само изображение также станет ссылкой, поэтому лимиты на текст уменьшаются до 255 и 230 соответственно. В остальном вся логика та же, меняются только названия атрибутов.
Основные сложности возникают при пересылке новых твитов в другие места. IFTTT не может сразу отреагировать на появление нового твита и просто проводит регулярную проверку каждые 5 минут.
Сначала я выделяю текст из твита, который идет по первой ссылке, а затем сравниваю этот текст с началами последних сообщений и описаний фотографий, которые есть в канале Telegram. Если сообщения в Telegram начинаются с текста твита, то пересылка такого сообщения прекращается. В моём случае эта логика не имеет смысла, так как я использую хак с невидимым символом, но я её уже написал и жалко удалять, а здесь она тем более может кому-то пригодиться.
Плюсом IFTTT является то, что система учитывает твиты, которые я отправил сам себе в ответ, когда создаю цепочку твитов в треде. Некоторые системы, например Friendica, такие твиты игнорируют. Поэтому пришлось отключить в Friendica автоматическое считывание твитов и публиковать их через IFTTT, так как Friendica теряет все твиты, написанные в ответ самому себе. При этом ретвиты Friendica отображает очень хорошо, а IFTTT не может делать такие ретвиты, так как считывает недостаточно данных об авторе твита, который ретвитишь.
Пришлось сделать дополнительный хак в Friendica. Там включил чтение и копирование твитов и ретвитов из Twitter, а в самом коде добавил возвращение из метода, который должен обрабатывать твиты, написанные мной самим. Таким образом, у меня Friendica теперь сама дублирует ретвиты из Twitter, а в IFTTT в фильтре я запретил отправлять ретвиты в Friendica. Правильнее было бы разобраться более подробно в плагине, взаимодействующем с Twitter в Friendica, и добавить настройки, но это отнимает время, поэтому я просто добавил одну строку в код, и теперь метод, который должен копировать не ретвиты из Twitter, не срабатывает. Возможно, в будущем сделаю как надо.
Жаль, что Friendica не умеет обрабатывать комментарии к ретвитам: она берёт только твит с комментарием, а не обрабатывает тот ретвит, который комментируется. Комментарий без того, что комментируется, обычно не имеет смысла. Пока что приходится помнить и мириться с тем, что ретвиты ретвитов-комментариев поступают в Friendica без основного содержания.
Далее в IFTTT-фильтре после проверки на ретвит следует проверка на наличие невидимого символа, и если он есть, то отменяю отправку в Telegram и Friendica. И в самом конце для Telegram заменяю символы новой строки на соответствующий HTML-тег, так как Telegram игнорирует символы новой строки и для форматирования сообщений через API требует HTML-разметку.
С Instagram свои сложности, хотя в то же время и проще, потому что из него нужно только считывать новые фотографии и не нужно в него ничего отправлять. Отправка фото в Instagram — это кропотливый процесс, где нужно соответствующим образом отредактировать фотографию и подобрать хэштеги. Вот в этом и заключается сложность.
В Instagram нужно добавлять много тегов, чтобы фотографию могли найти и увидеть другие пользователи, которые не подписаны на тебя. Хотя некоторые скажут, что теги, наоборот, не нужно добавлять, чтобы публикация автоматически показывалась другим, но алгоритмы Instagram постоянно меняются, а я привык добавлять теги к каждому фото.
Только в Instagram теги — это норма, к ним там привыкли, и часть из них имеет смысл только в Instagram. А вот в других местах такое количество хештегов будет раздражать. В Twitter вообще есть ограничение на длину сообщения, и туда столько не отправишь, а в Telegram и Friendica я просто не хочу видеть все эти теги и не хочу их показывать другим.
Поэтому сначала в фильтре нахожу первый хэштег и оставляю только текст к нему. Логика аналогична тому, как я удалял текст перед первой ссылкой при отправке из Twitter. После текста всегда с новой строки добавляю ссылку на оригинальную публикацию в Instagram, потому что я не против новых подписчиков там.
При ограничении длины сообщения для Twitter использую ограничение в 230 символов, так как твит всегда будет содержать сокращённую ссылку на Instagram и на саму фотографию в Twitter.
Поскольку текст меняется и не отсылается оригинал, то для Friendica приходится заново задавать и составлять весь текст для web-запроса.
Недавно я начал записывать подкаст с обзорами эпизодов телесериалов. И решил также автоматизировать публикацию ссылок на новые эпизоды в соцсетях. В случае с Telegram — публикация всего mp3-файла с выпуском, так как у IFTTT есть функция отправки mp3 в Telegram.
И вот здесь IFTTT снова меня разочаровал, потому что оказалось, что сервис не считывает XML-тег enclosure из RSS-канала подкаста, а именно этот тег содержит ссылку на mp3-файл. Быстро нашла в Google совет, что можно считывать RSS через Zapier, а из него уже отправлять web-запрос в IFTTT. Но сейчас веб-хуки в Zapier доступны только в платных тарифах, и с бесплатного тарифа такие запросы сделать невозможно.
О проблеме написал в службу поддержки IFTTT и попросил их добавить возможность считывать содержимое тега enclosure. Ответили, что передали просьбу разработчикам. Теперь посмотрим, появится ли у них когда-нибудь возможность получать ссылку на файл из RSS без сбоев.
После недолгих раздумий я додумался сделать через Zapier генерацию нового RSS, который уже обрабатываю в IFTTT. Zapier считывает RSS-канал подкаста и, при наличии нового эпизода, добавляет его в свой RSS-канал, при этом вместо ссылки на эпизод появляется ссылка на mp3-файл, вместо заголовка — ссылка на эпизод, а вместо автора — уже заголовок.
Ссылка на mp3 довольно длинная и сложная, поэтому не уверен, что она не испортится, если её вписать в поле заголовка, а вот ссылка на эпизод довольно короткая, и с ней в заголовке ничего не случится. Автором подкаста всегда являюсь я, информация в этом поле мне не нужна, а вот заголовок не помешает при публикации в Friendica.
Сами заголовки эпизодов в соцсеть не отправляю, так как там указаны только название сериала и номер его эпизода, по которым подкаст находят в различных сервисах прослушивания подкастов. Нет смысла пересылать текст заголовков в соцсети.
А вот текст из описания уже есть, потому что там своими словами я пишу, о чём выпуск подкаста, но после описания идут стандартные ссылки, которые нужно показать тем, кто слушает подкаст в сервисах прослушивания. Эти ссылки в соцсетях уже не нужно публиковать, потому что в соцсетях я и так размещаю ссылку на выпуск, по которой можно перейти к выпуску с полным описанием, включающим эти ссылки.
Поэтому сначала разбиваю текст на строки и отбираю все строки до первой строки, содержащей ссылку. Затем соединяю строки с помощью символа новой строки, а для Telegram — соответствующим HTML-тегом. Здесь ещё нужно следить, чтобы в описании эпизода подкаста не было других HTML-тегов, кроме <br>, а то в Friendica передаётся экранированный текст, и теги превращаются в текст.
Для Friendica снова приходится переписывать весь текст веб-хука, так как отправляется не оригинальный текст. Стоит отметить, что в Friendica из переданной ссылки на эпизод подкаста создается публикация с вложением, в которое автоматически подтягивается embed-код из ссылки на сервис Anchor, где я размещаю подкаст, и у себя уже отображает web-плеер, в котором можно прослушивать подкаст без перехода по ссылке.
Для подкаста ещё создал отдельную страницу в Facebook и публикую на ней посты с описанием и ссылкой на эпизод подкаста. Facebook не позволяет автоматическую публикацию в личный профиль, да и я не сижу в этой сети, поэтому в предыдущих апплетах никак не взаимодействовал с ней.
Результаты работы этих автоматизированных систем можно увидеть по ссылкам, приведенным ниже.
Twitter: https://twitter.com/Abysim
Telegram-канал: https://t.me/AbysimFeed
Instagram: https://www.instagram.com/abysim.whitelion/
Friendica: https://whitelion.me
Подкаст на Anchor: https://anchor.fm/abysim
Страница подкаста в Facebook: https://www.facebook.com/serialni.dumky