rmed

blog

Bridge? wat-bridge?

2016-10-13 17:27

Instant messaging services are very common nowadays. For instance, I use Telegram, while many people I know use WhatsApp, and that's cool. This, however, leads to a question I am asked often: "why don't you install WhatsApp?". The answer to that can be summarized in two main points: "because I don't want to" and "because I cannot install WhatsApp on my phone". But then again, it is interesting to see the user fragmentation between different services, so the Telegram bot API got me thinking about creating a "bridge" between WhatsApp and Telegram, just for fun.

TL;DR: source code available at https://github.com/rmed/wat-bridge

Architecture

The architecture that wat-bridge follows is actually very simple. It consists of two main components, the WhatsApp listener and the Telegram listener/bot (in the figure, wabot and tgbot respectively, that are executed in separate threads and communicate through signals, relaying messages from one service to the other.

Architecture overview

This architecture is designed to work with one-to-one conversations and has the following flow:

  1. Friend-A sends message from WhatsApp
  2. wabot receives message and sends it to tgbot
  3. tgbot receives the signal and sends the message to the owner of the bot
  4. The owner of the bot reads the message and replies through the bot using defined commands
  5. tgbot receives message and sends it to wabot
  6. wabot receives the signal and sends the message to the specified contact/phone

Note that among those steps some checks are performed, for instance whether the phone that sent the message from WhatsApp is a known contact or is blacklisted.

The Telegram bot uses the pyTelegramBotAPI library, while the WhatsApp listener uses the Yowsup library. In addition, I have included a simple database using TinyDB in order to keep contacts and blacklisted phone numbers.

Configuration

In order to keep things simple, wat-bridge uses a configuration file with the following structure:

[tg]
owner = OWNER_ID
token = TOKEN

[wa]
phone = PHONE_NUMBER
password = PASSWORD

[db]
path = PATH_TO_DB

The Telegram token is obtained by talking to the BotFather through Telegram and creating a bot, while the owner ID can be obtained by using the /me command.

The WhatsApp phone must include the country code (only two digits) followed by the number, for instance 49xxxxxxxxx, and the password can be obtained through the Yowsup cli interface.

Lastly, the database path is the full path to the file that will contain blacklist and contacts. Note that this path should be readable/writable by the user that executes the application.

Commands

The commands available in the Telegram bot are very straightforward:

  • /help: shows a help message (incredible, right?)
  • /add <name> <phone>: adds a new phone to the database, assigning a name to it
  • /blacklist: shows blacklisted Whatsapp phones
  • /blacklist <phone>: blacklists a WhatsApp phone number
  • /contacts: list stored contacts
  • /me: obtain owner Telegram ID
  • /rm <name>: remove a contact from database
  • /send <name> <message>: send message to Whatsapp contact
  • /unblacklist <phone>: unblacklist a phone number

In case anyone is wondering why contacts are used/needed to send messages to WhatsApp... I'm just too lazy to write phone numbers every time :) Furthermore, the database is configured to use query cache, so looking up phone numbers or contact names should not be much of a bottleneck.

Messages from blacklisted phones are directly ignored upon arrival. Surely this can come in handy, right?

Conclusions

The resulting code is not beautiful whatsoever, but it works, which I actually didn't expect, to be honest. It is a fun little toy project to play around with, but I don't think it should be used in a production environment or for serious business.

Also, as a reminder, this requires a real WhatsApp phone number. I registered my second SIM card to play, but I don't think I will use it that much.

Source code is released under MIT license and available at https://github.com/rmed/wat-bridge.