知识点:
- 操作:词典(Dictionary)
- 操作:替换文本(Replace Text)
- 操作:从输入中获取词典(Get Dictionary from Input)
- 捷径技巧:「获取 URL 内容(Get Content from URL)」中请求体(Body)的用法
- 捷径技巧:将 JSON 中的两条信息合为词典使用,做到选标题,传 ID
解决了认证问题之后,我们就铺垫好了地基,接下来就能进一步来在捷径中打造一个顺手的 Toggl 应用了。最开始,我们先来实现它功能里最主要的部分,也就是做到能够启动你 Toggl 中预设的计时器。
那么在制作 Toggl 的小程序之前,我们还要先简单了解一下 Toggl 的基本逻辑与结构。
Toggl 的逻辑与结构
Toggl 里的最小组成单位是一个个计时器,就像这样:
而每个计时器主要由两个东西组成:
- 这个计时器所处的项目(Project)
- 你对这个计时器的描述(Description)
计时器的项目与描述
上图左侧,黑色的字是描述。描述就是描述你这段时间做了什么,所以也可以当成任务(Task)去写。绿色的字是项目,项目的意义是最后它能出现在 Dashboard 里,给你一个饼状图的反馈:
饼状图里不会出现描述,只会出现项目,而且颜色是你在创建每个项目时预设的颜色,这里是我的项目列表:
我的思路大致是:
- 学校——绿色——对应数字「1」
- 工作——黑色——对应数字「2」
- 个人——蓝色——对应数字「3」
这个颜色方案我在日历、Todoist、Mac 上的标签颜色……都是一致的,我们对颜色的识别效率要比文字高,因此这些为任务或者项目指定的颜色并不应该按心情随机支配,而是应该让它们对应着身份,而且应该在各个工具进行统一。关于这一点,@文刀漢三 写过一篇 Power+ 文章《颜色与身份》有更详细的说明。
而使用数字主要是因为在使用应用时,用数字匹配项目要比输入文字快得多。
在 Toggl 里,当你开始一个计时器,需要先填写描述的部分,就是你现在在干什么。随后是选择项目,或者说指派项目。这其实和很多任务管理工具思路是一致的,你先把任务名写出来,再去把它放到它应该在的项目里。
项目所在的工作区
在项目之上,Toggl 中还有一个概念,是工作区(Workspace)。什么是工作区,或者说工作区该怎么用呢?这个问题应该通过实践来解答。
不同的工作区之间有两个不通用:
- 项目不通用
- Dashboard(统计数据和饼状图)不通用
所以,当我们想掌握个人的时间使用情况时,也就是我们需要通过一张饼状图,来看我们在工作、学业、个人上的时间分配时,我们应该把这些事都放到一个工作区。
但是,如果一个公司或者团队,特别是远程工作的团队,需要掌握员工的工作时间,那么这些员工应该都在同一个工作区里,形成一个 Team。同时每个员工都有他们的颜色以及项目。在统计过一段时间后,我们可以用一个饼状图,看出所有人都做了什么事,用了多少时间:
所以一般来说一个人用一个工作区就够了,但是如果他有不同的工作和兼职,同时这些职务要求他加入到不同的工作区,他就需要建立或者加入新的工作区。
我个人有两个工作区,这也会在稍后的教程里,调用 API 的时候显示出来。
Toggl 逻辑与结构小结
读到这里,如果你没有用过 Toggl 的话,只要记得下面两点就足够:
- 在启动 Toggl 的计时器时,要填写计时器的描述以及它所在的项目。
- Toggl 的结构是:工作区——项目——计时器
我们在通过 API 创建计时器时,需要写描述,还需要通过 API 获取到你的工作区和项目,并且进行选择,把计时器指定到某个项目以及工作区中去。
用 Toggl 的 API 在捷径中创建计时器
理解了 Toggl 的逻辑和结构之后,我们就要着手开始实现我们的想法了。
首先,我们要在 Toggl 的 API 文档中找到创建计时器的请求链接。我们想想,创建新计时器,肯定离不开「Start」这个单词。在 Toggl API 总目录里一搜,我们就发现了,「Time entries」1 这个类别下面有「start a time entry」这个选项,很像是我们需要的:
打开「Time entries」的文档,找到我们想要的链接:
https://www.toggl.com/api/v8/time_entries/start
接下来,我们就要看,发起这个请求需要填写哪些元素了:
- 方法,是「POST」
- 需要授权(这是肯定的,不然你创建的计时器要跑到哪去)
接下来,就是这个文档写得不清楚的地方了,它没有很清楚地写明其它必要的信息点,但是我们可以根据它的例子来推测。
我们可以自己先来想一下,我们肯定还需要填写这些东西:
- 描述,即任务描述
- 项目,即计时器所在的项目
在文档中搜索「Required(必须)」,还能发现一个参数 created_with
也要填:
综上,那现在,我们在创建一个计时器的时候,有 5 项必须要填的东西:
- 方法,我们已经知道了,是「POST」
- 需要授权,授权方式我们已经知道了(见上篇文章)
- 任务描述,这个我们可以在添加的时候临时填写
- 项目,其实这里要求的是 Project ID,而不是项目名称,我们目前还没有
created_with
,这一项的意思是你发起请求的客户端是什么,这里我们可以随便填,比如说可以写shortcut
所以这 5 项必须要填的东西里,我们已经有了 4 项,只剩下 Project ID 没有搞定。那么我们接下来就来看看如何获取我们需要的 Project ID。
用捷径获取 Toggl 的 Project ID
我们需要回想起来 Toggl 的层级结构,在项目(Project)之上,还有一个工作区(Workspace)。想要获取项目的 ID,还要先获取工作区的 ID,要一层一层向下走。
那么我们就先来获取工作区的 ID。获取工作区的 ID 要使用的请求链接是:https://www.toggl.com/api/v8/me
,2 方法是「GET」,需要授权。在捷径中,我们需要的操作组合如下:
先是「URL」,其中填写的链接就是前面提到的请求链接。
再是「获取 URL 内容」,方法我们选择「GET」,在头部我们按照 Toggl 的授权格式,把「键」的位置填上 Authorization
,在后面「文本」的区域,我们填上 Basic 之前编码过的登录信息
,注意「Basic」和登录信息之间有个空格。随后我们就可以发起请求,从中获取工作区的 ID3 。
请求的结果如下:
虽然很乱,但是一般看到它就说明成功了,接下来我们把它转一下格式即可:
转完格式发现,在「data」这个层级之下的「workspaces」里,有 2 个结果:
- 「name」是「Life」的这个工作区,它的「id」是「1642117」
- 「name」是「sspai」的这个工作区,它的「id」是「3097276」
这样,我们就知道了我这 2 个工作区的标题和 ID,接下来的问题,就是有没有什么办法可以把 ID 和标题绑定在一起,让我们可以选择标题,传输 ID。也就是从左边这样,做到右边这样:
捷径技巧:根据文本制作词典
解决这个问题需要对捷径的了解到达一定地步,也就是需要理解捷径处理数据的本质。这样的本质有很多,比如我们之前已经知道,列表不一定是「列表」这个操作搞出来的东西,只要是多项结果,它就可以是列表。而在这,我们要掌握的另一个本质,就是只要满足什么条件,就能在捷径中制作一个词典。我们接下来来一点一点实现它。
首先,回到我们的 JSON 数据,这个时候,我们已经知道,在「data」这个层级之下的「workspaces」里,有我们想要的工作区标题与 ID。
那么,我们就是要分别获去它们,然后把它们组在一起。分别获取它们的方法很容易:
我们首先用「获取词典值」拿到「data」这一层的数据,再同理拿到「workspaces」里的数据。接下来,因为「workspaces」之下有两组数据,所以我们要用「重复」来获取其中的数据。而且因为我们要从每组数据中获取 2 个信息(1 个是 id,1 个是标题),所以在获取第二个信息时,要使用「为每个项目重复」4 。
至此为止,我们已经做到了获取我们想要的工作区的名称和 ID,接下来,就是如何把它变成词典的样式供我们选择了。
首先,我们要在「重复」里加一个新的操作「词典」:
它左边的「键」是我们获得的工作区的标题(Name),右边的「值」是工作区的 ID。把它放在「重复」操作内部,是因为我们两个工作区都需要,所以在重复之后,这个操作可以帮我们组合出一套带有字典格式的结果,接上「合并文本」后可以看得更明显:
现在看起来,这两个工作区的名称和 ID 好像是以词典的样式结合在一起了。但是如果这时候在下面接「从列表中选取」的话,结果不会理想:
原因很简单,因为这本身就是一坨文本,它还没有被完全转化成词典。
要把这样的文本转化为词典,首先要知道一个词典转化成文本看起来是什么样的。大家可以新建一个捷径测试一下,比如像我这样:
拉出来一个「词典」操作,然后添加「文本」,不用多,2 个就够。左边写「名称一」、「名称二」,右边对应着写「1」、「2」。再一运行,就会发现它的结果是 {"名称一":"1","名称二":"2"}
这么一个格式。
而我们刚才那一坨文本,它是什么格式呢?它是这样的格式:{"Life":"1642117"} {"sspai":"3097276"}
。而如果我们把它中间的 } {
给替换成一个逗号(,)也就是这样 {"Life":"1642117","sspai":"3097276"}
,就和词典转的文本没什么两样了。
那我们在捷径里怎么做到这一点?使用「替换文本」:
「查找文本」就填 } {
(中间有个空格),替换为后面就填半角逗号(,),轻松解决。
但这现在还只是文本的状态,它还不是词典。想把文本转化为词典,要再多一个操作「从输入中获取词典」:
这么一来,再在下面接一个「从列表中选取」,就大功告成了。
搞定了文本转词典,下面我们就不用再绕什么弯路了。
我们本来是要获取工作区 ID,从中获得项目 ID,进而能够填补我们启动计时器的必要信息中唯一缺乏的 Project ID。现在工作区 ID 已经搞定,项目 ID 也可以照方抓药,同理解决。
首先我们找到获取项目 ID 的请求链接,是:https://www.toggl.com/api/v8/workspaces/工作区ID/projects
。我们直接把它放在刚才选择工作区 ID 的下面:
这时候,就可以用「选取的项目」这个魔法变量,来代替工作区 ID。随后再在下面加上「获取 URL 内容」,方法仍然是「GET」,授权的方式也没有变化:
这时候再运行捷径,就能获取到我们选择的工作区下所有的项目信息了。上图中我选择的工作区是「Life」(我总共只有 2 个工作区,一个是「Life」一个是「sspai」)。
接下来,我们因为需要项目的 ID,也就是 Project ID。所以要照着刚才为工作区 ID 制作词典的方法,把项目的标题和 ID 也绑定起来。两者的操作步骤完全一样:
首先是「为每个项目重复」,因为我们每个工作区里都有大量项目。随后分别获取「id」和「name」,再将其结合为词典。运行之后,就会看到所有项目的标题和 ID 都结合在了一起:
这时候我们可以选择项目标题,获得项目 ID。
所以现在,我们已经获得了 5 个关键信息中唯一确实的一个 Project ID。接下来就是把剩下的在捷径中实现了,这相对来说就轻松多了。
完成 Toggl 启动计时器的捷径
我们重新回顾制作 Toggl 启动计时器的捷径需要的各项要素。
- 请求链接(已知):
https://www.toggl.com/api/v8/time_entries/start
- 请求方法(已知):POST
- 授权:授权方式已知(见上篇文章)
- 计时器描述:在添加的时候临时填写
- 项目 ID:在添加的时候选择
created_with
,这一项的意思是你发起请求的客户端是什么,这里我们可以随便填,比如说可以写shortcut
那么一般来说,我们会先写计时器描述,再选项目。所以可以在捷径的最开始先做个「要求输入」,再把结果设为变量,留着备用:
想更省事一点,可以把自己比较经常做的事先做个列表。然后列表的最后一项是手动输入。这样的话能在启动常用计时器时更省事:
接下来,该准备的已经都准备完毕了,我们来看如何把它们全放到一个「获取 URL 内容」里:
首先,「URL」里填上 https://www.toggl.com/api/v8/time_entries/start
。
在接下来的「获取 URL 内容」里,先把方法选择为「POST」,再在头部授权。接下来是关键的部分,我们在「请求体」这个区域,首先选择「JSON」,再「添加“新字段”」,添加时格式选择「词典」。随后还要在这个「词典」里,添加 3 个新项目:
- 左边填
Description
(描述),右边填我们设好的变量。 - 左边填
pid
(项目 ID),右边填我们选择的项目 ID 的魔法变量(你也可以在那一步下面设一个变量)。 - 左边填
created_with
,右边填shortcut
。
按照这样的格式填写最后的「获取 URL 内容」操作,启动 Toggl 的捷径就全部完成了。
当我们运行这个捷径,会发现它仍然会给我们返回一些东西:
根据这个返回的结果,我们可以完善一下我们这个捷径的体验,比如让它告诉我们计时器已经运行了。做法很简单:
先获取「data」这个值,再获取其下的「description」,最后把这个「description」放到现实结果里,写一个提示信息即可。
小结
以上就是在捷径中利用 Toggl 的 API 创建计时器的完整讲解,也是至此为止最复杂的讲解了。特别是中间我们穿插了一个和 API 打交道时经常会用到的技巧——文字转词典。最后还有关于「获取 URL 内容」里请求细节填充方面的比较集中的知识。
建议各位还是尝试一下时间记录,尝试一下 Toggl。随后才能一步一步理解它的逻辑,才能更好地理解这个捷径里用到的所有知识点。
捷径下载:Toggl 计时器(启动)
- 1它实际上就是我们理解的计时器。
- 2从这开始我就不一一介绍每个链接都是怎么在文档里查找到的了。前面已经介绍过了不少,但这个过程还是需要大家多试,多适应,多反思,慢慢就能比较快地搞定自己需要的请求链接。
- 3授权的过程我们在 25–1 里已经讲过了:https://sspai.com/post/52596?series_id=68
- 4关于这一点,我们在《重复相关的操作》一文中有介绍:https://sspai.com/article/48357?series_id=68