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

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

其中大多数不提供“干净”的通知系统,例如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 NothingPROPS = 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 Nothingcallback(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 proceedingreturn;}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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/346121.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dubbo 消费者也要暴露端口吗_一文详细解读 Dubbo 中的 http 协议

(给ImportNew加星标,提高Java技能)转自:Kirito的技术分享,作者:kiritomoe太阳红彤彤,花儿五颜六色,各位读者朋友好,又来到了分享 Dubbo 知识点的时候了。说到 Dubbo 框架支持的协议,…

非一致性访存系统_Hibernate事实:访存策略的重要性

非一致性访存系统在使用ORM工具时,每个人都承认数据库设计和实体到表映射的重要性。 这些方面引起了很多关注,而诸如获取策略之类的事情可能只是推迟了。 我认为,不应将实体获取策略与实体映射设计分开,因为除非经过适当设计&…

应用新的JDK 11字符串方法

在“ 使用JDK 11的Java字符串上的新方法 ”和“ String#repeat即将加入Java? ”,我讨论了JDK 11引入Java String的六个新方法。 可用的早期访问JDK 11构建已经包含了这些新方法,在这篇文章中,我将使用其中的一种早期访…

为什么需要切换到在线签署文档和合同

嘿,怪胎, 今天,我们为您带来一些不同。 无论您是开发人员,经理还是设计师,这都会提高您的生产力和效率。 对于公司和个人而言,良好地管理文书工作是强大基础的最重要部分之一。 将工作流程从纸质转移到数…

github怎么自动更新被人更新过的项目_GitHub 的这 8 个实用技巧,95%的人不知道...

知道的越多,不知道的就越多,业余的像一棵小草!编辑:业余草来源:https://www.xttblog.com/?p49881、一秒钟把Github项目变成前端网站GitHub Pages大家可能都知道,常用的做法,是建立一个gh-pages…

java 注解 属性 类型_收藏!你一定要知道的Java8中的注解

全文共3002字,预计学习时长6分钟海中有大量的注解!JavaSE 1.5中首次引入了注解。Java注解的目的是允许程序员编写关于其程序的元数据。在OracleDocs中,注解的定义是:“注解是元数据的一种形式,它提供的数据与程序本身无关。”注解可以在代码的…

camel 多个 to_具有多个查询参数的Camel CXF服务

camel 多个 to出色的Apache Camel团队忙于解决查询中多个参数的处理问题,这是一种解决方法。 希望本文将在下一版本的Camel中不再使用。 (目前,我使用2.7.5) 问题 大于1的查询参数作为null值传递给Camel-CXF服务。 假设网址中有四…

select * from where 三个条件_VBA学习笔记70: Select语句基础

学习资源:《Excel VBA从入门到进阶》第72集 by兰色幻想 这节课来详细讲解Select语句。 Select 字段 from 表 where 条件 例:从sheet1中筛选全部数据。 * 表示全部字符,无条件可以省略where。 Select * from [sheet1$] 如果是对表中特定单元格区域进行查找,可以在[sheet1$]的…

使用Servlet和Bootstrap上传Ajax文件

介绍 在本教程中,我们将检查Ajax文件上传如何与Servlet一起使用。 同样,我们将用Bootstrap装饰表单并通过jQuery Ajax上传ajaxify文件。 实作 基本的servlet实现是相同的。 因此,我们需要做的第一件事是更新我们的web.xml文件并为我们的应用…

linux文件系统dentry_Linux文件系统(四)---三大缓冲区之inode缓冲区 (内存inode映像 )...

在文件系统中,有三大缓冲为了提升效率:inode缓冲区、dentry缓冲区、块缓冲。(内核:2.4.37)一、inode缓冲区为了加快对索引节点的索引,引入inode缓冲区,下面我们看Linux/fs/inode.c代码。inode缓冲区代码1、一些数据结构…

使用这些先进的GC技术提高应用程序性能

应用程序性能是我们的首要考虑因素,垃圾收集优化是取得小而有意义的进步的好地方 自动化垃圾收集(与JIT HotSpot编译器一起)是JVM中最先进,最有价值的组件之一,但是许多开发人员和工程师对垃圾收集(GC&a…

mysql中lead_SqlServer2012中LEAD函数简单分析_MySQL

LEAD函数简单点说,就是把下一行的某列数据提取到当前行来显示,看示例更能解释清楚,先看测试用脚本DECLARE TestData TABLE(ID INT IDENTITY(1,1),Department VARCHAR(20),LastName VARCHAR(20),Rate FLOAT)INSERT INTO TestData(Department,L…

堆栈溢出回答了我们不知道的Java首要问题

您不应该错过的堆栈溢出问题集合: 这不是秘密; 我们都使用堆栈溢出。 它掌握了生命,宇宙以及几乎所有与代码相关的内容的答案。 该平台为开发人员,工程师和其他人员提供了一个找到他们所面临问题的答案的地方,或者至少…

sequelize连接mysql_node.js通过Sequelize 连接MySQL

node.js通过Sequelize 连接MySQL一.通过koa2脚手架构建项目1.1 安装koa-generator在终端输入:$ npm install -g koa-generator11.2 使用koa-generator生成koa2项目$ koa2 HelloKoa21成功创建项目后,进入项目目录,并执行npm install命令$ cd H…

杀java_java怎么杀掉java进程

展开全部java中有调用外部程序的e69da5e887aa62616964757a686964616f31333337623431类,Runtime.getRuntime().exec("./**.exe");此函数返回的是一个Process 对象,该对象在创建后,可以对它进行 destroy () 杀掉子进程、 waitFor () …

高级java开发_我最喜欢的Java高级开发人员书籍

高级java开发我上一篇博客文章 (我对高级Java开发人员的十个最喜欢的在线资源)的想法,是由Xiaoran Wang发表的“面向高级Java开发人员的十大网站”的启发。 Wang还写了一篇名为“面向Java高级开发人员的十大书籍”的文章。 就像关于高级Java开…

camera.swf java_java调用摄像头保存图片上传功能

在项目中要用到jsp页面实现网页采集摄像头图像,并实现上传的功能,页面主要js调用的,所以可以使用多种语言php,asp等都可以使用,而且是跨浏览器的。可以整合的到SSH项目中和struts1或者struts2项目中使用方法1:下载 pri…

java 北理工 教材_北理工《Java技术与应用》在线作业

北理工《Java技术与应用》在线作业可以代做所有奥鹏平台的作业、小论文、毕业论文、离线作业、考核作业、在线作业、在线测试,有需要的请联系本人一、单选题(共 20 道试题,共 40 分。)V1. Socket对象中____函数获取远程端口。A. getPort( )B. getLocalPo…

Apache Spark Job的剖析

Apache Spark是通用的大规模数据处理框架。 了解spark如何执行作业对于获取大部分作业非常重要。 关于Spark评估范式的简短回顾:Spark使用的是惰性评估范式,在该范式中,Spark应用程序在驱动程序调用“ Action”之前不会执行任何操作。 惰性…

scala本地调试_如何编写自己的Java / Scala调试器

scala本地调试在本文中,我们将探讨Java / Scala调试器的编写和工作方式。 诸如Windows的WinDbg或Linux / Unix的gdb之类的本机调试器通过操作系统直接提供给它们的钩子来获取其功能,以监视和操纵外部进程的状态。 JVM充当OS之上的抽象层,它提…