创建重复性的Notion任务以及自动更新任务状态

背景

在上一篇的文章中,我介绍了如何通过Notion创建Daily task来提升工作效率,但是也发现了2个问题。

  1. Notion不支持创建循环任务,比如每天都需要创建的Daily Wrike,Daily review等task

  2. 如果任务已经完成需要手动设置CompletedDate,否则已经Done的任务也会显示在第二天的看板里

需求

  1. 循环任务需求
Requirement
创建一个循环任务模板page,并且建立好对应的循环任务
查询循环任务模板,根据任务的循环类型,创建不同的Daily task,例如 task daily wrike是每日都要做的,娃跳舞是每个周日的task
  1. 自动更新任务状态
Requirement Comment
如果一个task是TBD或者空状态,并且task过期时间小于等于今天,那么标记task为Doing状态 已经过期或者今天即将要期的task,但是目前还没做,需要当天立即去做,所以放到doing组里今天需要马上去做
如果一个task是TBD或者空状态,并且Task 将在X天内过期(设置了提前X天过期提醒,X不为空或者0),那么提前X天标记task为Todo状态 X天内即将到期的task,需要尽快完成,所以放到Todo 组下面,防止忘记
如果一个task是TBD或者空状态,并且Task 将在X天内过期(未设置提前X天过期提醒,X为空或者0),那么直到task过期的那天设置tas为Doing状态 已经到期的task需要马上去做,所以设置task为Doing状态
如果一个task是TBD或者空状态,并且当天的时间在过期时间段之内,那么标记task为Doing状态 Task已经到了开始做的时间,需要马上开始做,所以放到doing组里去马上做
如果task过期时间是空,那么更新过期时间是今天,并且标记task状态为ToDo 创建任务的时候忘记标记过期时间,默认当天需要完成该task
如果task为Done状态,那么自动填充CompletedDate 只有completedDate<当前时间,并且状态为Done, 第二天的daily task才不会显示在看板里

解决方案

流程图

  1. 创建重复性任务

  2. 每日自动更新任务状态

设计

  1. 创建一个database页面作为模板记录需要重复做的任务,

    1.1列名及对应的值如下表

Column Value Comment
Title task名称 task名称
Status TBD,Todo,Doing,Done,Blocker,Invalid,Withdrawn,Unfinishted,OnHold Task状态
Type WorkDay,SpecificDay,SpecificDateRange 循环任务的类型
Tag Work,Life,Python,Docker等等 任务类型标签,自定义字段,请根据自身需要修改
Cycle Date 9/18/2022-9/25/2022 某一段日期
Cycle Days Monday到Sunday,选择其中一天或者多天 一周之内某几天
EndDate 例如12/31/2022 循环任务失效日期
  1. 2Daily task 有不同状态,TBD,Todo,Doing,Done,Blocker,Withdrawn,Unfinishted,OnHold
Task Status Comment
TBD(To be determined) 将来需要做的task,但是目前还没必要马上做的task,类似Jira的backlog
Todo 今天需要做的事项
Doing 今天正在做的事项
Done 今天已经完成的事项
Blocker 依赖于其他事项完成之后,才能继续进行的task,目前改事项无法进行
Invalid 无效的事项,目前只在循环任务page中使用
Withdrawn 不再需要的task
Unfinished 当天应该完成,但是实际未完成,该task当天有效
OnHold 当天做了一部分的task,现在需要先做其他优先级更高的task,该task先搁置一会,当天晚点继续做或者后面几天继续做
  1. 创建python package,开发Python代码去调用Notion的API读取dabase模板里的循环任务记录,将对应的循环任务创建到Daily task page(针对循环任务需求)

  2. 创建python package,开发Python代码去调用Notion的API去daily task page里的任务状态(针对其他任务需求)

  3. 创建azure function 定时任务,每天凌晨调用前面步骤提到的python package(当然此处也可以用jenkins定时任务或者本机的定时任务去做)

