Post Tweets To Public Telegram Channel



Lets Create A Bot That Posts To A Public Telegram Channel From Twitter

Do you want tweets to go to Telegram automagically? Do you really want to do it in PHP?

Requirements

Lets gather all the resources we need to build this bot...

Composer
Install PHP requirements with composer. If you don't have composer installed you can find all the info you need to get started here: https://getcomposer.org/

Install the Twitter helper class.

composer require j7mbo/twitter-api-php

And Requests for PHP.

composer require rmccue/requests

Twitter

  1. Go to https://developer.twitter.com/apps and create a new app.
  2. Get your your keys and tokens.

Telegram

  1. We'll need an API key from Telegram. Open up Telegram and go see @BotFather, create a new bot and get your key.
  2. We also need to add the bot to the channel as an Administrator.
  3. And get the channel name you want to post to (e.g. @your_channel_name).

Reading From Twitter Timeline

Enter your keys, tokens, username, change the other parameters if you like and then run it (php read_twitter.php). If all goes well you should see a list of tweets. It should replace all short t.co urls with the full expanded url and remove all hashtags.

read_twitter.php

<?php
require_once(__DIR__ . "/vendor/autoload.php");

$twitter_api = new TwitterAPIExchange([
    "consumer_key" => "XXXX",
    "consumer_secret" => "XXXX",
    "oauth_access_token" => "XXXX",
    "oauth_access_token_secret" => "XXXX"
]);

$twitter_username = "XXXX";
$include_retweets = 0;
$exclude_replies = 1;
$tweet_count = 20;
$url = "https://api.twitter.com/1.1/statuses/user_timeline.json";
$params = "?screen_name=$twitter_username&tweet_mode=extended&include_rts=$include_retweets&exclude_replies=$exclude_replies&count=$tweet_count";

$response = $twitter_api->setGetfield($params)->buildOauth($url, "GET")->performRequest();
$tweets = json_decode($response);

foreach ($tweets as $tweet) {
    $tweet_id = $tweet->id_str;
    $text = $tweet->full_text;

    foreach ($tweet->entities->urls as $url) {
        $text = str_replace($url->url, $url->expanded_url, $text);
    }

    foreach ($tweet->entities->hashtags as $hashtag) {
        $text = str_replace("#" . $hashtag->text, "", $text);
    }

    echo $tweet_id . "\n";
    echo $text . "\n";
}

More info on the user_timeline endpoint here: https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-user_timeline

Posting To Public Telegram Channel

Enter your API key, channel name (include @ prefix), your message and run it (php write_telegram.php). If all goes well you should see a 1 and a new message in your channel.

write_telegram.php

<?php
require_once(__DIR__ . "/vendor/autoload.php");

$telegram_api_key = "XXXX";
$telegram_chat_id = "@XXXX";
$telegram_message = "XXXX";
$response = Requests::get("https://api.telegram.org/bot$telegram_api_key/sendMessage?chat_id=$telegram_chat_id&text=$telegram_message");

Using A Simple SQLite Database To Avoid Repeats

We need a way to avoid repeats so lets use an SQLite database to store the tweet IDs.

database.php

$pdo = new PDO("sqlite:" . __DIR__ . "/database.db");
$pdo->exec("CREATE TABLE IF NOT EXISTS tweets(id INTEGER PRIMARY KEY, tweet_id TEXT UNIQUE)");

$tweet_id = "TEST";
$sql = "INSERT INTO tweets (tweet_id) VALUES (:tweet_id)";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(":tweet_id", $tweet_id, PDO::PARAM_STR);

if ($stmt->execute()) {
    echo "Added $tweet_id to db\n";
} else {
    echo "$tweet_id already exists in db\n";
}

This will create a file called database.db, which will hold the table data. A table called tweets with a will be created if not already.
It then inserts a new row if the tweet_id does not exist in the database.
Give it a whirl (php database.php).

Wrapping it all up

Lets jam it all together so it posts some tweets...

<?php
require_once(__DIR__ . "/vendor/autoload.php");

$pdo = new PDO("sqlite:" . __DIR__ . "/database.db");
$pdo->exec("CREATE TABLE IF NOT EXISTS tweets(id INTEGER PRIMARY KEY, tweet_id TEXT UNIQUE)");

$telegram_api_key = "XXXX";
$telegram_chat_id = "@XXXX";

$twitter_api = new TwitterAPIExchange([
    "consumer_key" => "XXXX",
    "consumer_secret" => "XXXX",
    "oauth_access_token" => "XXXX",
    "oauth_access_token_secret" => "XXXX"
]);

$twitter_username = "XXXX";
$include_retweets = 0;
$exclude_replies = 1;
$tweet_count = 10;
$twitter_base_url = "https://api.twitter.com/1.1/statuses/user_timeline.json";
$params = "?screen_name=$twitter_username&tweet_mode=extended&include_rts=$include_retweets&exclude_replies=$exclude_replies&count=$tweet_count";

$response = $twitter_api->setGetfield($params)->buildOauth($twitter_base_url, "GET")->performRequest();
$tweets = json_decode($response);

foreach ($tweets as $tweet) {
    $tweet_id = $tweet->id_str;
    $text = $tweet->full_text;

    foreach ($tweet->entities->urls as $url) {
        $text = str_replace($url->url, $url->expanded_url, $text);
    }

    foreach ($tweet->entities->hashtags as $hashtag) {
        $text = str_replace("#" . $hashtag->text, "", $text);
    }

    $sql = "INSERT INTO tweets (tweet_id) VALUES (:tweet_id)";
    $stmt = $pdo->prepare($sql);
    $stmt->bindParam(":tweet_id", $tweet_id, PDO::PARAM_STR);

    if ($stmt->execute()) {
        $response = Requests::get("https://api.telegram.org/bot$telegram_api_key/sendMessage?chat_id=$telegram_chat_id&text=$text");
        if ($response->success) {
            echo "$tweet_id added to db\n";
        } else {
            echo "Telegram fail\n";
        }
    } else {
        echo "$tweet_id already exists in db\n";
    }
}

By no means is this production ready. It's just a simple example to get you started. Have fun!

Thanks for reading. x

Resources