无服务器 – Telegram Echo Bot

无服务器 – Telegram Echo Bot


这是官方无服务器项目列表中的另一个有趣项目。我们基本上在 Telegram 上创建了一个新的机器人,然后使用 set_webhook 方法将它连接到我们的 lambda 函数,并在 lambda 函数中编写代码,使机器人回显它收到的任何消息。

先决条件

您需要在手机或台式机上安装 Telegram 应用程序。可以在此处找到下载选项Telegram 是一个消息应用程序,有点类似于 WhatsApp 或 Messenger。安装应用程序后,您需要在应用程序中创建一个新机器人。为此,单击“新消息”图标(右下角的圆形铅笔图标),然后搜索 BotFather。单击已验证的帐户。

电报

一旦你开始与 BotFather 聊天,创建一个新的机器人就很容易理解了。您发送\newbot命令,输入机器人的名称和用户名,您将获得一个访问令牌,您需要记下该令牌。

新机器人

代码演练

代码可以在 GitHub 上找到 – https://github.com/serverless/examples/tree/master/aws-python-telegram-bot

我们将查看项目结构,然后执行 serverless.yml 文件和 handler.py 文件的演练。

项目结构

我们可以看到这个项目有一个外部依赖(python 电报机器人库),列在 requirements.py 中 –

python-telegram-bot==8.1.1

package.json 和 serverless.yml 都表明 serverless-python-requirements 插件已经用于捆绑 python 需求(在这种情况下是电报机器人库)。因此,README.md 文件也建议您执行npm install安装必要的插件。我个人建议您删除 package.json,并使用sls plugin install -n serverless-python-requirements 安装 serverless-python-requirements这将自动创建 package.json 文件。这还将确保您安装最新版本的 serverless-python-requirements。通过运行npm install,您将安装现有 package.json 中提到的版本,该版本可能已过时。

如果您阅读 README.md 文件,您会发现引用的一个文件实际上并不存在于项目中 – serverless.env.yml。您被要求创建此文件并在此文件中输入您的 TELEGRAM_TOKEN。这样做是出于安全原因。TELEGRAM_TOKEN 应该是机密的,您不想公开共享。因此,该项目的创建者并未在 GitHub 上添加 serverless.env.yml 文件。但是您需要在本地机器上创建它。

serverless.yml 演练

serverless.yml 文件以服务的定义开始。

service: serverless-telegram-bot

接下来,定义提供者。这里再次设置了一个环境变量。此变量 (TELEGRAM_TOKEN) 的值是从应该在本地创建的 serverless.env.yml 文件中获取的。在这里,我们再次使用$来表示变量。

provider:
   name: aws
   runtime: python3.6
   profile: ckl
   environment:
      TELEGRAM_TOKEN: ${file(./serverless.env.yml):TELEGRAM_TOKEN, ''}

功能块非常简单。定义了两个函数,都是 HTTP 触发的。但是,http 事件参数在这里定义在一行中。

- http:
   path: /set_webhook
   method: post

而不是使用单行执行– httpPOST /set_webhook

另外,请注意webhookset_webhook函数位于同一个处理程序文件中。

functions:
   webhook:
      handler: handler.webhook
      events:
         - http: POST /
set_webhook:
   handler: handler.set_webhook
   events:
      - http: POST /set_webhook

最后,定义了 serverless-python-requirements 插件。

plugins:
   - serverless-python-requirements

handler.py 演练

我们有几个导入语句

import json
import telegram
import os
import logging

接下来定义了一个logger对象,它基本上可以帮助我们输入日志语句。请注意,这对于 python 运行时函数不是必需的。简单的打印语句也会被记录。

唯一的区别是 logger 的输出包括日志级别、时间戳和请求 ID。您可以在此处阅读有关日志记录库的更多信息

# Logging is cool!
logger = logging.getLogger()
if logger.handlers:
   for handler in logger.handlers:
      logger.removeHandler(handler)
logging.basicConfig(level=logging.INFO)

接下来,定义 OK_RESPONSE 和 ERROR_RESPONSE 的 JSON。这些用作函数的返回值。