开发部署步骤

  1. 创建Notion 循环任务模板page,请参考https://stone-fighter-9fa.notion.site/530ba8c6780d4f668235e9b62f697d92?v=c802b9ed6928482c88da55051b41bb32
    RecurringTask

  2. 开发python代码调用Notion API查询循环任务记录,寻找到符合要求的循环任务,在daily task page里面创建循环任务,代码详见github

  3. 创建Azure function 定时任务,每天凌晨调用step 2中的python 程序,自动创建Notion任务
    Function.json

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    {
    "scriptFile": "__init__.py",
    "bindings": [
    {
    "name": "mytimer",
    "type": "timerTrigger",
    "direction": "in",
    "schedule": "0 10 16 * * *"
    }
    ]
    }

    init.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import datetime
    import logging
    import os
    import azure.functions as func
    from NotionRecurringTask.RecurringTask import RecurringTask
    def main(mytimer: func.TimerRequest) -> None:
    utc_timestamp = datetime.datetime.utcnow().replace(
    tzinfo=datetime.timezone.utc).isoformat()
    if mytimer.past_due:
    logging.info('The timer is past due!')
    auth=os.environ["Auth"]
    taskConfiguration_dabaseid=os.environ["TaskConfiguration_dabaseid"]
    timeDeltaWithUTC=(int)(os.environ["TimeDeltaWithUTC"])
    databaseid=os.environ["DatabaseID"]
    knotion=RecurringTask()
    knotion.process(auth,taskConfiguration_dabaseid,databaseid,timeDeltaWithUTC)
    logging.info('Python timer trigger function ran at %s', utc_timestamp)

    requirement.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    --index-url=https://test.pypi.org/simple/
    azure-functions
    requests


    NotionRecurringTask-KevinZhou>0.0.7

    # git+https://github.com/nightwish2016/NotionRecurringTask.git

    # ./DailyNotionTaskTrigger/dist/NotionRecurringTask_KevinZhou-0.0.1-py3-none-any.whl
  4. 在Aure Function中配置如下环境变量

Environment Variable Value
Auth 用来访问你授权notion page,请参考Getting started (notion.com)
DatabaseID Daily task 页面 的DatabaseId
TimeDeltaWithUTC 当前是时间与UTC时间的时间差,如果北京时间时区设置成8
TaskConfiguration_dabaseid 循环任务模板页面的 DatabaseId

Configuration

测试

一般任务测试

当前时间:2022/9/24(utc+8)

Test Case Test Data Test Result Comment
如果一个task是TBD或者空状态,并且task过期时间小于等于今天,那么标记task状态为Doing Name:M117 Regression,ExpirationDate:9/19/2022 Pass,Status:Doing 已经过期或者今天将要期的task,但是还没轮到做,需要当天立即去做,所以放到doing组里今天需要马上去做
如果一个task是TBD或者空状态,并且Task 将在3天内过期,那么标记task为Todo状态 Name:Legacy regression,ExpirationDate:9/25/2022 Pass,Status:ToDo 3天内即将到期的task,需要尽快完成,所以放到Todo 组下面
如果一个task是TBD或者空状态,并且当天的时间在过期时间段之内,那么标记task为doing状态 Name:Production testing Preparation,ExpirationDate:9/19/2022-9/31/2022 Pass,Status:Doing Task已经到了开始做的时间,需要马上开始做,所以放到doing组里去马上做
如果task过期时间是空,标记task status为Todo,那么更新过期时间是今天,并且标记task状态为ToDo Name: Task1,ExpirationDate:empty Pass,Status:ToDo 创建任务的时候忘记标记过期时间,默认当天需要完成该task
如果task为Done状态,那么自动填充CompletedDate Name: Task2,Status:Done Pass,Status:Done,CompletedDate:Today 只有completedDate<当前时间,并且状态为Done, 第二条的daily task才不会显示

循环任务测试

Test Case Test Data Test Result
如果task type是Workday,那么task只会在周一到周5创建 Name:M117 Regression,ExpirationDate:9/19/2022 Pass,Task会在周一到周5创建
如果task type是Daily,那么task每天都会创建 Name:运动 Pass,Task 每天都会创建
如果task type是SpecificDay,那么task 只会在指定的某一天(比如周一,周二)会创建 Name:核酸,Cycle Days:Wednesday,SunDay Pass,Task只会在周一周日创建
如果task type是SpecificDateRange,那么task只会在在指定的日期范围内每天创建。 Name:check for CBS automation test results,Cycle Date:9/1/2022-9/30/2022 Pass,Task会在9/1/2022-9/30/2022期间每天创建
如果task已经过期了,那么task就不会创建 Name:Docker practice,EndDate:8/31/2022 Pass,Task 不会创建因为模板里的task已经过期了

执行 Azure function前的task状态(前一天的task状态),详细请见https://stone-fighter-9fa.notion.site/DailyTask-Demo-59a57f31d29b4dfcab5db9d20aeca6ab:
InnitalDailyTask

执行Azure function定时任务后的task 状态

result

Auzure function中的日志

azure function log

此处的日志时间是UTC时区的时间

源码以及安装包

Python Package

https://test.pypi.org/project/NotionRecurringTask-KevinZhou/

Install package : pip install -i https://test.pypi.org/project/NotionRecurringTask-KevinZhou/

Github source Code

https://github.com/nightwish2016/NotionRecurringTask

参考文档

https://developers.notion.com/docs/getting-started