2023-09-28 09:15:19 +00:00
2023-09-28 09:15:19 +00:00
2023-09-04 15:29:40 +08:00
2023-08-16 10:55:19 +08:00
2023-08-16 10:55:19 +08:00
2023-09-27 10:21:35 +08:00
2023-09-28 09:15:19 +00:00
2023-09-28 09:15:19 +00:00
2023-08-16 10:55:19 +08:00
2023-08-16 10:55:19 +08:00
2023-09-28 09:15:19 +00:00
2023-09-04 14:45:56 +08:00
2023-09-28 09:15:19 +00:00
2023-09-27 10:21:35 +08:00
2023-09-01 21:43:16 +08:00

小煎蛋 通知系统服务端

初始的目标是替代小方糖

里程碑

[ ] 建立日志系统

[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;
}
Description
小煎蛋的服务端
Readme 3.7 MiB
Languages
TypeScript 99.1%
JavaScript 0.8%
Dockerfile 0.1%