“每当收到Webhook更新时,就有两个选择”从
Telegram Bot Api常见问题解答
哈Ha!
长期以来,无服务器概念(或更确切地说,将其作为AWS Lambda服务实现)对我来说是一个相对清晰但非常抽象的想法。 她经常在Radio-T上进行有关Reddit的讨论,但从未进入我的生活。 工作项目不是存在于云中,而是家庭项目-为什么? 虚拟计算机变得越来越便宜,Docker已经掌握,并且一切正常。
但是,Yandex Cloud Functions的展示,尤其是该服务的宣布价格,为我们提供了新的思路。
TL; DR-在一个下雨的星期五晚上,我们将使用JavaScript编写一个简单的Telegram机器人,该机器人可以用简单的消息响应请求。 如果这是您的家庭项目-几乎可以肯定,使用它比最预算的VPS便宜得多。
走吧
在最常识上,无服务器是什么?
我不会深入丛林;有关此主题的评论文章会 定期出现在Habré上。 这是一个机会,可以使用平台支持的一种编程语言将功能放置在云中,以设置其运行条件,仅此而已。 当触发发生时,虚拟环境上升,该功能在其中起作用,然后关闭。 与环境一起。
这种方法的优点是什么?
安全性
您可以获得最新版本的编译器/解释器的安全隔离环境。
您无需将程序上载到虚拟机中实际操作系统上的更新更新并设置安全策略和防火墙,而是将程序上载到服务器即可运行。
稳定性和弹性
无需配置pm2,而是设置重新启动策略,监视内存泄漏并理解部署的细微差别-是的,您只需将程序上载到服务器,其余的由服务提供商负责。
价格,尤其是在低负荷项目的家中
充电时,将考虑该函数在执行过程中保留的内存量和调用次数。 根据文档,启动10,000,000个功能(运行800毫秒,512 MB内存限制)将花费3,900卢布。
这对我意味着什么? 我典型的宠物项目是一个机器人,它可以回答狭窄圈子中众所周知的事件的预定问题。 您需要每年运行一次,持续几天。 去年,他回答了来自参与者的1000个请求,对于他来说128mb绰绰有余,该功能的执行时间为300ms。 这样的用例将花费0.046₽ 。
是的,4.6科比。 另外,我不会花时间在设置上,这更加令人愉快。 pm2没有规则,没有Dockerfile或环境的实现,而且蛋糕上的小菜一碟-SLA 99.9。
在到目前为止尚未解决的任务中(但我想这是时间问题)-外部域的绑定以及对用作该函数触发器的http方法的微调。 现在,http触发器会针对自动生成的入口点(例如https://functions.yandexcloud.net/xxxxxxxxxxxxxxxx)的DELETE,GET,HEAD,OPTIONS,PATCH,POST或PUT请求中的任何一个触发。
好消息是,这是成熟的https,可以满足所有Telegram通过webHooks使用api的要求。 但是AWS Lambda具有API网关形式的附加组件,如果需要,触发器设置本身会更宽。
无论平台如何,无服务器方法本身都有明显的局限性-您必须完全使用它们提供的功能。 您不能使用不受支持的编程语言编写代码,也不能使用非标准的编译器/解释器参数。 可能还有其他限制旨在保护开发过程中的所有参与者。
如何创建.js文件以在Yandex.Cloud中工作?
通过网络界面的简短指南:
- 创建功能
- 在Web界面中使用任何名称和扩展名js创建文件
- 选择一个解释器-nodejs10或nodejs12
- 在文件中,我们在exports.myFunction中编写一个带有一个参数的函数(嗯,在exports的任意字段中)
- 指示函数的超时,RAM(128MB-1024MB,以128MB为增量),入口点(filename.myFunction)
- 公开功能
写入文件的函数可以:
通过输入参数获取http请求数据:
该函数不会以其纯格式接收请求,并且当然也不控制请求的进度-它仅在其参数中接收带有有关请求信息的对象 :
{ "httpMethod": "< HTTP >", "headers": "< HTTP->", "multiValueHeaders": "< HTTP->", "queryStringParameters": "< queryString->", "multiValueQueryStringParameters": "< queryString->", "requestContext": "< >", "body": "< >", "isBase64Encoded": <true false> }
回复http请求
根据文档 :
{ "statusCode": <HTTP >, "headers": "< HTTP->", "multiValueHeaders": "< HTTP->", "body": "< >", "isBase64Encoded": <true false> }
所以,星期五没事
首先,请看一下我们之前已经写过的东西-此类针对AWS Lambda货车和小型手推车的机器人的实现。
他们有一个问题-为了不重新发明轮子,并提供一个熟悉的界面,所有这些实现都在收到请求后向电报api服务器发起一个帖子。 但是您可以更轻松地完成此操作。
正如您在KDPV上所看到的,以及帖子开头的引号-通过webHook进行工作时,电报会监听对其更新消息的响应,以便了解它是否已被我们的机器人处理。 此外,他准备接受该消息作为相同答案的一部分。
根据文档,答案应仅包含一个功能(选中sendMessage和sendPhoto )。 对于许多项目来说,这就足够了。
我们将遵循传统,并向哈布罗夫查纳致以问候:
exports.input = function (data){ let body = JSON.parse(data.body); let answer = { "method":"sendMessage", "chat_id": body.message.chat.id, "reply_to_message_id" : body.message.message_id, "text" : ", Habr!" }; return { "statusCode": 200, "headers": { 'Content-Type': 'application/json' }, "body": JSON.stringify(answer), "isBase64Encoded": false } }
将设置设置为最小值:

并告诉Telegram我们将使用webHook:
curl -F "url=https://functions.yandexcloud.net/{secret_function_id}" https://api.telegram.org/bot{secret_bot_key}/setWebhook
仅此而已。 机器人正在运行。

您可以和他聊天: @YandexServerlessBot
总结-在某些情况下,无服务器非常便宜,方便,并且节省了大量时间,任何文档都应仔细阅读:然后它可能会令人惊喜。
如果您有兴趣,欢迎访问Yandex Cloud Functions 文档 ,从与其他云服务的集成到调试,负载计划等,有很多有趣的事情。
会议视频也可以在YouTube上获得 。
UPD :如进一步的研究所示(感谢IRT的帮助),tg服务器无需此类技巧即可访问,因此您可以安全地使用传统的api请求。