小煎蛋 通知系统服务端
初始的目标是替代小方糖
里程碑
[ ] 建立日志系统
[x] Dockerfile & Gitea Action
[ ] webhook消息通知
[ ] 通过GPT接口判断用户意图创建提醒
[ ] 日常提醒 & 重复提醒
[ ] 提醒统计
[ ] 备忘录功能
[ ] 倒数日功能
零碎TODO
[ ] 精细化模板卡片的返回值,以及存储
[ ] 模板改成JSON格式的,模板ID的话只能自己创建
[ ] 支持编辑更多设置,飞书网页就行
[ ] 飞书网页鉴权逻辑,分为内网和外网部分,内网使用米盾,支持查看全部的提醒信息等等,外网只支持创建/编辑卡片带出来的提醒,但是这里不支持鉴权,尝试改成群里的聊天仅对发送者可见
[ ] 仅对发送者可见的卡片是否可以后续修改成结果对全员显示
[ ] 提醒挂靠在卡片发送者的身上,不论网页还是卡片,谁触发提醒卡片,挂靠在谁身上
[ ] 支持快速提醒,输入数字,[1-120]分钟
[ ] 销毁创建用卡片,创建卡片添加取消按钮,点击去掉卡片可交互部分
[ ] 支持消息快捷操作
[ ] 摸索一下萝卜提醒的统计功能,想法是给个飞书网页
[ ] 看看提醒统计的卡片需要什么数据,应该是需要单建统计数据表,看看能不能融合进Remind表,加个needReply字段
[ ] 支持单独艾特某人,应该是创建一句话提醒的时候,提醒里边如果有艾特的非小煎蛋人物就发送给他
[ ] 自定义工作日
[ ] 离职人员的提醒会发一条通知,然后提醒别人认领
[x] 数据库新增图片key value以及原图保存,方便查看
[x] 支持同一提醒设置多个时间
[x] 每个时间,支持多时间点设置,类似每周一二三,每月1 3 10号
[x] 通过info指令,在对话里返回请求的数据
[x] 用药提醒的卡片模板,确认、取消、延迟
待定TODO
[ ] 支持消息加急
网页可配置项
-
卡片配置
- 提醒标题
- 详细内容
- 插图Key
- 确认文本
- 取消文本
- 延迟文本
-
时间配置(手风琴支持多条)
- 重复类型
- 提醒时间
- 星期几
- 每月的几号
- 每年的哪天提醒
-
接收配置
- 接收者类型
- 接收者ID
-
基本设置
- 是否需要回复
- 延迟提醒时间
项目框架 Fastify
Fastify 是一个高效、低开销、功能丰富的 Web 框架,专为提高开发人员的生产力和性能而设计。
CLI工具 Fastify-CLI
Docs Fastify documentation.
项目备忘
运行端口: 3000
JSON结构设计
提醒主体信息
不论是用药提醒,还是什么提醒,本质上是一个可重复提醒的闹钟,单独建一个表存
每次提醒之后计算下次提醒时间,每次遍历列表确定是否需要提醒
interface Remind {
/**
* id
*/
id: string;
/**
* 所有者信息,绑定用户表的id
*/
owner: string;
/**
* 消息Id
*/
messageId: string;
/**
* 接收者类型
*/
subscriberType: "open_id" | "user_id" | "union_id" | "email" | "chat_id";
/**
* 接收者Id
*/
subscriberId: string;
/**
* 是否需要回复,不需要回复的也不会重复提醒
*/
needReply: boolean;
/**
* 延迟时间
*/
delayTime: number;
/**
* 卡片信息,用于绘制初始卡片、确认卡片、取消卡片、延迟卡片
*/
cardInfo: {
/**
* 提醒标题,必须要有
*/
title: string;
/**
* 插图key
*/
imageKey?: string;
/**
* 提醒内容,为空不显示
*/
content?: string;
/**
* 确认文本,为空不显示,为需要回复卡片时,如果为空则默认为“完成”
*/
confirmText?: string;
/**
* 取消文本,为空不显示
*/
cancelText?: string;
/**
* 延迟文本,为空不显示
*/
delayText?: string;
} | null;
/**
* 卡片模板信息
*/
templateInfo: {
/**
* 卡片模板ID,会注入变量
* ${owner} 所有者
* ${remindTime} 提醒时间
*/
pendingTemplateId: string;
/**
* 交互之后的卡片模板ID,如果有这个就不会用下边三个但是都会注入变量
* ${owner} 所有者
* ${remindTime} 提醒时间
* ${result} 交互结果,会读卡片按钮绑定的变量text,如果没有则是绑定的result对应的 已确认、已取消、已延迟
* ${interactTime} 交互时间
*/
interactedTemplateId: string;
/**
* 确认之后的卡片模板ID
*/
confirmedTemplateId: string;
/**
* 取消之后的卡片模板ID
*/
cancelededTemplateId: string;
/**
* 延迟之后的卡片模板ID
*/
delayedTemplateId: string;
} | null;
/**
* 提醒时间
*/
remindTimes: RemindTime[];
/**
* 是否启用
*/
enabled: boolean;
/**
* 下次提醒的时间,格式为yyyy-MM-dd HH:mm
*/
nextRemindTime: string;
/**
* 下次提醒时间的中文,类似每天 07:00
*/
nextRemindTimeCHS: string;
}
/**
* 提醒时间
* 为了支持多个时间点提醒,将时间存成数组
*/
interface RemindTime {
/**
* 重复类型
* single: 一次性
* daily: 每天
* weekly: 每周
* monthly: 每月
* yearly: 每年
* workday: 工作日
* holiday: 节假日
*/
frequency:
| "single"
| "daily"
| "weekly"
| "monthly"
| "yearly"
| "workday"
| "holiday";
/**
* 提醒时间,格式为HH:mm, single类型时仅作展示用,类型为yyyy-MM-dd HH:mm
*/
time: string;
/**
* 星期几[1-7],当frequency为weekly时有效
*/
daysOfWeek: number[];
/**
* 每月的几号[1-31],当frequency为monthly时有效
*/
daysOfMonth: number[];
/**
* 每年的哪天提醒,当frequency为 yearly 时有效,格式为MM-dd
*/
dayOfYear: string;
}
提醒记录
每次提醒之后记录下messageId,用于确认、取消、延迟
将用户的反馈结果融合进提醒状态里,用于统计
多余的数据如选择的结果则存储进result,没有留空
interface RemindRecord {
/**
* 记录Id
*/
id: string;
/**
* 关联的提醒Id
*/
remindId: string;
/**
* 发送的卡片Id
*/
messageId: string;
/**
* 提醒状态
* pending: 待确认
* delay: 已延迟
* confirmed: 已确认
* canceled: 已取消
*/
status: "pending" | "delayed" | "confirmed" | "canceled";
/**
* 本次提醒时间,格式为yyyy-MM-dd HH:mm
*/
remindTime: string;
/**
* 用户交互的时间,格式为yyyy-MM-dd HH:mm
*/
interactTime: string;
/**
* 用户回答的结果
*/
result: object;
}
用户列表
存储用户信息便于拿取提醒列表,浏览器应用接入米盾之后可以用user_id对应username拿到对应信息
后续可能有关键词提醒
interface User {
/**
* id
*/
id: string;
/**
* 用户名
* @example zhaoyingbo
*/
user_id: string;
/**
* open_id
*/
open_id: string;
}