LeanCloud施富辰我们生活中接触到的很多互联网服务都有定时发送个性化邮件提醒的功能。有一些项目管理应用程序会定期向用户发送即将到来的待办事项的摘要。作为应用开发者,我们如何实现这样的功能呢?许多批量电子邮件服务提供商允许您设置一个时间间隔来自动向用户发送电子邮件,但此类服务的缺点是内容不能高度定制。通常您可以在电子邮件模板中插入用户列表中可以找到的姓名、职位和其他信息,但这些信息是静态的。如果我们想让邮件内容根据用户的实际使用数据动态生成(比如在还款提醒中插入还款金额),那么就必须有某种机制从应用数据库中拉取用户相关的数据(通常是某些计算)仍然需要),这是基于模板的群发服务无法做到的。另外,如果你需要在不同的时间向不同的用户发送提醒(例如,不同的信用卡客户有不同的账单日期,或者应用允许用户自定义接收提醒的时间和频率),那么如何管理发送时间成了问题。因此,如果要给用户个性化的提醒,就需要维护一个独立于群发邮件服务商的定时器。这个计时器应该能够主动访问应用程序数据库,并根据获取的数据执行特定的代码;同时,选择一个支持通过API调用发送邮件内容和收件人的邮件服务商,让之前的定时器在需要发送邮件时将相关数据传入API。该代码从数据库中获取数据并根据数据编写电子邮件。我们做了一个演示来展示如何实现这些功能。该演示包括一个基本的Todo应用程序。用户可以创建Todo项目并为每个项目设置截止日期。Todo会保存在LeanCloud的数据存储服务中。本Demo还包含了一个云函数(可以在云端执行的代码)查询是否有某个时间段内到期但还没有完成的项目。如果是这样,它将调用SendGrid的API将包含这些项目的邮件发送到固定地址。这个云函数会托管在LeanCloud云引擎上,每隔一段时间执行一次。准备为了顺利运行demo,请确保您分别拥有LeanCloud和SendGrid账号。如果没有,可以去各自的官网注册:LeanCloud:https://www.leancloud.cn/SendGrid:https://sendgrid.com/前端部分先把Demo克隆到本地,然后使用包含Todo应用程序前端的编辑器.html打开索引。它满足以下需求:用户可以创建Todo项。创建待办事项时,提供标题和截止日期。该应用程序在列表中显示所有待办事项,包括它们的标题和截止日期。每个Todo都有一个复选框,可以在“未完成”和“已完成”之间切换。Todo创建后默认为“未完成”状态。每个Todo都有一个“删除”按钮,可以将其从列表中删除。代码基于Vue.js编写。以下是对部分的解释:
NewTodo
下面的表单绑定了data.newTodo中的数据。点击“Create”会触发add方法,从data.newTodo中获取数据,创建一个Todo对象(这个对象有一个title属性表示标题,一个due属性表示截止时间,还有一个completed属性表示是否Completed,默认为false),并保存到LeanCloud云端。fetchTodos方法将从LeanCloud云中获取所有Todo对象,并用它们替换data.todos。data.todos中的数据会呈现在
Todolist
下方。当某个Todo项的复选框被点击时会触发toggleCompleted方法,它会根据复选框的状态更新相应Todo对象的completed属性(选中为true,未选中为false),并将修改最终对象保存到LeanCloud云端。当点击某个Todo项的“删除”按钮时会触发remove方法,从LeanCloud云中删除对应的Todo对象。fetchTodos会在页面加载完成后运行一次,将数据库中已有的Todo项拉取到前端。add、toggleCompleted、remove在完成各自的操作后也会触发一个fetchTodos刷新前端的Todo列表。LeanCloud数据存储SDK的使用请参考官方指南。在运行demo之前,我们先去LeanCloud创建一个存储数据的应用。在LeanCloud控制台首页点击“创建应用”,填写任意应用名称,然后点击“创建”,再点击应用名称进入应用管理界面。点击左侧“设置”中的“应用密钥”,找到“AppID”、“AppKey”和“RESTAPIServerAddress”分别填入index.html中的appId、appKey和serverURLs,然后保存文件。现在您可以直接在浏览器中打开此文件并尝试我们之前提到的那些功能。尝试填写标题、日期、时间并单击“创建”。如果您输入的内容出现在“待办事项列表”中,则证明该待办事项已成功保存到LeanCloud。现在回到LeanCloud控制台,点击左侧的“Storage”,再点击“Todo”类,可以看到刚才创建的所有Todos:Todo表包含了刚刚创建的Todo项目云函数接下来,我们准备云函数。我们希望每30秒检查一次是否有任何未完成的项目在第二天(24小时)内到期,如果有,请发送电子邮件。实现的思路是:写一个查询,找到due位于当前时间一天内completed为false的Todo对象。如果查询返回1个或多个对象,则调用SendGrid的API以发送一封电子邮件,其内容是根据这些对象中包含的数据生成的。将以上逻辑打包成一个云函数。每30秒运行一次云函数。cloud.js中名为checkTodos的云函数中已经实现了上述逻辑中的第1至3项,但是为了正常发送邮件,我们还需要从SendGrid获取一个APIKey。我们打开SendGrid控制台,点击左侧“EmailAPI”,进入“IntegrationGuide”,选择“WebAPI”,然后选择“Node.js”:下一界面第二步SendGrid界面截图即可填写一个名字,然后点击“CreateKey”,就可以得到一个APIKey:SendGrid界面截图,填入cloud.js中的sgMail.setApiKey。另外,在后面填写你的邮箱地址,这样后面我们测试代码的时候,你就可以接收和查看应用发送的邮件了。至此,我们的Todo应用的前后端代码就准备好了。我们要做的最后一件事是将其部署到LeanCloud云引擎并设置计划任务。部署和设置定时任务如果您还没有安装LeanCloud命令行工具,请按照此处的说明进行安装。安装并登录LeanCloud账号后,将本地项目关联到LeanCloud上的应用,然后运行leandeploy进行部署。部署完成后,打开LeanCloud控制台,点击左侧“云引擎”,进入“计划任务”,然后点击“创建计划任务”。名称随便填,在“请选择一个功能”下拉列表中选择“checkTodos”,勾选“周期性任务间隔时间”并在下方填入“30”,最后点击“保存”。你完成了!你现在可以尝试创建几个在当前时间24小时内过期的Todo项,过一段时间你应该可以收到类似这样的通知邮件:ListtheemailsofTodoitems注意:如果你不执行计划任务上的其他操作,则它将永远运行。确保在每次测试完成后暂停或删除cron作业。现在您已经掌握了如何定期向用户发送包含自定义内容的电子邮件。其实还有很多其他的方式可以发挥定时任务的功能,比如定时清理垃圾数据,定时生成统计报表等等。如果你觉得这是一个不错的功能,不妨自己根据Demo中的代码做一些修改,尝试做一些更有趣更实用的功能。