mirror of
https://github.com/eternnoir/pyTelegramBotAPI.git
synced 2023-08-10 21:12:57 +03:00
Merge pull request #82 from skgsergio/webhook-examples
Add Webhook examples (CPython, Flask, CherryPy)
This commit is contained in:
commit
ca2019b8f1
@ -208,7 +208,7 @@ tb.polling(none_stop=False, interval=0, block=True)
|
|||||||
user = tb.get_me()
|
user = tb.get_me()
|
||||||
|
|
||||||
# setWebhook
|
# setWebhook
|
||||||
tb.set_webhook(url="http://example.com", cert=open('mycert.pem'))
|
tb.set_webhook(url="http://example.com", certificate=open('mycert.pem'))
|
||||||
# unset webhook
|
# unset webhook
|
||||||
tb.remove_webhook()
|
tb.remove_webhook()
|
||||||
|
|
||||||
@ -373,8 +373,10 @@ bot.set_update_listener(handle_messages)
|
|||||||
bot.polling()
|
bot.polling()
|
||||||
```
|
```
|
||||||
|
|
||||||
### Using web hooks
|
### Using webhooks
|
||||||
If you prefer using web hooks to the getUpdates method, you can use the `process_new_messages(messages)` function in TeleBot to make it process the messages that you supply. It takes a list of Message objects. This function is still incubating.
|
When using webhooks telegram sends one Update per call, for processing it you should call process_new_messages([update.message]) when you recieve it.
|
||||||
|
|
||||||
|
There are some examples using webhooks in the *examples/webhook_examples* directory.
|
||||||
|
|
||||||
### Logging
|
### Logging
|
||||||
|
|
||||||
|
100
README.rst
100
README.rst
@ -52,6 +52,7 @@ API <https://core.telegram.org/bots/api>`__.
|
|||||||
|
|
||||||
- `The Telegram Chat Group <#the-telegram-chat-group>`__
|
- `The Telegram Chat Group <#the-telegram-chat-group>`__
|
||||||
- `More examples <#more-examples>`__
|
- `More examples <#more-examples>`__
|
||||||
|
- `Bots using this API <#bots-using-this-api>`__
|
||||||
|
|
||||||
Getting started.
|
Getting started.
|
||||||
================
|
================
|
||||||
@ -213,9 +214,39 @@ Outlined below are some general use cases of the API.
|
|||||||
Message handlers
|
Message handlers
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
A message handler is a function which is decorated with the
|
A message handler is a function that is decorated with the
|
||||||
``message_handler`` decorator of a TeleBot instance. The following
|
``message_handler`` decorator of a TeleBot instance. Message handlers
|
||||||
examples illustrate the possibilities of message handlers:
|
consist of one or multiple filters. Each filter much return True for a
|
||||||
|
certain message in order for a message handler to become eligible to
|
||||||
|
handle that message. A message handler is declared in the following way
|
||||||
|
(provided ``bot`` is an instance of TeleBot):
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
@bot.message_handler(filters)
|
||||||
|
def function_name(message):
|
||||||
|
bot.reply_to(message, "This is a message handler")
|
||||||
|
|
||||||
|
``function_name`` is not bound to any restrictions. Any function name is
|
||||||
|
permitted with message handlers. The function must accept at most one
|
||||||
|
argument, which will be the message that the function must handle.
|
||||||
|
``filters`` is a list of keyword arguments. A filter is declared in the
|
||||||
|
following manner: ``name=argument``. One handler may have multiple
|
||||||
|
filters. TeleBot supports the following filters:
|
||||||
|
|
||||||
|
+------------------+---------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
| name | argument(s) | Condition |
|
||||||
|
+==================+=============================================+=================================================================================================================================================================================+
|
||||||
|
| content\_types | list of strings (default ``['text']``) | ``True`` if message.content\_type is in the list of strings. |
|
||||||
|
+------------------+---------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
| regexp | a regular expression as a string | ``True`` if ``re.search(regexp_arg)`` returns ``True`` and ``message.content_type == 'text'`` (See `Python Regular Expressions <https://docs.python.org/2/library/re.html>`__ |
|
||||||
|
+------------------+---------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
| commands | list of strings | ``True`` if ``message.content_type == 'text'`` and ``message.text`` starts with a command that is in the list of strings. |
|
||||||
|
+------------------+---------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
| func | a function (lambda or function reference) | ``True`` if the lambda or function reference returns ``True`` |
|
||||||
|
+------------------+---------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
Here are some examples of using the filters and message handlers:
|
||||||
|
|
||||||
.. code:: python
|
.. code:: python
|
||||||
|
|
||||||
@ -250,8 +281,15 @@ examples illustrate the possibilities of message handlers:
|
|||||||
def handle_text_doc(message)
|
def handle_text_doc(message)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
*Note: all handlers are tested in the order in which they were declared*
|
# Handlers can be stacked to create a function which will be called if either message_handler is eligible
|
||||||
#### TeleBot
|
# This handler will be called if the message starts with '/hello' OR is some emoji
|
||||||
|
@bot.message_handler(commands=['hello'])
|
||||||
|
@bot.message_handler(func=lambda msg: msg.text.encode("utf-8") == SOME_FANCY_EMOJI)
|
||||||
|
def send_something(message):
|
||||||
|
pass
|
||||||
|
|
||||||
|
**Important: all handlers are tested in the order in which they were
|
||||||
|
declared** #### TeleBot
|
||||||
|
|
||||||
.. code:: python
|
.. code:: python
|
||||||
|
|
||||||
@ -270,6 +308,11 @@ examples illustrate the possibilities of message handlers:
|
|||||||
# getMe
|
# getMe
|
||||||
user = tb.get_me()
|
user = tb.get_me()
|
||||||
|
|
||||||
|
# setWebhook
|
||||||
|
tb.set_webhook(url="http://example.com", certificate=open('mycert.pem'))
|
||||||
|
# unset webhook
|
||||||
|
tb.remove_webhook()
|
||||||
|
|
||||||
# getUpdates
|
# getUpdates
|
||||||
updates = tb.get_updates()
|
updates = tb.get_updates()
|
||||||
updates = tb.get_updates(1234,100,20) #get_Updates(offset, limit, timeout):
|
updates = tb.get_updates(1234,100,20) #get_Updates(offset, limit, timeout):
|
||||||
@ -322,6 +365,14 @@ examples illustrate the possibilities of message handlers:
|
|||||||
# 'record_audio', 'upload_audio', 'upload_document' or 'find_location'.
|
# 'record_audio', 'upload_audio', 'upload_document' or 'find_location'.
|
||||||
tb.send_chat_action(chat_id, action_string)
|
tb.send_chat_action(chat_id, action_string)
|
||||||
|
|
||||||
|
# getFile
|
||||||
|
# Downloading a file is straightforward
|
||||||
|
# Returns a File object
|
||||||
|
import requests
|
||||||
|
file_info = tb.get_file(file_id)
|
||||||
|
|
||||||
|
file = requests.get('https://api.telegram.org/file/bot{0}/{1}'.format(API_TOKEN, file_info.file_path))
|
||||||
|
|
||||||
Reply markup
|
Reply markup
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
@ -465,29 +516,31 @@ function as a listener to TeleBot. Example:
|
|||||||
bot.set_update_listener(handle_messages)
|
bot.set_update_listener(handle_messages)
|
||||||
bot.polling()
|
bot.polling()
|
||||||
|
|
||||||
Using web hooks
|
Using webhooks
|
||||||
---------------
|
--------------
|
||||||
|
|
||||||
If you prefer using web hooks to the getUpdates method, you can use the
|
When using webhooks telegram sends one Update per call, for processing
|
||||||
``process_new_messages(messages)`` function in TeleBot to make it
|
it you should call process\_new\_messages([update.message]) when you
|
||||||
process the messages that you supply. It takes a list of Message
|
recieve it.
|
||||||
objects. This function is still incubating.
|
|
||||||
|
There are some examples using webhooks in the
|
||||||
|
*examples/webhook\_examples* directory.
|
||||||
|
|
||||||
Logging
|
Logging
|
||||||
-------
|
-------
|
||||||
|
|
||||||
You can use the Telebot module logger to log debug info about Telebot.
|
You can use the Telebot module logger to log debug info about Telebot.
|
||||||
Use ``telebot.logger`` to get the logger of the TeleBot module.
|
Use ``telebot.logger`` to get the logger of the TeleBot module. It is
|
||||||
|
possible to add custom logging Handlers to the logger. Refer to the
|
||||||
|
`Python logging module
|
||||||
|
page <https://docs.python.org/2/library/logging.html>`__ for more info.
|
||||||
|
|
||||||
.. code:: python
|
.. code:: python
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
logger = telebot.logger
|
logger = telebot.logger
|
||||||
formatter = logging.Formatter('[%(asctime)s] %(thread)d {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s',
|
telebot.logger.setLevel(logging.DEBUG) # Outputs debug messages to console.
|
||||||
'%m-%d %H:%M:%S')
|
|
||||||
ch = logging.StreamHandler(sys.stdout)
|
|
||||||
logger.addHandler(ch)
|
|
||||||
logger.setLevel(logging.DEBUG) # or use logging.INFO
|
|
||||||
ch.setFormatter(formatter)
|
|
||||||
|
|
||||||
F.A.Q.
|
F.A.Q.
|
||||||
======
|
======
|
||||||
@ -513,6 +566,8 @@ Get help. Discuss. Chat.
|
|||||||
|
|
||||||
Join the `pyTelegramBotAPI Telegram Chat
|
Join the `pyTelegramBotAPI Telegram Chat
|
||||||
Group <https://telegram.me/joinchat/067e22c60035523fda8f6025ee87e30b>`__.
|
Group <https://telegram.me/joinchat/067e22c60035523fda8f6025ee87e30b>`__.
|
||||||
|
We now have a Telegram Channel as well! Keep yourself up to date with
|
||||||
|
API changes, and `join it <https://telegram.me/pytelegrambotapi>`__.
|
||||||
|
|
||||||
More examples
|
More examples
|
||||||
=============
|
=============
|
||||||
@ -524,5 +579,14 @@ More examples
|
|||||||
- `next\_step\_handler
|
- `next\_step\_handler
|
||||||
Example <https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/step_example.py>`__
|
Example <https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/step_example.py>`__
|
||||||
|
|
||||||
|
Bots using this API
|
||||||
|
===================
|
||||||
|
|
||||||
|
- `SiteAlert bot <https://telegram.me/SiteAlert_bot>`__
|
||||||
|
(`source <https://github.com/ilteoood/SiteAlert-Python>`__) by
|
||||||
|
*ilteoood* - Monitors websites and sends a notification on changes
|
||||||
|
Want to have your bot listed here? Send a Telegram message to
|
||||||
|
@eternnoir or @pevdh.
|
||||||
|
|
||||||
.. |Build Status| image:: https://travis-ci.org/eternnoir/pyTelegramBotAPI.svg?branch=master
|
.. |Build Status| image:: https://travis-ci.org/eternnoir/pyTelegramBotAPI.svg?branch=master
|
||||||
:target: https://travis-ci.org/eternnoir/pyTelegramBotAPI
|
:target: https://travis-ci.org/eternnoir/pyTelegramBotAPI
|
||||||
|
36
examples/webhook_examples/README.md
Normal file
36
examples/webhook_examples/README.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# Webhook examples using pyTelegramBotAPI
|
||||||
|
|
||||||
|
There are 3 examples in this directory using different libraries:
|
||||||
|
|
||||||
|
* **Python (CPython):** *webhook_cpython_echo_bot.py*
|
||||||
|
* **Pros:**
|
||||||
|
* Official python libraries, it works out of the box (doesn't require to
|
||||||
|
install anything).
|
||||||
|
* Works with Python 2 and Python 3 (need to be converted with 2to3).
|
||||||
|
* **Cons:**
|
||||||
|
* Ugly code.
|
||||||
|
* Many things to handle yourself, this can lead to errors.
|
||||||
|
* Not powerful, do the trick but the performance is low.
|
||||||
|
|
||||||
|
* **CherryPy (3.8.0):** *webhook_cherrypy_echo_bot.py*
|
||||||
|
* **Pros:**
|
||||||
|
* It's a web application framework, cleaner code, uses objects for defining
|
||||||
|
the web application.
|
||||||
|
* Very good performance.
|
||||||
|
* The project seems to be active, latest version is recent.
|
||||||
|
* Works with Python 2 and Python 3.
|
||||||
|
* **Cons:**
|
||||||
|
* Some things are not very intuitive, reading the doc is a must.
|
||||||
|
|
||||||
|
* **Flask (0.10.1):** *webhook_flask_echo_bot.py*
|
||||||
|
* **Pros:**
|
||||||
|
* It's a web application framework, cleaner code, uses decorator which can
|
||||||
|
be nice.
|
||||||
|
* Good performance.
|
||||||
|
* It's intuitive if you know how web application works.
|
||||||
|
* **Cons:**
|
||||||
|
* The project seems not to be very active, latest version dates 2013.
|
||||||
|
* They don't recommend to use it with Python 3, but may work.
|
||||||
|
* May be a oversized for just handling webhook petitions.
|
||||||
|
|
||||||
|
*Latest update of this document: 2015-10-06*
|
85
examples/webhook_examples/webhook_cherrypy_echo_bot.py
Normal file
85
examples/webhook_examples/webhook_cherrypy_echo_bot.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This is a simple echo bot using decorators and webhook with CherryPy
|
||||||
|
# It echoes any incoming text messages and does not use the polling method.
|
||||||
|
|
||||||
|
import cherrypy
|
||||||
|
import telebot
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
API_TOKEN = '<api_token>'
|
||||||
|
|
||||||
|
WEBHOOK_HOST = '<ip/host where the bot is running>'
|
||||||
|
WEBHOOK_PORT = 8443 # 443, 80, 88 or 8443 (port need to be 'open')
|
||||||
|
WEBHOOK_LISTEN = '0.0.0.0' # In some VPS you may need to put here the IP addr
|
||||||
|
|
||||||
|
WEBHOOK_SSL_CERT = './webhook_cert.pem' # Path to the ssl certificate
|
||||||
|
WEBHOOK_SSL_PRIV = './webhook_pkey.pem' # Path to the ssl private key
|
||||||
|
|
||||||
|
# Quick'n'dirty SSL certificate generation:
|
||||||
|
#
|
||||||
|
# openssl genrsa -out webhook_pkey.pem 2048
|
||||||
|
# openssl req -new -x509 -days 3650 -key webhook_pkey.pem -out webhook_cert.pem
|
||||||
|
#
|
||||||
|
# When asked for "Common Name (e.g. server FQDN or YOUR name)" you should reply
|
||||||
|
# with the same value in you put in WEBHOOK_HOST
|
||||||
|
|
||||||
|
WEBHOOK_URL_BASE = "https://%s:%s" % (WEBHOOK_HOST, WEBHOOK_PORT)
|
||||||
|
WEBHOOK_URL_PATH = "/%s/" % (API_TOKEN)
|
||||||
|
|
||||||
|
|
||||||
|
logger = telebot.logger
|
||||||
|
telebot.logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
bot = telebot.TeleBot(API_TOKEN)
|
||||||
|
|
||||||
|
|
||||||
|
# WebhookServer, process webhook calls
|
||||||
|
class WebhookServer(object):
|
||||||
|
@cherrypy.expose
|
||||||
|
def index(self):
|
||||||
|
if 'content-length' in cherrypy.request.headers and \
|
||||||
|
'content-type' in cherrypy.request.headers and \
|
||||||
|
cherrypy.request.headers['content-type'] == 'application/json':
|
||||||
|
length = int(cherrypy.request.headers['content-length'])
|
||||||
|
json_string = cherrypy.request.body.read(length)
|
||||||
|
update = telebot.types.Update.de_json(json_string)
|
||||||
|
bot.process_new_messages([update.message])
|
||||||
|
return ''
|
||||||
|
else:
|
||||||
|
raise cherrypy.HTTPError(403)
|
||||||
|
|
||||||
|
|
||||||
|
# Handle '/start' and '/help'
|
||||||
|
@bot.message_handler(commands=['help', 'start'])
|
||||||
|
def send_welcome(message):
|
||||||
|
bot.reply_to(message,
|
||||||
|
("Hi there, I am EchoBot.\n"
|
||||||
|
"I am here to echo your kind words back to you."))
|
||||||
|
|
||||||
|
|
||||||
|
# Handle all other messages
|
||||||
|
@bot.message_handler(func=lambda message: True, content_types=['text'])
|
||||||
|
def echo_message(message):
|
||||||
|
bot.reply_to(message, message.text)
|
||||||
|
|
||||||
|
|
||||||
|
# Remove webhook, it fails sometimes the set if there is a previous webhook
|
||||||
|
bot.remove_webhook()
|
||||||
|
|
||||||
|
# Set webhook
|
||||||
|
bot.set_webhook(url=WEBHOOK_URL_BASE+WEBHOOK_URL_PATH,
|
||||||
|
certificate=open(WEBHOOK_SSL_CERT, 'r'))
|
||||||
|
|
||||||
|
# Start cherrypy server
|
||||||
|
cherrypy.config.update({
|
||||||
|
'server.socket_host': WEBHOOK_LISTEN,
|
||||||
|
'server.socket_port': WEBHOOK_PORT,
|
||||||
|
'server.ssl_module': 'builtin',
|
||||||
|
'server.ssl_certificate': WEBHOOK_SSL_CERT,
|
||||||
|
'server.ssl_private_key': WEBHOOK_SSL_PRIV
|
||||||
|
})
|
||||||
|
|
||||||
|
cherrypy.quickstart(WebhookServer(), WEBHOOK_URL_PATH, {'/': {}})
|
99
examples/webhook_examples/webhook_cpython_echo_bot.py
Normal file
99
examples/webhook_examples/webhook_cpython_echo_bot.py
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This is a simple echo bot using decorators and webhook with BaseHTTPServer
|
||||||
|
# It echoes any incoming text messages and does not use the polling method.
|
||||||
|
|
||||||
|
import BaseHTTPServer
|
||||||
|
import ssl
|
||||||
|
import telebot
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
API_TOKEN = '<api_token>'
|
||||||
|
|
||||||
|
WEBHOOK_HOST = '<ip/host where the bot is running>'
|
||||||
|
WEBHOOK_PORT = 8443 # 443, 80, 88 or 8443 (port need to be 'open')
|
||||||
|
WEBHOOK_LISTEN = '0.0.0.0' # In some VPS you may need to put here the IP addr
|
||||||
|
|
||||||
|
WEBHOOK_SSL_CERT = './webhook_cert.pem' # Path to the ssl certificate
|
||||||
|
WEBHOOK_SSL_PRIV = './webhook_pkey.pem' # Path to the ssl private key
|
||||||
|
|
||||||
|
# Quick'n'dirty SSL certificate generation:
|
||||||
|
#
|
||||||
|
# openssl genrsa -out webhook_pkey.pem 2048
|
||||||
|
# openssl req -new -x509 -days 3650 -key webhook_pkey.pem -out webhook_cert.pem
|
||||||
|
#
|
||||||
|
# When asked for "Common Name (e.g. server FQDN or YOUR name)" you should reply
|
||||||
|
# with the same value in you put in WEBHOOK_HOST
|
||||||
|
|
||||||
|
WEBHOOK_URL_BASE = "https://%s:%s" % (WEBHOOK_HOST, WEBHOOK_PORT)
|
||||||
|
WEBHOOK_URL_PATH = "/%s/" % (API_TOKEN)
|
||||||
|
|
||||||
|
|
||||||
|
logger = telebot.logger
|
||||||
|
telebot.logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
bot = telebot.TeleBot(API_TOKEN)
|
||||||
|
|
||||||
|
|
||||||
|
# WebhookHandler, process webhook calls
|
||||||
|
class WebhookHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||||
|
server_version = "WebhookHandler/1.0"
|
||||||
|
|
||||||
|
def do_HEAD(self):
|
||||||
|
self.send_response(200)
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
def do_GET(self):
|
||||||
|
self.send_response(200)
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
def do_POST(self):
|
||||||
|
if self.path == WEBHOOK_URL_PATH and \
|
||||||
|
'content-type' in self.headers and \
|
||||||
|
'content-length' in self.headers and \
|
||||||
|
self.headers['content-type'] == 'application/json':
|
||||||
|
json_string = self.rfile.read(int(self.headers['content-length']))
|
||||||
|
|
||||||
|
self.send_response(200)
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
update = telebot.types.Update.de_json(json_string)
|
||||||
|
bot.process_new_messages([update.message])
|
||||||
|
else:
|
||||||
|
self.send_error(403)
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
|
||||||
|
# Handle '/start' and '/help'
|
||||||
|
@bot.message_handler(commands=['help', 'start'])
|
||||||
|
def send_welcome(message):
|
||||||
|
bot.reply_to(message,
|
||||||
|
("Hi there, I am EchoBot.\n"
|
||||||
|
"I am here to echo your kind words back to you."))
|
||||||
|
|
||||||
|
|
||||||
|
# Handle all other messages
|
||||||
|
@bot.message_handler(func=lambda message: True, content_types=['text'])
|
||||||
|
def echo_message(message):
|
||||||
|
bot.reply_to(message, message.text)
|
||||||
|
|
||||||
|
|
||||||
|
# Remove webhook, it fails sometimes the set if there is a previous webhook
|
||||||
|
bot.remove_webhook()
|
||||||
|
|
||||||
|
# Set webhook
|
||||||
|
bot.set_webhook(url=WEBHOOK_URL_BASE+WEBHOOK_URL_PATH,
|
||||||
|
certificate=open(WEBHOOK_SSL_CERT, 'r'))
|
||||||
|
|
||||||
|
# Start server
|
||||||
|
httpd = BaseHTTPServer.HTTPServer((WEBHOOK_LISTEN, WEBHOOK_PORT),
|
||||||
|
WebhookHandler)
|
||||||
|
|
||||||
|
httpd.socket = ssl.wrap_socket(httpd.socket,
|
||||||
|
certfile=WEBHOOK_SSL_CERT,
|
||||||
|
keyfile=WEBHOOK_SSL_PRIV,
|
||||||
|
server_side=True)
|
||||||
|
|
||||||
|
httpd.serve_forever()
|
84
examples/webhook_examples/webhook_flask_echo_bot.py
Normal file
84
examples/webhook_examples/webhook_flask_echo_bot.py
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This is a simple echo bot using decorators and webhook with flask
|
||||||
|
# It echoes any incoming text messages and does not use the polling method.
|
||||||
|
|
||||||
|
import flask
|
||||||
|
import telebot
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
API_TOKEN = '<api_token>'
|
||||||
|
|
||||||
|
WEBHOOK_HOST = '<ip/host where the bot is running>'
|
||||||
|
WEBHOOK_PORT = 8443 # 443, 80, 88 or 8443 (port need to be 'open')
|
||||||
|
WEBHOOK_LISTEN = '0.0.0.0' # In some VPS you may need to put here the IP addr
|
||||||
|
|
||||||
|
WEBHOOK_SSL_CERT = './webhook_cert.pem' # Path to the ssl certificate
|
||||||
|
WEBHOOK_SSL_PRIV = './webhook_pkey.pem' # Path to the ssl private key
|
||||||
|
|
||||||
|
# Quick'n'dirty SSL certificate generation:
|
||||||
|
#
|
||||||
|
# openssl genrsa -out webhook_pkey.pem 2048
|
||||||
|
# openssl req -new -x509 -days 3650 -key webhook_pkey.pem -out webhook_cert.pem
|
||||||
|
#
|
||||||
|
# When asked for "Common Name (e.g. server FQDN or YOUR name)" you should reply
|
||||||
|
# with the same value in you put in WEBHOOK_HOST
|
||||||
|
|
||||||
|
WEBHOOK_URL_BASE = "https://%s:%s" % (WEBHOOK_HOST, WEBHOOK_PORT)
|
||||||
|
WEBHOOK_URL_PATH = "/%s/" % (API_TOKEN)
|
||||||
|
|
||||||
|
|
||||||
|
logger = telebot.logger
|
||||||
|
telebot.logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
bot = telebot.TeleBot(API_TOKEN)
|
||||||
|
|
||||||
|
app = flask.Flask(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
# Empty webserver index, return nothing, just http 200
|
||||||
|
@app.route('/', methods=['GET', 'HEAD'])
|
||||||
|
def index():
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
# Process webhook calls
|
||||||
|
@app.route(WEBHOOK_URL_PATH, methods=['POST'])
|
||||||
|
def webhook():
|
||||||
|
if flask.request.headers.get('content-type') == 'application/json':
|
||||||
|
json_string = flask.request.get_data()
|
||||||
|
update = telebot.types.Update.de_json(json_string)
|
||||||
|
bot.process_new_messages([update.message])
|
||||||
|
return ''
|
||||||
|
else:
|
||||||
|
flask.abort(403)
|
||||||
|
|
||||||
|
|
||||||
|
# Handle '/start' and '/help'
|
||||||
|
@bot.message_handler(commands=['help', 'start'])
|
||||||
|
def send_welcome(message):
|
||||||
|
bot.reply_to(message,
|
||||||
|
("Hi there, I am EchoBot.\n"
|
||||||
|
"I am here to echo your kind words back to you."))
|
||||||
|
|
||||||
|
|
||||||
|
# Handle all other messages
|
||||||
|
@bot.message_handler(func=lambda message: True, content_types=['text'])
|
||||||
|
def echo_message(message):
|
||||||
|
bot.reply_to(message, message.text)
|
||||||
|
|
||||||
|
|
||||||
|
# Remove webhook, it fails sometimes the set if there is a previous webhook
|
||||||
|
bot.remove_webhook()
|
||||||
|
|
||||||
|
# Set webhook
|
||||||
|
bot.set_webhook(url=WEBHOOK_URL_BASE+WEBHOOK_URL_PATH,
|
||||||
|
certificate=open(WEBHOOK_SSL_CERT, 'r'))
|
||||||
|
|
||||||
|
# Start flask server
|
||||||
|
app.run(host=WEBHOOK_LISTEN,
|
||||||
|
port=WEBHOOK_PORT,
|
||||||
|
ssl_context=(WEBHOOK_SSL_CERT, WEBHOOK_SSL_PRIV),
|
||||||
|
debug=True)
|
Loading…
x
Reference in New Issue
Block a user