0x00 写在前面
我家小区里使用的是丰巢快递柜,每次快递寄达后,都会收到一条来自丰巢的短信:
【丰巢】请凭取件码『12345678』到XXXX取XX快递的包裹。
理想的情况当然是在收到短信以后马上去取,但实际上常常因为不在家里或者暂时没空,只好等有空的时候再去取快递。而等到自己有空时,却怎么也想不起来还有个快递要拿,等到想起来的时候又已经超时了。
待办事项软件是一个可以完美解决此问题的工具。当收到丰巢的短信时,只要创建一条待办事项,设置好提醒时间(或者设置位置提醒),就能够按时或按地点提醒自己去领取快递。
但每次收到短信都手动创建待办事项实在是太过麻烦。因此,本文就尝试通过 Tasker,实现收到丰巢的短信时,自动添加待办事项,提醒自己领取快递。
0x01 什么是 Tasker
Tasker 是一款 Android 平台的自动化工具应用。所谓「自动化」,也就是说,用户设定了一定的规则以后,当遇到合适的条件,Tasker 就会自动执行相应的任务。
Tasker 具有多种触发的条件,几乎囊括了手机上的所有功能。例如接到电话、收到短信、打开某个应用、到达指定位置、日历日程的开始、扫描到NFC标签、手机的翻转和移动、文件的修改与删除,甚至是在其他 App 内执行了某项操作,都可以作为 Tasker 执行任务的触发条件。
除了具有各式各样的触发条件,Tasker 还允许用户执行各类动作,不仅能调用手机本身的硬件功能,还能与其他第三方 App 协同工作,实现跨应用的自动化任务执行。
Tasker 具有如此多且强大的功能,本文就介绍如何通过 Tasker,实现为快递短信创建待办提醒。
在正式开始前,首先要安装好 Tasker 应用和授予相关权限。你可以在Google Play下载 Tasker。
![Tasker 在 Google Play 上是一款付费应用](https://maronyea.me/wp-content/uploads/2020/09/E4AE10B6-16A6-459B-B6AE-8DBF87ED468C-1.jpeg)
注意,Tasker 是一款付费应用。如果条件允许,请尽量支持正版。
由于我使用的待办任务工具是 Todoist,因此本文主要介绍向 Todoist 添加待办事项的流程。如果使用其他待办事项清单工具,可能要针对该平台修改 Tasker 执行的任务。
0x02 怎样向 Todoist 添加任务
Todoist 最大的特点就是开放。它提供了多种添加任务的方式,包括从应用内添加、通过快捷方式添加、通过 IFTTT 添加、通过邮件添加、通过 IFTTT 等自动化平台添加、通过 Python 程序添加、通过 API 接口添加等。
由于接收短信的是手机,所以主要考虑手机平台可以运用的方式,有这样几种:
- 从应用内添加任务:这种方法一般是打开应用,再点击应用中的按钮、逐一输入内容来添加。如果要想实现自动化的话,就得模拟点击屏幕,难度较大。
- 通过快捷方式添加:依旧是要模拟点击屏幕,难度较大。
- 通过IFTTT添加:通过触发IFTTT规则实现添加预定内容的任务,这种方法问题在于IFTTT在大陆地区访问较慢,而且成功率不算高。
- 通过Python程序添加:可以,但没必要。太麻烦了。
- 通过API接口添加:通过POST请求发送内容至Todoist的服务器,这种方法比较快捷,而且很容易实现自动化,但参数的设置比较麻烦。
综上几种方法,我最终选择了通过API接口的方式添加待办任务。
首先打开 Todoist 的 API 文档页面https://developer.todoist.com/:
![哦豁,全英文](https://maronyea.me/wp-content/uploads/2020/09/9CC10C9A-9747-49F9-BD79-DC715E31417A-1-scaled.jpeg)
默认显示的是 Sync API,如果你觉得 Sync API 比较啰嗦,也可以换成 REST API。不过本文是基于 Sync API 实现的。
看到左边的菜单栏,因为是「收到短信就创建提醒」,所以选择「Items → Add an item」。
![看到「Items → Add an item」](https://maronyea.me/wp-content/uploads/2020/09/DraggedImage.png)
这里列举出了创建一个待办事项的所有参数,有些是必须要有的,有些是可有可无、看自己需要的。我总结一下,这些参数是必须的:
token
:这个是用户独一无二的标志,当你提交数据到 Todoist 的服务器时,就不需要输入用户名和密码,直接通过 API Token 识别你的身份;temp_id
和uuid
:提交数据时,通过temp_id
和uuid
来判断你是否重复提交了数据。这对于网络较差的情况非常有用,可以避免创建多个相同的待办任务;content
:也就是待办任务的标题。
其中,temp_id
、uuid
和 content
都是用户自己设置的,而 token
是需要在 Todoist 官网上申请的。所以接下来,打开 Todoist 的官网https://todoist.com/app/,在登录账号后,点击页面右上角的设置按钮,在弹出的菜单中选择「设置」。进入设置页面后,选择「关联应用」菜单,在页面最下方就能看到一个「API 置换符」。将该置换符复制下来,一会儿就要用到。
![在官网设置页面中复制 API 置换符](https://maronyea.me/wp-content/uploads/2020/09/0386BDFC-9721-48D5-9FAB-FA719409E148-scaled.jpeg)
0x03 在 Tasker 中创建任务
获取到 API 置换符,也就是 token
以后,接下来就是在 Tasker 中创建任务,实现从 Tasker 中通过 Todoist API 创建待办任务。
提醒一下,由于 Tasker 中执行的一系列动作称为「任务」,和 Todoist 中的「待办任务」名称类似,因此当我写到「任务」时,请注意这个「任务」到底是哪个「任务」。
创建任务
打开 Tasker,选中「任务」选项卡,点击右下角的悬浮按钮,然后输入任务的名称,这里将任务名称设置为「测试」。将来也可以更改这个任务的名字,所以不用太在意。
![点击界面右下角的按钮,创建一个新的任务](https://maronyea.me/wp-content/uploads/2020/09/99C64776-9EE0-469C-BD3B-FAB100BF5D44-scaled.jpeg)
设置 Todoist API 置换符
接下来会进入任务的编辑页面,点击右下角的悬浮按钮,点击操作类别「变量」,选择「变量定义」。
![选择「变量」→「变量定义」](https://maronyea.me/wp-content/uploads/2020/09/7C07358B-E867-442D-8D58-22028676C1ED.png)
在该页面中,将「名称」设置为 %token
,「发往」粘贴为刚才复制的 Todoist 的 API 置换符。如果想要备注一下这一步是在干什么,还可以勾上「标签」,然后输入「设置 Todoist 的 API 置换符」,或者其他备注内容。设置完成后,直接点击左上角的返回按钮即可自动保存。
![将复制来的 API 置换符赋值给 %token 变量](https://maronyea.me/wp-content/uploads/2020/09/6F9591B1-ABDA-403F-AE9B-0708255C1013.png)
设置待办任务的参数
设置了 API 置换符后,就轮到待办任务的参数了,包括:
- 待办任务标题:
%content
- 待办任务所属的项目:
%project_name
- 到期时间:
%due
- 标签:
%labels_name
- 重要性:
%task_priority
还是使用「变量定义」,逐一设置好这些参数。如下图所示。
![设置待办任务标题、项目、标签、到期时间与重要性](https://maronyea.me/wp-content/uploads/2020/09/7BF4E55E-960C-4C5A-B3D8-E430C62CAA46-1.png)
有两点需要注意:
- 如果你不打算把待办任务添加到某个指定的项目中去,而是将待办任务保存在收件箱中,那么只要设置
%project_name
的值为Inbox
即可。 - 如果你要设置多个标签,那么就用上图右边这种方式,每输入一个标签名就换一行。例如图中就是为待办任务设置了「下楼」和「15分钟」这两个标签。
设置参数并上传 Todoist 的 API 服务器
继续点击右下角的按钮,在「代码」中,找到一个名为「JavaScriptlet」的动作,点击添加该动作。
![添加「JavaScriptlet」动作](https://maronyea.me/wp-content/uploads/2020/09/597230C6-A2A1-4801-8883-5E7206FD6BCC-1.png)
注意别看错了,不是「JavaScript」,而是「JavaScriptlet」。
在「代码」输入框中,输入如下代码:
var project_id = "";
var labels_id = [];
var url = "https://api.todoist.com/sync/v8/sync";
var method = "POST"
var xhttp = new XMLHttpRequest();
xhttp.open( method, url, false );
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhttp.send('token=' + token + '&sync_token=*&resource_types=["projects", "labels"]');
var response = xhttp.responseText;
for (var i in JSON.parse(response).projects) {
var name = JSON.parse(response).projects[i].name;
if (unescape(name.replace(/\\u/g, '%u')) == project_name) {
project_id = JSON.parse(response).projects[i].id + "";
}
}
var labels_name_list = labels_name.split("\n");
for (var i in JSON.parse(response).labels) {
var name = JSON.parse(response).labels[i].name;
for (var j in labels_name_list) {
if (unescape(name.replace(/\\u/g, '%u')) == labels_name_list[j]){
labels_id.push(JSON.parse(response).labels[i].id + "");
}
}
}
var uuid = ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
var temp_id = ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
var commands = '[{ "type": "item_add", "temp_id": "' + temp_id + '", "uuid": "' + uuid + '", "args": { "content": "' + content + '", "project_id": "' + project_id + '", "due": {"string": "' + due + '"}, "priority": ' + task_priority + ', "labels": [' + labels_id + '] } } ]'
var http = new XMLHttpRequest();
http.open( method, url, false );
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
http.send('token=' + token + '&commands=' + commands);
如下图所示:
![输入 JavaScript 代码](https://maronyea.me/wp-content/uploads/2020/09/BDE78042-26FC-4FE2-8984-30819F15048E-1.png)
上面的这一串代码中,包含了从 Todoist 的 Sync API 中根据项目名、标签名获取到项目 ID 和标签 ID,以及生成 uuid
、temp_id
,提交待办任务数据至 Todoist 这样几个步骤。因此,在添加完这一串代码以后,实际上就可以实现「向 Todoist 添加待办任务」的功能了。此时,你可以点击一下左下角的三角形按钮「▶︎」,可以执行一遍所有步骤。
当你看到界面上全部显示绿色的小圆点时,表示该任务已经执行完成了。现在打开 Todoist,刷新一下,你应该就能看到新添加的待办任务了。
![在 Todoist 中可以看到刚刚创建的待办任务](https://maronyea.me/wp-content/uploads/2020/09/9BD97062-07E4-49C0-B62D-843D11212E16-1.png)
0x04 为任务设置配置文件
不过到目前为止,还只是实现了从 Tasker 中添加待办任务至 Todoist,并没有实现获取「取货码」,并将取货码设为待办任务的标题。因此,我们还需要设置触发 Tasker 任务的条件,并对 Tasker 任务进行一些改造。
创建配置文件
现在返回 Tasker 应用,回到主页面下的「配置文件」选项卡。所谓「配置文件」,就是指触发 Tasker 任务的条件。只有设置配置文件,才能让 Tasker 知道什么时候执行我们刚才设置的任务。
将配置文件名称设为「短信:取快递」——当然也可以设置成别的名称——然后选择「事件」,再选择「电话→收到短信」。
![创建配置文件](https://maronyea.me/wp-content/uploads/2020/09/6798F6D2-6DFB-4574-804D-436C2644A708-1.png)
接下来会显示一个界面,让你设置收到什么样的短信、收到谁的短信、收到什么内容的短信、哪个 SIM 卡收到短信时,触发指定的待办任务。不过我们这里不用填任何东西。因为快递短信一般是服务器下发的,没有固定的号码。而内容也暂时不用管,因为我们接下来要到 Tasker 任务中去设置过滤接收短信。
点击左上角的返回按钮,就会弹出一个列表,让你选择该配置文件触发什么任务。选中刚才创建的「测试」任务即可。
让任务读取到短信的内容
重新打开刚才创建的「测试」任务,继续添加「任务→If」动作。在左边的输入框中输入 %SMSRB
,这个变量是一个特殊变量,它能够读取到最近一条短信。点击中间的按钮,选择「匹配正则表达式」,并在右边输入「丰巢」。
点击返回以后,长按新增的这个「If」动作,向上拖拽到顶部,就能把其他的所有动作包含进来。这样,就只有当收到短信内容中包含有「丰巢」的短信时,才会创建 Todoist 中的待办任务了。
![添加筛选短信的条件](https://maronyea.me/wp-content/uploads/2020/09/1EC9FD1F-F8B3-4F1C-B1B7-E55AEAC95B6B.png)
但是还没结束——因为待办任务的标题中还没有包含取件码!
刚才已经说了,%SMSRB
这个变量的内容是最近一条短信。所以,只要将这个变量中的取件码提取出来,那就可以可以向待办任务的标题中添加取件码了。
为了提取取件码,就要用到「变量搜索替换」这个动作。这个动作可以从一个变量中提取出符合条件的内容。
选择「变量→变量搜索替换」,将「变量」设置为 %SMSRB
,再把「搜索」设置为 \d{8}
,这表示搜索连续的 8 位数字。
随后勾选「只匹配一次」,在「将匹配存储到」中填入 %qjm
,表示将提取出来的 8 位数字取件码保存到变量 %qjm
中。
点击返回,随后长按该动作,调整顺序,把它放到「If」后面。
![获取取件码](https://maronyea.me/wp-content/uploads/2020/09/C601A463-33E6-4371-8CF4-808D761C51FF.png)
接着编辑刚才设置的 Todoist 待办任务标题,把变量 %qjm1
加上去。注意,这后面是有个 1
的,这表示提取到的第一个结果。如果不加这个 1
,就不会正常显示刚刚提取到的取件码。
![设置待办任务标题,注意不要漏了后面的「1」](https://maronyea.me/wp-content/uploads/2020/09/D8B91FFE-A734-40ED-9678-0D3B2E427A89.png)
整个 Tasker 任务的动作顺序如上图右边所示。至此,整个 Tasker 任务已经编辑完成了。
测试一下!
虽然配置已经全部完成了,但是还没有检验一下到底能不能行。现在,随便找一台手机(借朋友的也行),给自己的手机发一条短信吧:
【丰巢】请凭取件码『12345678』到XXXX取XX快递的包裹。
如果不出意外的话,过一会儿,你就会在 Todoist 中看到这样的待办任务了:
![含有取件码的待办任务会更加方便](https://maronyea.me/wp-content/uploads/2020/09/AD8CA826-09D4-4C53-9801-D536CF0CB033-1.png)
大功告成!
0xFF 写在后面
可能看完上面你会觉得:实在是太麻烦了!
但是其实只要配置完一次,之后你就不用再管了,它只会默默地执行。而除此之外,由于有了这样一个模板,稍微修改一下,就能拓展出许多类似的任务。在后面还会介绍,基于这样一套模板,还可以怎样用好 Tasker 和 Todoist,方便提醒我们不要遗漏任何事。
当然,你也可以点击下方链接下载本文创建的 Tasker 任务文件进行导入,这样就不用自己手动设置各种各样的步骤了,直接修改一下 API 置换符就行。
下载到手机后解压,选中「任务」选项卡,然后再点击一次,就会弹出导入到选项。找到刚刚解压出来的 XML 格式任务文件导入即可。
![选择「导入一个任务」](https://maronyea.me/wp-content/uploads/2020/09/B06C58B6-ECA9-4FD5-BC55-6785585E9AB2.png)
本文到此结束。