Project

General

Profile

Actions

Feature #3146

open

Homework for Lesson 1: Set up Telegram Bot PHP WebHook

Added by Gregory Magarshak 9 months ago. Updated 9 months ago.

Status:
New
Priority:
High
Start date:
08/28/2024
Due date:
08/29/2024 (about 9 months late)
% Done:

0%

Estimated time:
4.00 h

Description

Welcome to your first homework. I am not just teaching you Telegram and giving you random homework, I will be giving you mini-projects so at the end of this course / sprint, you'll have a re-usable framework inside Qbix that you can re-use for many projects, and also have access to the full power of the Qbix platform at the same time :)

The lesson, code samples and related links can be found at https://issues.qbix.com/projects/telegram/wiki

Feel free to refer to that wiki, it will grow.

Information / Discussion

Read this: https://issues.qbix.com/projects/telegram/wiki/Telegram_Plugin

Set up Telegram Bot WebHook in PHP

For now, just practice setting up a web-server which is accessible from the internet. You have a couple options to make your local computer accessible from the Internet:

1) Dynamic DNS from https://www.duckdns.org/

2) SSH Tunnel simply mapping a remote port to a port on your machine, then have your NGinx listen on that port: https://serverfault.com/questions/1004529/access-an-http-server-as-localhost-from-an-external-pc-over-ssh

Anyway, practice calling setWebhook method from PHP installer script.

https://core.telegram.org/bots/api#setwebhook

You shouldn't use HTTP (port 80) but rather HTTPS (port 443). Please generate a self-signed certificate, and Post it to setWebhook(): https://core.telegram.org/bots/self-signed and https://stackoverflow.com/a/44550366

Also please generate and send secret_token along, which will send along a header X-Telegram-Bot-Api-Secret-Token with each request.

Registering webhook

Add a hook plugins/Telegram/handlers/after/Q_Plugin_install.php analogous to what we already have in Users_after_Q_Plugin_install or Streams_after_Q_Plugin_install

This hook will run whenever installer runs. It will

$extra = Q_Plugin::extra('Telegram', 'plugin', 'Users');
$apps = Q_Config::get('Users', 'apps', 'telegram', array());
foreach ($apps as $app) {
    if (!empty($extra[$app])) {
       continue; // already installed for this app
    }
    $extra[$app] = array('setWebhook' => true);
    $extra = Q_Plugin::extra('Telegram', 'plugin', 'Users', $extra);
    $token = Q::ifset($app, 'token', null);
    $secret = Q::ifset($app, 'secret', Q_Config::get('Q', 'internal', 'secret', ''));
    if (!$token) continue;
    $cert = Q::ifset($app, 'cert', null);
    if ($certfile) {
       $certificate(file_get_contents($cert));
    }
    $url = Q_Request::baseUrl('telegram.php');
    $secret_token = "$app\t$secret"; // will come in header X-Telegram-Bot-Api-Secret-Token
    $result = Telegram_Bot::setWebhook(@compact('token', 'url', 'certificate', 'secret_token'));
    if ($result['error']) {
       throw new Telegram_Exception_Webhook(@compact('app', 'url', 'token', 'certificate'));
    }
}

So now it registers webhooks that will call the controller telegram.php

Handling updates

Make telegram.php controller call Telegram_Dispatcher::dispatch($update) method when a request comes from a telegram bot.

It's similar to how index.php controller calls Q_Dispatcher::dispatch($uri) when a web request comes in from a browser, but the dispatcher will be much simpler.

Telegram_Dispatcher::dispatch($update) should look at header('X-Telegram-Bot-Api-Secret-Token') and $parts = explode("\t", $header) to determine $appId = reset($parts). Now do $params = compact('appId', 'update'). And call Q::event("Telegram/update", $params) similar to how Q_Dispatcher calls Q::event("Q/response").

The handler of Telegram/update" event, in turn, would determine the update type (from a growing list of types such as "message" and "edited_message"), and then fire Q::event("Telegram/update/$appId/$updatetype)", $params similar to how Q/response handler fires event "$module/$action/response/$slotname.

So now, different plugins would be able to add handlers for these events. Suppose I had an app / bot on telegram with appId = "MyCoolBot" and internal appId "Calendars". Then as a developer of "Calendars" plugin module, I would implement events such as:

  • Telegram/update/Calendars/message
  • Telegram/update/Calendars/edited_message
  • Telegram/update/Calendars/callback_query

Artem can help you manually test at least these 3, by using the inline keyboard code from our lesson

Implementing the actual bots

Plugins will be able to implement any kind of complex logic to interact with a user. They might use AI plugin with ChatGPT. They might query a database. They will probably store a context for each user, of what they remember about this user and conversation with him. But for now, we don't care what the plugins will do. We just built the support for them: installer, addWebhook, and handlers.

For the end of this homework, I'd ask you to use Telegram_Bot::sendVideo() method that Artem will implement. I mean, it's a simple method, that you can implement too. But I gave it to Artem to practice calling sendVideo, sendDocument, etc.

Actions #1

Updated by Gregory Magarshak 9 months ago

  • Description updated (diff)
Actions #2

Updated by Gregory Magarshak 9 months ago

  • Description updated (diff)
Actions #3

Updated by Gregory Magarshak 9 months ago

  • Description updated (diff)
Actions

Also available in: Atom PDF