所有核心逻辑(权限校验、幂等去重、时间约束、开奖算法)由 JS 脚本执行,NPC 只负责调用脚本并格式化输出。
| 保障项 | 实现方式 |
|---|---|
| 权限控制 | 脚本比对 CURRENT_USER 与 CNB_ISSUE_OWNER |
| 幂等性 | 脚本扫描全部评论,同一用户只取首次 |
| 开奖时间约束 | 脚本比对 new Date() 与 Issue 中的开奖时间 |
| 开奖后锁定 | 脚本检测评论中是否已存在「🎊 开奖结果」标记 |
| 角色 | 发起活动 | 参与抽奖 | 开奖 |
|---|---|---|---|
| Issue 创建者(举办者) | ✅ | ❌ | ✅ |
| 其他人(参与者) | ❌ | ✅ | ❌ |
创建 Issue,按模板填写:
## 🎰 第N期抽奖
> 📅 开奖时间:2026-04-20 20:00
### 🎁 奖品设置
| 奖品等级 | 奖品名称 | 数量 |
|----------|----------|------|
| 🥇 一等奖 | CNB限定T恤 | 1 |
| 🥈 二等奖 | CNB马克杯 | 2 |
| 🥉 三等奖 | 贴纸套装 | 5 |
必填:奖品等级、奖品名称、数量、开奖时间
在抽奖 Issue 下评论:抽奖
- 同一用户多次评论
抽奖只算一次(幂等,由脚本强制保证)- 开奖后的
抽奖评论无效(由脚本强制保证)
到达开奖时间后,Issue 创建者评论:开奖
- 开奖时间未到 → 脚本拒绝并提示剩余时间
- 无人参与 → 脚本拒绝
- 已开奖 → 脚本拒绝重复开奖
| Skill | 脚本 | 职责 |
|---|---|---|
lottery-config-validator | scripts/validate.js | 校验 Issue 配置(活动名称、开奖时间、奖品表格) |
draw-lottery | scripts/lottery.js | 抽奖参与(权限+幂等+时效)、开奖(时间+算法+锁定) |