Categories
Tech

Sync Tweets to a Telegram Channel Using Account Activity API

Yet another post that has something to do with Telegram. Yeah, I know, but there’s never such thing as too much when you talk about blog articles.

A lot of people around my Telegram circle has been maintaining their own channels, and a lot of them has had a few hundreds or even thousands of subscribers. I think that I may make one too, but I also don’t want to give up with my Twitter account which is more accessible to search engines. So why not sync my tweets to the channel? Given the openness of both Telegram and Twitter, this shouldn’t be much of an issue.

The first option I turned to is, of course, IFTTT. It is one of the most famous solution for casual automation. I have also used it in another script. The problem of IFTTT is that the option it provides is too simple. There is no text transformation, no condition and no everything I would need for an ideal forwarder. It even drops line breaks when quoting the tweet content.

Soon after I got time, I replaced the IFTTT bot with my own one for a better presentation and granular control over it.

The bot

Setting up a Telegram bot for this purpose isn’t hard, especially when it doesn’t require any input. In fact you can even reuse bot that you already have for this (which is what I was doing).

Add the bot to a channel as admin, get the ID/username of the channel, and you are good to go.

The hard part is to create a Twitter app to use the Account Activity API. You have to fill a quite lengthy survey telling them why you want to make an app and how are you going to use the API. Only after they have approved your request, then you can proceed to the next step.

Note that Twitter has been pretty strict on the quota of the Account Activity API ever since they have moved from the Streaming API (which has broken most third-party clients). You can’t share your API key and secret to more than 15 accounts if you are on the Sandbox (free) plan, or you may be asked to pay for the bill.

Also, since the new Account Activity API is webhook-like, that means you have to figure out, in one way or another, to expose your bot as an HTTP entry point. I used my existing Nginx web server to forward request to the bot. Other methods should also work.

I am using a Python library called Twitivity which provides a simple Flask web server and some helper functions, PickleDB for simple file-based key-value storage, and Python Telegram Bot for the bot.

Setup environment

Once you have set up your Twitter App, you can go to the Dev Environments page to create an environment for your Account Activity API. The environment label (e.g. env_name) will be used later in the code.

If you are running the bot on your own account, go to your app page and choose “Keys and tokens”. From there you can get your API key/token and access key/token in one go. For users other than yourself, you need to setup authentication manually to get the tokens.

When you have these tokens ready, you can then register your webhook with Twitter.

Python source to register webhook with Twitter.

Once the webhook is registered, you can copy over the config to the actual bot file, and start it up. Since it runs flask in the background, you can actually use all the fancy uWSGI and Gunicorn stuff to maintain the bot, but a simple flask dev server should suffice if you don’t tweet 100 times per second.

The bot script

As you might have seen above, the bot itself has quite a complicated logic. The bot would identify the nature of a tweet and treat each kind of tweet differently.

  • For plain tweets, the bot would expand all shortened links back as the length limit here isn’t that strict. Link preview will only be enabled if a link is found in the tweet.
  • For tweets with media, the bot will send them as picture/video (or media group) messages. Thank to the fact that Telegram Bot API accepts external media URL, we don’t need to download and upload again.
  • For retweets with comments, only the comment is copied over.
  • For likes and plain comments, the original tweet is only shown as link preview.
  • Every message sent has links to the original tweet, and the source tweet too if its a like or retweet. (The links are on the emoji at the end of the messages.)
  • If the tweet is a reply to something that we already have, it will reply to the previous message in the channel.

Some screenshots here:

A plain tweet
A plain tweet.
A retweet
A retweet
A retweet with comment
A retweet with comment
A liked tweet
A liked tweet
A plain tweet with a picture
A plain tweet with a picture
A plain tweet with multiple pictures.
A plain tweet with multiple pictures.

Update 30 Mar 2020: I have made another version of this script for Mastodon instances as well. The Mastodon version relies on the WebSocket Streaming API which is much easier to set up than the one for Twitter. You only need to go to your Mastodon instance, create an app, and get your access token. By default, the application management page is at https://example.com/settings/applications. Once you got your access token and everything on the Telegram side, you can simply download this script, modify the configs accordingly, and run it 24/7 wherever you want.

Note that there are some caveats on the Mastodon side. As the home stream is not designed to monitor the activity of one specific account, it means that:

  • No favorites can be captured, and
  • Boosts can only be found sometimes.

Everything else should work similar to the one for Twitter, except that it’s now an elephant (🐘) instead of a (🐦).


Last but not least, don’t forget to follow me on Twitter, Mastodon, and Telegram 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

*