前言 之前在做微信机器人的时候(见:制作一个微信机器人 ),突然想到能不能在微信上发送一条消息就可以将笔记记录到trilium中,毕竟手机浏览web端的体验实在是有些别扭。
摸索一番后发现trilium有相应的API可供调用而且还支持自定义API,于是打算在微信机器人中增加与trilium的联动。
目前实现的功能
记录灵感 - 记录突然想到的事情
记录日记 - 记录今日的想法
在日程表上记录重要事件
查看重要事件倒数日
查看待办任务
新建待办任务
准备工作 导入python包 trilium-py ,这个库中封装了部分trilium的常用方法。使用前需要初始化自己的笔记地址和token。
def __init__(self) -> None: server_url = 'https://domain:8080' token = 'mytoken' self.ea = ETAPI(server_url, token)
记录灵感 我的习惯是在今日日记下方建立子笔记方便日后回溯,首先建立一个方法,用于处理事件。
def sendInspiration(self,title="新灵感",content=""): pass
所以首先需要做的是获取今日日记笔记的id。
today = str(datetime.today().date()) todayNoteId = self.ea.get_day_note_id(today)
在笔记下方建立子笔记,传入标题和内容,并且设置前缀【灵感】。
res = self.ea.create_note(parentNoteId=todayNoteId,type="text",title=title,content=content,prefix="灵感")
此外,我还习惯在【灵感】笔记上打标签,一个是【#灵感】方便查找,另一个是【#createdDate=<创建日期>】,方便使用 Trilium-collection-views. 进行布局。
self.ea.create_attribute(attributeId="",noteId=res["note"]["noteId"],name="灵感",type="label",value="",isInheritable=False) self.ea.create_attribute(attributeId="",noteId=res["note"]["noteId"],name="createdDate",type="label",value=today,isInheritable=False)
至此微信机器人可以通过调用sendInspiration
方法记录灵感,在微信机器人的监听方法中加入判断:
记录重要事件elif "灵感" == newMsg[1][0:2]: content = newMsg[1][3:] title = loopTips("请输入标题") res = triliumtools.sendInspiration(title,content) wechat.SendMsg(res)
效果如下图:
记录日记也是同理,在此不做赘述。
记录重要日程 这里需要一个trilium插件: trilium-scripts. ,这是一个更好的日历视图,可以直观的显示某天的日程安排和重要事项,效果如下图所示:
这个插件通过在日记笔记中增加设定的标签,可以在视图中显示相应的事件,比如在1月10日的日记笔记中增加标签:#Event=理发
,就会在日历的相应位置显示事件。
所以我们需要做的就是接受相应的参数,在指定的日记笔记中添加标签即可。
创建方法:
def setEvent(self,type,date,name): dateId = self.ea.get_day_note_id(date) self.ea.create_attribute(attributeId="",noteId=dateId,name=type,type="label",value=name,isInheritable=False) return "记录成功!"
在微信机器人的监听方法中增加新的判断:
elif "Event" in newMsg[1] or "Holiday" in newMsg[1] or "Birthday" in newMsg[1]: res = newMsg[1].split(" ") if re.search(r'\d{1,2}-\d{1,2}-\d{1,2}',res[1]) == None: wechat.SendMsg("日期有误!") else: anser = triliumtools.setEvent(res[0],res[1],res[2]) wechat.SendMsg(anser)
这里我只设定了Event
、Holiday
、Birthday
三个事件,之后只需要在与机器人对话的时候传入相应的关键词、日期和事件即可记录到trilium中,效果如下图:
获取倒数日 倒数日是我在上一步中的插件上进行的魔改,在日历下方增加了倒数日功能,效果图如下:
它会根据我们设立的事件标签,动态生成事件并且自动算出距离事件的日期。
现在我需要实现的是向微信机器人发送【倒数日】三个字,然后微信机器人将倒数日推送给我。
显然trilium-py无法实现我的需求,这时候需要自己定义一个API接口,说到这里我又不得不感叹trilium真是一个神级软件,可拓展性也太强了。
新建一个后端js代码笔记,添加一个标签#customRequestHandler=daysMatter
,代码如下:
const {req,res} = api; api.log('获取倒数日api调用'); function putHTML (type,eventName,date) { var nowDate = new Date(); var lastDate = new Date(date); if ((type == "Birthday" || type == "Holiday") && (nowDate > lastDate)) { return } if (nowDate >= lastDate){ var days = parseInt((nowDate - lastDate)/(1000*3600*24)) var infoText = "⋆ "+eventName+"已经:"+days+"天" }else { var days = parseInt((lastDate - nowDate)/(1000*3600*24))+1 var infoText = "⋆ "+eventName+"还有:"+days+"天" } return infoText } if (req.method == 'GET' ) { var types=["Event","Birthday","Holiday"] var newArr =[] for (const type of types) { var attrs = api.sql.getColumn(`SELECT DISTINCT value FROM attributes WHERE name='`+type+`' AND isDeleted =0`) for (attr of attrs) { notes = api.getNotesWithLabel(type,attr) targetNote = notes[[notes.length-1]] noteTitle = targetNote.title.substring(0,11) templist = [type,attr,noteTitle] newArr.push(templist) } } var msgs = [] for (const note of newArr) { msgs.push(putHTML(note[0],note[1],note[2])) } res.status(201).json(msgs); } else { api.log("请求参数错误, 返回400"); res.send(400); }
之后即可通过https://域名/custom/daysMatter
进行访问,如此一来即可使用requests获取返回值,代码如下:
def daysMatter(): wechat = WeChat() wechat.ChatWith("东东") msgs = [] url = "https://domain:8080/custom/countdown" headers = { 'Accept': "application/json, text/plain, */*", 'User-Agent': "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36", 'Connection':'close' } requests.DEFAULT_RETRIES = 5 # 增加重试连接次数 s = requests.session() s.keep_alive = False # 关闭多余连接 try: res = requests.get(url,headers=headers) for event in res.json(): if event !=None: msgs.append(event) wechat.SendWrapMsg(msgs) except: wechat.SendMsg("trilium连接失败...")
最终实现的效果如下图:
任务管理 之前在这篇文章中介绍过trilium的任务管理功能:改进 trilium 的任务管理功能 。
因为平时不方便使用电脑的时候有查看当前待办事项的需求,所以使用微信机器人快速查看任务是个不错的方法,调用trilium-py可以很方便的实现这一功能,代码如下:
def findTask(self,type): msgs = [] boxNoteId = "HDjVNjIYU3iI" doingNoteId = "WgDRTZpY7StM" serchId = (type == "盒子") and boxNoteId or doingNoteId try: childsNoteId = self.ea.get_note(serchId)["childNoteIds"] for childNoteId in childsNoteId: title = self.ea.get_note(childNoteId)["title"] msgs.append(title) except: msgs.append("连接失败...") return msgs
新建任务的方法与上文类似,不过多赘述, 但是有一点需要注意的是,我的任务是由模板创建的,类似下图:
所以在建立任务笔记的时候需要增加一个关系标签,将template
指向任务模板:
create_attribute(attributeId="",noteId=res["note"]["noteId"],name="template",type="relation",value="任务模板",isInheritable=False)
结语 经过这么一番折腾之后,我可以在微信中实现与云端笔记的交互。