Bot-ChatBots-Telegram

 view release on metacpan or  search on metacpan

lib/Bot/ChatBots/Telegram/Guide/Tutorial.pod  view on Meta::CPAN

As you can see, it's mostly the same as the longpoll one, except that in
this case the initial message C<1> is sent from Telegram. Additionally, as
we already discovered, it's possible to use the sender outside of an
update.


=head2 WebHooks Are Fussy

One thing is to decide when to get Updates using a client, possibly behind
a proxy; another thing is to set up a service that acts as the contact
point for Telegram. The road to be a I<server> that Telegram is fine about
has a few milestones, as you will see in the following subsections.

Telegram will need a URL to contact you:

   $ export BOT_URL="$BOT_PROTO://$BOT_ADDRESS:$BOT_PORT$BOT_PATH"

Before you can C<export> this... you have to decide a few things!

=head3 Find a public spot and set C<BOT_ADDRESS>

While your program will I<still> act as a client to Telegram, it now also
becomes a I<server>. This means finding out a suitable, public spot on the
internet; it might be your home computer with a public IP address, a VPS,
or a free-tier AWS virtual machine if you're lucky to have some capacity.

You might even go the extra mile and set up a DNS resolution to transform
a I<domain name> into that IP address; Telegram will not insist on this
anyway.

In the following, we will assume that you know your (public) IP Address:

   $ export BOT_ADDRESS='...'

=head3 Decide a port and set C<BOT_PORT>

Not every port is born equal, because Telegram will contact you only on
one of the following ones: C<443>, C<80>, C<88> or C<8443>.

Again, we will fit this piece of configuration into an environment
variable:

   $ export BOT_PORT="...'

=head3 No decision on C<BOT_PROTO='https'>

Telegram will only work with encryption, so you will have to set up TLS.
This is not difficult to do with L<Mojolicious>, but you still have to set
up certificates. So, there is actually nothing to decide about
C<BOT_PROTO>:

   $ export BOT_PROTO='https'

The I<best> would be to obtain a publicly recognised certificate. You can
reuse something that you already have, buy something, or take a look at
L<"Let's Encrypt"|https://letsencrypt.org/> to get one free.

Telegram will not insist on this, anyway, and it is also possible to
generate a self-signed certificate and then hand it over to Telegram. On
the other hand, it I<will> insist on the certificate and the domain or IP
address of your endpoint to match, so you will have to generate your
certificate depending on it, e.g. using the following command:

   $ openssl req -x509  -nodes \
      -newkey rsa:2048 \
      -sha256 \
      -days 365 \
      -subj "/C=IT/ST=Roma/L=Roma/O=Pinco Pals/CN=$BOT_IP" \
      -keyout server.key \
      -out server.crt

Hence, C<server.key> and C<server.crt> will be hanging around in the
directory you are using, keep this in mind!

You can fiddle with the C<-subj> part of course, as long as you make sure
that the C<CN> part matches the IP address or domain name you chose for
your bot endpoint.

=head3 Decide a path and set C<BOT_PATH>

This is really up to you. If you are expanding a previous program, using
a reverse proxy, or just want to go deeper than the root path, you can
just do so:

   $ export BOT_PATH='...'

You can also decide to leave this part empty.

=head3 Wrap it all together

I find it useful to put all environment variables in a single
configuration file that can be C<source>d in a shell:

   # we will ignore BOT_PROTO and just use https
   export BOT_ADDRESS='...'   # Public IP or public domain address
   export BOT_PORT='...'      # 80, 88, 443, 8443
   export BOT_PATH='/'        # or leave it empty
   export BOT_URL="https://$BOT_ADDRESS:$BOT_PORT$BOT_PATH"


=head2 The Program

Our program will be a full-fledged L<Mojolicious> application this time,
although this does not mean it will be much more complicated. After the
previous section, we know there are two additional files in the directory,
namely the certificate file C<server.crt> and the private key file
C<server.key>.

   #!/usr/bin/env perl

   use strict;
   use warnings;
   use Mojolicious::Lite;

   my $token   = $ENV{TOKEN};
   my $bot_url = $ENV{BOT_URL};
   my $certificate = do { local (@ARGV, $/) = 'server.crt'; <> };

   plugin 'Bot::ChatBots::Telegram' => instances => [
      [
         'WebHook',
         processor   => \&process_record,
         register    => 1,
         token       => $token,
         unregister  => 1,
         url         => $bot_url,
         certificate => $certificate,
      ],
   ];

   # set this as a "shim" to make the whole thing similar to LongPoll
   my $bcb = app->chatbots->telegram->instances->[0];

   # encapsulating initialization comes handy
   setup_recurring();

   # now it's time to hand operations over to Mojolicious



( run in 1.209 second using v1.01-cache-2.11-cpan-39bf76dae61 )