OK_RESPONSE = {
   'statusCode': 200,
   'headers': {'Content-Type': 'application/json'},
   'body': json.dumps('ok')
}
ERROR_RESPONSE = {
   'statusCode': 400,
   'body': json.dumps('Oops, something went wrong!')
}

接下来,定义了两个 API 函数都使用的辅助函数。此函数使用 serverless.yml 中作为环境变量提供的 Token 返回一个机器人实例。

def configure_telegram():
   """
   Conimages the bot with a Telegram Token.
   Returns a bot instance.
   """
   TELEGRAM_TOKEN = os.environ.get('TELEGRAM_TOKEN')
   if not TELEGRAM_TOKEN:
      logger.error('The TELEGRAM_TOKEN must be set')
      raise NotImplementedError
   return telegram.Bot(TELEGRAM_TOKEN)

接下来,定义两个 API 的处理程序函数。我们先来看看set_webhook函数。在这里,bot 实例是从我们之前看到的 configure_telegram 函数中获取的。接下来,从头中提取主机字段,从传入事件的 requestContext 块中提取 stage 字段。使用这两个字段,构建 webhook 的 URL。最后,它使用bot.set_webhook(url)函数应用于机器人如果 webhook 设置正确,则设置 OK_RESPONSE,否则设置 ERROR_RESPONSE。请注意,此 set_webhook API 必须使用 POSTMAN 之类的工具手动触发一次。

def set_webhook(event, context):
   """
   Sets the Telegram bot webhook.
   """
   logger.info('Event: {}'.format(event))
   bot = configure_telegram()
   url = 'https://{}/{}/'.format(
      event.get('headers').get('Host'),
      event.get('requestContext').get('stage'),
   )
   webhook = bot.set_webhook(url)

   if webhook:
      return OK_RESPONSE
   return ERROR_RESPONSE

让我们了解 set_webhook 函数如何能够获取 webhook 的正确 URL。请注意,set_webhook 和 webhook 函数的路径只有 ‘/set_webhook’ 不同。他们共享同一个主持人和舞台。因此,我们可以使用在 set_webhook 函数的事件中接收到的 host 和 dev 来导出 webhook 函数的端点。如果您的端点是“https://abcdefghijk.execute-api.us-east-1.amazonaws.com/dev”,则主机将为“https://abcdefghijk.execute-api.us-east-1”。 amazonaws.com”,舞台将是“dev”。set_webhook 函数由“https://abcdefghijk.execute-api.us-east-1.amazonaws.com/dev/set_webhook”触发,webhook 函数由“https://abcdefghijk.execute-api.us”触发-east-1.amazonaws.com/dev’。因此,

最后,我们来看一下 webhook 函数。这很简单。它从configure_telegram辅助函数接收机器人实例然后它检查事件。如果它是一个 POST 事件并且包含一个正文,那么它会从正文中提取聊天 ID 和消息。如果文本是“/start”,表示对话开始,它会使用bot.sendMessage(chat_id=chat_id, text=text)命令回复标准问候语否则,它会用收到的相同文本回复。

def webhook(event, context):
   """
   Runs the Telegram webhook.
   """
   bot = configure_telegram()
   logger.info('Event: {}'.format(event))

   if event.get('httpMethod') == 'POST' and event.get('body'): 
      logger.info('Message received')
      update = telegram.Update.de_json(json.loads(event.get('body')), bot)
      chat_id = update.message.chat.id
      text = update.message.text
      
      if text == '/start':
         text = """Hello, human! I am an echo bot, built with Python and the Serverless Framework.
         You can take a look at my source code here: https://github.com/jonatasbaldin/serverless-telegram-bot.
         If you have any issues, please drop a tweet to my creator: https://twitter.com/jonatsbaldin. Happy botting!"""

      bot.sendMessage(chat_id=chat_id, text=text)
      logger.info('Message sent')

      return OK_RESPONSE
   return ERROR_RESPONSE

一旦您通过 POSTMAN 之类的工具触发了 set_webhook 功能,您就可以在 Telegram 上打开您的机器人并与其聊天。它将按预期回显消息。

设置 WebHook

祝贺你的第一个 Telegram 机器人!

觉得文章有用?

点个广告表达一下你的爱意吧 !😁