我的机器人现在无处可去。 无家可归。 无服务器。

我通常会关注各种网站-有关最新出版物,热门新优惠,限时游戏和竞赛等。

其中大多数不提供“干净”的通知系统,例如RSS feed。 因此,我经常不得不刮擦他们HTML才能达到我所需要的。

这意味着我经常需要运行一些自定义的字符串操作魔术来达到所需。

而且我需要它是周期性的(谁知道下一次热更新何时出现?)。

并且是自动的(我一天中还有很多重要的事情要做)。

并且是远程托管的(我不想让我的笔记本电脑不间断地运行24×7,并且互联网连接不中断)。

到目前为止,我一直依靠Google Apps脚本 (最近是Google App Engine )来驱动这类自制的集成“代码段”。 但是,随着整个世界沉浸在无服务器环境中 ,我为什么不这样做呢?

因此,我开始迁移我的一个脚本,该脚本是为监视中国零售网站而编写的。 该网站偶尔会发布各种折扣优惠和季节性游戏,在这些游戏中,我可以通过日常游戏获得不错的优惠券和积分。 但是由于某种原因,该网站没有向我的电子邮件地址发送促销电子邮件,这意味着我必须不时检查一下该网站,以确保不会错过任何有趣的内容。

而且您知道演习。

我很容易忘记事情。 有时,当我离开电脑时,也会想起提醒。 有时候,我懒得去找东西,因为我最终没有新鲜感,占75-80%的时间。 这么多借口...

此外,当您可以设置机器人,坐下来放松一下时,谁会在他们正确的开发人员心中想做那么无聊的事情呢?

我从AWS Lambda开始, AWS Lambda是免费的无服务器计算的明显选择。 它的非到期免费层使我每个月的运行时间达到了令人难以置信的320 (是, 百万 )秒–实际上,我可以使一个lambda永远运行,甚至更多! –调用次数超过1M (又是百万次!)。 以前,在App Script或App Engine上,我每天只有90分钟的时间,每月只有16万秒,这意味着我不得不非常谨慎地使用配额。 但是现在我可以放开恐惧,充分享受我的发展自由。 与Apps Script或App Engine的框架限制相比,更不用说完全成熟的容器环境了。

聊够了。 让我们编码吧!

我没有采用标准的方法 ,而是从SLAppForge中选择了Sigma作为开发框架。 主要是因为它在支持外部依赖项方面享有盛誉,并代表我负责打包和部署工作-包括所有外部服务(API,表,cron和诸如此类)。

首先,我必须注册Sigma 。 尽管我可以继续使用其演示功能(黄色的大按钮),但我已经拥有一个AWS账户和一个GitHub账户(更不用说电子邮件地址了); 那为什么不试一试呢?

无服务器

完成注册并登录后,我看到了一个项目选择窗格,在这里我选择了一个名为site-monitor的新项目:

该应用程序运行非常快,当我点击Create Project时,弹出编辑器:

事不宜迟,我抓住了以前的Apps脚本功能的内容,并将其放入Sigma!

let AWS = require('aws-sdk');

