Skip to content

Implementing a Telegram Messenger Bot with Spring Webflux

License

Notifications You must be signed in to change notification settings

hmunoz/telegram-bot-spring

 
 

Repository files navigation

Spring Webflux Telegram Bot Build Status Code Coverage Status

Telegram bot webhook implementation with Spring Boot Webflux

1. Technologies

  • Spring Boot 2.0 with Webflux

  • Reactive MongoDB

  • Lombok

  • Reactor IO

  • Gradle

  • (Nginx)

2. Starting the Spring Boot application

You can either import the project into the Spring Tool Suite (https://spring.io/tools/sts/all) by using the Buildship (https://github.com/eclipse/buildship/blob/master/docs/user/Installation.md) import wizard and start it from the IDE or simply start the application by running the bootRun Gradle task.

./gradlew bRun

3. Using a Webhook

Usually you’d want to use a webhook, if you’re providing a rest endpoint like this app does.

The webhook should point the /telegram/webhook endpoint, e.g., https://{your-domain}/telegram/webhook.

4. Sample Update for the webhook

curl -H "Content-Type: application/json" -X POST -d '{"update_id":463166687, "message":{"message_id":256,"from":{"id":{your-user-id},"is_bot":false,"first_name":"Simon","last_name":"Scholz","language_code":"en-US"},"chat":{"id":{your-chat-id},"first_name":"Simon","last_name":"Scholz","type":"private"},"date":1519229850,"text":"/now Hamburg","entities":[{"offset":0,"length":4,"type":"bot_command"}]}}' https://localhost:8080/telegram/webhook

4.1. Set a webhook

A nice way to set the webhook is by using curl:

curl -F "url=https://{your-domain}/telegram/webhook" https://api.telegram.org/bot{your-bots-api-token}/setWebhook

For a custom ssl certificate(telegram required pem) the following command can be used:

curl -F "url=https://{your-domain}/webhook" -F "certificate=@/home/simon/ssl/keystore.pem" https://api.telegram.org/bot{your api token}/setWebhook
Tip
See https://core.telegram.org/bots/api#setwebhook for further information about setting a webhook.

4.2. SSL secure the webhook endpoint

To use a webhook for telegram you need to use port 443 or 8443 with ssl. See Let’s Encrypt for further information about ssl security for your domain.

This is also a nice introduction how to achieve that: https://dzone.com/articles/spring-boot-secured-by-lets-encrypt

4.2.1. Secure Spring App directly

To run this Spring Boot application with your own bot you usually have to adjust the application.yml file.

server:
  port: 443
  ssl:
    key-store: /{path-to-file}/keystore.p12 (1)
    key-store-password: *** your password ***
    key-store-type: PKCS12
    key-alias: {your-key-alias}
  1. See Let’s Encrypt for *.p12 key store generation

4.2.2. Use Nginx for SSL encryption

You can install Nginx on your server and add the following config files.

http.conf.j2

server {
    listen 80 default_server;

    server_name _;

    return 301 https://$host$request_uri; (1)
}
  1. Redirect port 80 (http) to port 443 (https)

Then add the following https.conf.j2 Nginx config:

upstream app-upstream {
    server localhost:{port}; (1)
}

server {
    listen       443 default ssl;
    server_name  {{ service_host }};

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    ssl_certificate /etc/letsencrypt/live/{{ service_host }}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/{{ service_host }}/privkey.pem;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;

    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";

    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_ecdh_curve secp384r1;


    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
        proxy_pass https://app-upstream;
    }
}
  1. Substitute {port} with your server apps port

5. Questions

Please make use of this bot, share your knowledge and adapt it for your needs.

6. Contributing

Feedback is highly appreciated. You may open issues, send pull requests or simply contact me.

7. Let’s Encrypt

Add ssl certificate to your domain.

7.1. For Fritz!Box AVM Router

AVM is currently working on a setting for Let’s Encrypt and their routers.

7.2. Using certbot

cd {your home directory}

mkdir certbot

cd certbot

wget https://dl.eff.org/certbot-auto

chmod +x certbot-auto

./certbot-auto certonly -a standalone -d {your domain name -> example.ddns.net}

cd /etc/letsencrypt/live/{your domain name -> example.ddns.net}/

openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name telegram-bot -CAfile chain.pem -caname root

The keystore.p12 file has to be moved to a location, which can be accessed by the user, which starts the spring boot app service. The chown -R {username} and chgrp -R {username} command are helpful here.

The conversion to a keystore.p12 file with openssl is necessary, because spring boot does not work with *.pem files, but with *.p12 files. See server.ssl.key-store property in application.properties file of the spring boot application.

7.3. Renew the certificate

cd certbot

./certbot-auto renew

cd /etc/letsencrypt/live/{your domain name -> example.ddns.net}/

openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name telegram-bot -CAfile chain.pem -caname root

About

Implementing a Telegram Messenger Bot with Spring Webflux

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • HTML 77.5%
  • Java 22.5%