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
- Go to https://developer.twitter.com/apps and create a new app.
- Get your your keys and tokens.
Telegram
- We'll need an API key from Telegram. Open up Telegram and go see
@BotFather
, create a new bot and get your key. - We also need to add the bot to the channel as an Administrator.
- 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
- Composer: https://getcomposer.org/
- Twitter API Class: https://github.com/J7mbo/twitter-api-php/
- Telegram: https://core.telegram.org/bots
- SQLite: https://www.sqlite.org/
- PDO: https://www.php.net/manual/en/book.pdo.php/