exports.handler = function(event, context, callback) {

    // Here Goes Nothing

    PROPS = PropertiesService.getScriptProperties();
    page = UrlFetchApp.fetch("http://www.my-favorite-site.com").getResponseText();
    url = page.match(/(lp|\?r=specialTopic)\/[^"]*/)[0];
    if (url != PROPS.getProperty("latest")) {
        GmailApp.sendEmail("janakaud@gmail.com", "MyFavSite Update!", url);
        PROPS.setProperty("latest", url);
    }

    // end of Here Goes Nothing

    callback(null,'Successfully executed');
}

(我知道,我知道那是行不通的。忍受我:))

接下来的几分钟,我花了我的Apps脚本代码转换为NodeJS。 一旦将request模块添加到项目中,就不那么困难了(毕竟都是JS!):

但是我必须说我确实错过了UrlFetchApp模块熟悉的同步语法。

在App Engine下,我拥有非常简单的PropertiesService来充当我的机器人的“内存”。 在Sigma(AWS)下,事情并不是那么简单。 经过一番环顾后,我决定使用DynamoDB (尽管我仍然觉得这太过头了)。

从页面中提取URL后,我需要检查是否已将其通知给自己。 等同于在我的表(以前称为PropertiesService )中查询现有条目。 在DynamoDB-land中,这显然是一个Get Document操作,因此我尝试将DynamoDB拖入我的代码中:

删除后,DynamoDB条目将转换为一个弹出窗口,我可以在其中定义表并提供代码级参数。 希望Sigma会记住表配置,这样我就不必在我的代码中一次又一次地输入它。

由于DynamoDB并不是简单的键值对象,因此我花了几分钟的时间来研究如何在其中存储“值”。 最终我决定使用表单的“文档”结构

{
    "domain": "my-favorite-site.com",
    "url": "{the stored URL value}"
}

在这里我可以使用每个bot的特定domain值查询表,从而将表重新用于不同的bot。

在我的旧代码中,我使用GmailApp.sendEmail()调用在收到新内容时向自己发送通知。 在Sigma中,我尝试通过拖放简单电子邮件服务( SES条目来做到这一点:

这里似乎有点打small,因为看来我需要先验证电子邮件地址,然后才能发送一些东西。 我不确定自己的骑行有多坎,,无论如何,我都输入了电子邮件地址,然后点击发送验证电子邮件

果然,我通过电子邮件收到了一个验证链接,单击该链接可以将我重定向到“验证成功”页面

猜猜是什么:当我切换回Sigma时,弹出窗口进行了自我更新,说明该电子邮件已通过验证,并指导我进行下一步!

我立即填写了详细信息( 我自己而言,没有CC或BCC,没有主题 MyFavSite Update!Text Body @{url} (它们自己的可变语法;但我希望它是${} )):

在SES电子邮件发件人的回调中,我必须更新DynamoDB表以反映已通过电子邮件发送的新条目(因此,我不会再通过电子邮件发送它)。 就像我原始漫游器中的PROPS.setProperty("latest", url)调用一样。

这很容易,而且拖放操作也很简单:在“ 现有表”下选择先前创建的表,然后选择domain设置为my-favorite-site.com (我的“搜索查询”;等同于"latest" ”)的"latest" 放置文档”操作 "latest"在旧BOT)和url条目集的电子邮件地址:

最终,我获得了相当不错的代码(尽管比我亲爱的旧版Apps Script机器人要长得多):

let AWS = require('aws-sdk');
const ses = new AWS.SES();
const ddb = new AWS.DynamoDB.DocumentClient();
const request = require("request");

exports.handler = function (event, context, callback) {
    request.get("http://www.my-favorite-site.com",
        (error, response, body) => {
            if (!body) {
                throw new Error("Failed to fetch homepage!");
            }

            let urls = page.match(/(lp|\?r=specialTopic)\/[^"]*/);
            if (!urls) { // nothing found; no point in proceeding
                return;
            }
            let url = urls[0];

            ddb.get({
                TableName: 'site-data',
                Key: { 'domain': 'my-favorite-site.com' }
            }, function (err, data) {
                if (err) {
                    throw err;
                } else {
                    if (!data.Item || data.Item.url != url) {
                        ses.sendEmail({
                            Destination: {
                                ToAddresses: ['janakaud@gmail.com'],
                                CcAddresses: [],
                                BccAddresses: []
                            },
                            Message: {
                                Body: {
                                    Text: {
                                        Data: url
                                    }
                                },
                                Subject: {
                                    Data: 'MyFavSite Update!'
                                }
                            },
                            Source: 'janakaud@gmail.com',
                        }, function (err, data) {
                            if (err) {
                                throw err;
                            }
                            ddb.put({
                                TableName: 'site-data',
                                Item: { 'domain': 'my-favorite-site.com', 'url': url }
                            }, function (err, data) {
                                if (err) {
                                    throw err;
                                } else {
                                    console.log("New URL saved successfully!");
                                }
                            });
                        });
                    } else {
                        console.log("URL already sent out; ignoring");
                    }
                }
            });
        });

    callback(null, 'Successfully executed');
}

Sigma一直试图通过提供方便的编辑帮助(代码完成,语法着色,变量建议等)来帮助我,甚至突出显示DynamoDB和SES操作并在前面显示小图标。 单击后,将显示(重新)配置弹出窗口,类似于我第一次将其拖放时得到的弹出窗口。

由于异步,基于回调的语法,我不得不在代码的n位片段中四处移动。 Sigma处理得很好,在我将代码粘贴到新位置后,再过一两秒钟重新进行了突出显示。

只是为了好玩,我尝试手动编辑代码(不使用弹出窗口),很公平的是,弹出窗口理解了更改并在下次检查时进行了更新。 对于一个新手来说很整洁,他们希望不花太多时间去完成文档。

现在,我该如何定期运行我的机器人?

Sigma在函数标题附近显示一个红色的闪电符号,并突出显示相同的event参数。 可能表明这是lambda的调用或触发点。

对。 他们的文档说的也是一样。

AWS文档Sigma自己的 文档向我介绍了CloudWatch计划的事件触发器 ,该事件触发器可以按预定义的时间表触发lambda,例如Apps Script触发器,但功能强大得多。 更像App Engine cron表达式

如他们的文档所述 ,我将CloudWatch条目拖到了event变量上,并进行了如下配置:

整个event从红色变为绿色,这可能表明我的触发器已成功设置。

对。 该测试一下了。

工具栏上有一个“ 测试 (播放)”按钮,带有一个下拉菜单以选择您的测试用例。 与Apps Script一样 ,但从某种意义上讲,它可以定义调用的输入有效负载(而Apps Script只是运行没有任何输入参数的函数)就更好了:

配置好测试用例并单击运行按钮后,状态栏即开始显示运行进度:

几秒钟后,会自动弹出SigmaTrail日志输出窗口,并开始显示一些日志:

errorMessage:"RequestId: 87c59aba-8822-11e8-b912-0f46b6510aa8 Process exited before completing request"
[7/15/2018][5:00:52 PM] Updating dependencies. This might make runtime longer than usual.
[7/15/2018][5:00:55 PM] Dependencies updated.
[7/15/2018][5:00:57 PM] ReferenceError: page is not defined
at Request.request.get [as _callback] (/tmp/site-monitor/lambda.js:13:24)
at Request.self.callback (/tmp/site-monitor/node_modules/request/request.js:185:22)

糟糕,看来我弄错了变量名。

一个简单的编辑和另一个测试。

[7/15/2018][5:04:50 PM] ResourceNotFoundException: Requested resource not found
at Request.extractError (/tmp/site-monitor/node_modules/aws-sdk/lib/protocol/json.js:48:27)
at Request.callListeners (/tmp/site-monitor/node_modules/aws-sdk/lib/sequential_executor.js:105:20)

嗯,那是什么意思?

看起来这是来自AWS开发工具包本身的。

也许我拖放到应用程序中的AWS“资源”在AWS端尚不可用; 此外,许多Sigma教程在进行测试之前都提到了“部署”步骤。

哦,好,让我们尝试部署这个东西。

我希望能够进行无缝的“一键式部署”,但是当我单击“ 部署”按钮时,出现一个弹出窗口,提示我需要向GitHub进行身份验证。 Sigma可能会将我的东西保存在GitHub存储库中,然后将其用于其余的部署。

看到没有恶意,我单击了登录,并在随后的弹出窗口中授权了他们的应用程序。 几秒钟后,我又弹出一个窗口,要求我选择一个存储库名称和一个提交消息。

我的帐户中没有回购site-monitor ,因此我很想知道Sigma会做什么。 正如我怀疑的那样,单击“ 提交”几秒钟后,又弹出一个对话框,询问我是否希望它代表我创建一个新的仓库。

Sigma非常善良,甚至提供创建私有存储库的机会。 但是可惜的是,我没有那么奢侈,所以我只单击了Create Repo and Commit

从那时起,一切都变得相当自动化:在“成功完成”通知之后,出现了一个非常快的“构建”步骤(伴随着底部状态窗格中的进度条)。

接下来,我又弹出另一个窗口,这次是“ 变更摘要” ; 再过几秒钟,就会在其中填充“部署摘要”:

我对底层细节不怎么感兴趣(尽管我确实cweOneAM识别为我的cron触发器,将siteMonitorLambda为我的机器人),所以我只是点击Execute ; 这次等待了相当长的时间(伴随着另一个进度条,这次是在弹出窗口中)。

一旦达到100%,Sigma表示我的部署以CREATE_COMPLETE状态完成(听起来不错!)。

现在,让我们再次尝试测试。

"Successfully executed"
[7/15/2018][5:39:34 PM] New URL saved successfully!

好极了!

等等,如果我再次运行它,它会重新发送吗?

"Successfully executed"
[7/15/2018][5:39:41 PM] URL already sent out; ignoring

都好; 没有重复!

现在检查我的收件箱,看看Sigma是否在说真话。

最初,我有点困惑,因为我实际上没有收到电子邮件。 但最终我发现它位于我的Spam文件夹中(可能是因为它是由第三方(AWS)发送的?),并取消了标记,因为它起到了垃圾邮件的作用。

希望我的CloudWatch触发器明天明天凌晨1点触发,如果有的话,给我带来了好消息!

总而言之,图形化IDE非常漂亮,值得同事们推荐。 除了部署时间(我认为这是无服务器应用程序,Lambda或也许是AWS的特征)之外,我几乎感觉到了家–甚至所有这些漂亮的功能-自动完成,拖放,GUI配置,测试,日志等。

是时候喝杯咖啡了,然后开始将我的其他机器人迁移到Sigma…嗯…AWS。

翻译自: https://www.javacodegeeks.com/2018/07/bots-placeless-homeless-serverless.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值