Skip to content

Instantly share code, notes, and snippets.

@ammarfaizi2
Last active September 14, 2018 17:18
Show Gist options
  • Save ammarfaizi2/b2b1ad4f5d18ab28834ba42e7b03256e to your computer and use it in GitHub Desktop.
Save ammarfaizi2/b2b1ad4f5d18ab28834ba42e7b03256e to your computer and use it in GitHub Desktop.
<?php
/**
* @author Ammar Faizi <[email protected]>
* @license MIT
*
* --- Simple Telegram Bot ---
*/
date_default_timezone_set("Asia/Jakarta");
define("IS_WEBHOOK", false);
define("BOT_TOKEN", "...bot_token...");
is_dir(__DIR__."/bot_data") or mkdir(__DIR__."/bot_data");
is_dir(__DIR__."/bot_data/cache") or mkdir(__DIR__."/bot_data/cache");
function cmlog($format, ...$params)
{
printf("[%s] %s\n",
date("Y-m-d H:i:s"),
sprintf($format, ...$params)
);
}
if (!is_dir(__DIR__."/bot_data")) {
cmlog("%s", "Could not create bot_data directory");
exit(1);
}
if (!is_dir(__DIR__."/bot_data/cache")) {
cmlog("%s", "Could not create bot_data/cache directory");
exit(1);
}
class Exe {
public static function __callStatic($method, $parameters)
{
if (isset($parameters[0])) {
$opt = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($parameters[0]),
CURLOPT_HTTPHEADER => ["Content-Type: application/json"]
];
} else {
$opt = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false
];
}
$ch = curl_init("https://api.telegram.org/bot".BOT_TOKEN."/{$method}");
curl_setopt_array($ch, $opt);
$out = curl_exec($ch);
curl_close($ch);
return $out;
}
}
class Cmd {
public static function start($v)
{
return Exe::sendMessage(
[
"chat_id" => $v["message"]["chat"]["id"],
"reply_to_message_id" => $v["message"]["message_id"],
"parse_mode" => "HTML",
"text" =>
"<b>Pilihan:</b>\n".
"/keyboard\n".
"/callback\n"
]
);
}
public static function unknown($v)
{
return Exe::sendMessage(
[
"chat_id" => $v["message"]["chat"]["id"],
"reply_to_message_id" => $v["message"]["message_id"],
"parse_mode" => "HTML",
"text" => "Perintah tidak dikenal!\nKetik /start atau /help untuk menampilkan menu!"
]
);
}
public static function keyboard($v)
{
return Exe::sendMessage(
[
"chat_id" => $v["message"]["chat"]["id"],
"reply_to_message_id" => $v["message"]["message_id"],
"parse_mode" => "HTML",
"text" =>
"<b>Pilihan Keyboard:</b>\n".
"<code>1. !k ABC</code>\n".
"<code>2. !k DEF</code>\n".
"<code>3. !k GHI</code>\n".
"<code>4. !k JKL</code>\n\n".
"<b>Clean keyboard:</b> /keyboard_clean"
]
);
}
public static function keyboardClean($v)
{
if (file_exists(__DIR__."/bot_data/cache/available_keyboards")) {
if (!unlink(__DIR__."/bot_data/cache/available_keyboards")) {
cmlog("Could not clean the keyboard!");
exit(1);
}
return Exe::sendMessage(
[
"chat_id" => $v["message"]["chat"]["id"],
"reply_to_message_id" => $v["message"]["message_id"],
"text" => "Keyboard has been cleaned!",
"reply_markup" => [
"remove_keyboard" => true
]
]
);
} else {
return Exe::sendMessage(
[
"chat_id" => $v["message"]["chat"]["id"],
"reply_to_message_id" => $v["message"]["message_id"],
"text" => "There is no keyboard to be removed!",
"reply_markup" => [
"remove_keyboard" => true
]
]
);
}
}
public static function pressKeyboard($v, $key)
{
$key = strtoupper($key);
return Exe::sendMessage(
[
"chat_id" => $v["message"]["chat"]["id"],
"reply_to_message_id" => $v["message"]["message_id"],
"text" => "Keyboard {$key} was pressed!"
]
);
}
public static function addKeyboard($v, $key)
{
$key = strtoupper($key);
if (file_exists(__DIR__."/bot_data/cache/available_keyboards")) {
$keyboards = [[]];
$available_keyboards = json_decode(file_get_contents(__DIR__."/bot_data/cache/available_keyboards"), true);
if (is_array($available_keyboards)) {
$available_keyboards[] = $key;
$available_keyboards = array_unique($available_keyboards);
foreach ($available_keyboards as $keyvv => $vv) {
$keyboards[0][] = [
"text" => "{$vv}"
];
}
file_put_contents(__DIR__."/bot_data/cache/available_keyboards", json_encode($available_keyboards));
} else {
$keyboards = [[["text" => "{$key}"]]];
file_put_contents(__DIR__."/bot_data/cache/available_keyboards", json_encode([$key]));
}
} else {
$keyboards = [[["text" => "{$key}"]]];
file_put_contents(__DIR__."/bot_data/cache/available_keyboards", json_encode([$key]));
}
return Exe::sendMessage(
[
"chat_id" => $v["message"]["chat"]["id"],
"reply_to_message_id" => $v["message"]["message_id"],
"parse_mode" => "HTML",
"text" => "{$key} keyboard has been created!",
"reply_markup" => [
"keyboard" => $keyboards
]
]
);
}
public static function callbackMe($v)
{
return Exe::sendMessage(
[
"chat_id" => $v["message"]["chat"]["id"],
"reply_to_message_id" => $v["message"]["message_id"],
"parse_mode" => "HTML",
"text" => "Inline keyboard with callback data has been created successfully!",
"reply_markup" => [
"inline_keyboard" => [
[
[
"text" => "Callback Data 1",
"callback_data" => "callback:1"
],
[
"text" => "Callback Data 2",
"callback_data" => "callback:2"
]
]
]
]
]
);
}
public static function callbackHandler($callback_data, $v)
{
return Exe::sendMessage(
[
"chat_id" => $v["callback_query"]["message"]["chat"]["id"],
"reply_to_message_id" => $v["callback_query"]["message"]["message_id"],
"parse_mode" => "HTML",
"text" => "<b>Got callback_data from inline button:</b>\n".htmlspecialchars($callback_data, ENT_QUOTES, "UTF-8")
]
);
}
}
function process($v)
{
if (isset($v["message"]["text"])) {
if (preg_match("/^(?:\/)([a-z\_]*)$/Usi", $v["message"]["text"], $m)) {
$cmd = strtolower($m[1]);
switch ($cmd) {
case "start":
case "help":
Cmd::start($v);
break;
case "keyboard":
Cmd::keyboard($v);
break;
case "keyboard_clean":
Cmd::keyboardClean($v);
break;
case "callback":
Cmd::callbackMe($v);
break;
default:
Cmd::unknown($v);
break;
}
return;
} elseif (preg_match("/^(?:\!k\s)([a-z\_]*)$/Usi", $v["message"]["text"], $m)) {
$key = strtolower($m[1]);
switch ($key) {
case "abc":
Cmd::addKeyboard($v, "abc");
break;
case "def":
Cmd::addKeyboard($v, "def");
break;
case "ghi":
Cmd::addKeyboard($v, "ghi");
break;
case "jkl":
Cmd::addKeyboard($v, "jkl");
break;
default:
Cmd::unknown($v);
break;
}
return;
} elseif (in_array(strtolower($v["message"]["text"]), ["abc", "def", "ghi", "jkl"])) {
Cmd::pressKeyboard($v, strtoupper($v["message"]["text"]));
return;
}
Cmd::unknown($v);
} elseif (isset($v["callback_query"])) {
if (isset(
$v["callback_query"]["data"],
$v["callback_query"]["message"]["message_id"],
$v["callback_query"]["message"]["chat"]["id"]
)) {
$callback_data = $v["callback_query"]["data"];
Cmd::callbackHandler($callback_data, $v);
} else {
cmlog("Unknown callback format");
}
}
}
function cleanUpdate()
{
print Exe::{"getUpdates?offset=-1"}();
}
function handleUpdate() {
if (defined("IS_WEBHOOK") && IS_WEBHOOK) {
header("Content-Type: application/json");
http_response_code(200);
flush();
process(file_get_contents("php://input"));
exit(0);
}
if (file_exists(__DIR__."/bot_data/cache/latest_update_id")) {
$latestUpdateId = (int)file_get_contents(__DIR__."/bot_data/cache/latest_update_id");
} else {
$latestUpdateId = 0;
}
cmlog("Getting update from telegram...");
$updates = json_decode(Exe::getUpdates(), true);
$countAllResult = count($updates["result"]);
cmlog("Filtering updates...");
foreach ($updates["result"] as $key => $v) {
if ($v["update_id"] <= $latestUpdateId) {
unset($updates["result"][$key]);
}
}
$countResult = count($updates["result"]);
cmlog("Got %d new update(s)", $countResult);
foreach ($updates["result"] as $key => $v) {
cmlog("Processing update_id \"%d\"...", $v["update_id"]);
process($v);
}
if (isset($v["update_id"])) {
$latestUpdateId = $v["update_id"];
}
if ($countAllResult > 50) {
cmlog("Cleaning updates...");
cleanUpdate();
}
file_put_contents(__DIR__."/bot_data/cache/latest_update_id", $latestUpdateId, LOCK_EX);
}
while (1) {
handleUpdate();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment