-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
188 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
module.exports = | ||
port: 8201 | ||
dbPath: 'db' | ||
webhookUrl: null |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,148 @@ | ||
config = require 'config' | ||
cron = require 'cron' | ||
_ = require 'lodash' | ||
Promise = require 'bluebird' | ||
logger = require 'graceful-logger' | ||
moment = require 'moment' | ||
{CronJob} = cron | ||
request = require 'request' | ||
|
||
requestAsync = Promise.promisify request | ||
|
||
model = require './model' | ||
rules = require './rules' | ||
|
||
class Bot | ||
|
||
module.exports = (app) -> | ||
isActive: -> | ||
config.activeDate is moment().format('YYYYMMDD') | ||
|
||
active: -> | ||
config.activeDate = moment().format('YYYYMMDD') | ||
|
||
bot = new Bot | ||
|
||
_messageHandler = (req, res) -> | ||
return res.status(400).send("Missing creator") unless req.body.creator | ||
|
||
# 动态记录频道 id,以便发送记录 | ||
if req.body._storyId | ||
config._targetId = req.body._storyId | ||
config.targetType = 'story' | ||
else if req.body._roomId | ||
config._targetId = req.body._roomId | ||
config.targetType = 'room' | ||
|
||
bot.active() | ||
|
||
checkinData = | ||
_creatorId: req.body.creator._id | ||
name: req.body.creator.name | ||
time: Date.now() | ||
|
||
model.addCheckin checkinData | ||
|
||
.then -> | ||
|
||
# 提取回复规则 | ||
replyRule = null | ||
rules.replies.some (reply) -> | ||
switch | ||
when reply.match and req.body.body?.match(reply.match) | ||
replyRule = reply | ||
return true | ||
else return false | ||
|
||
return res.status(200).send('ok') unless replyRule | ||
|
||
# 构造回复消息 | ||
replyMsg = | ||
switch | ||
when replyRule.msg | ||
replyRule.msg = [replyRule.msg] if toString.call(replyRule.msg) is '[object String]' | ||
replyMsg = replyRule.msg[_.random(0, replyRule.msg.length - 1)] | ||
|
||
return res.status(200).send('ok') unless replyMsg | ||
|
||
bot = new Bot | ||
# 预处理回复消息 | ||
if rules.replaces | ||
for key, val of rules.replaces | ||
replyMsg = replyMsg.replace key, val | ||
|
||
app.post '/messages', (req, res) -> | ||
# 构造消息结构 | ||
message = content: replyMsg | ||
# 回应消息 | ||
res.status(200).send message | ||
|
||
return res.status(400).send({error: "Missing creator"}) unless req.body.creator | ||
.catch (err) -> res.status(400).send error: err.message | ||
|
||
_sendCheckinSummary = -> | ||
return unless bot.isActive() | ||
return unless rules.members and config._targetId and config.webhookUrl | ||
model.getCheckins().then (checkins) -> | ||
nonCheckMembers = rules.members.filter (memberName) -> | ||
return false if checkins._creatorId is memberName | ||
return false if checkins.name.indexOf(memberName) > -1 | ||
return true | ||
if nonCheckMembers.length | ||
msg = "#{nonCheckMembers.join(',')} 这几个家伙还没签到,去哪儿啦?" | ||
else | ||
msg = "大家来的好早,每一位都签到啦" | ||
|
||
message = content: msg | ||
|
||
switch config.targetType | ||
when 'story' then message._storyId = config._targetId | ||
when 'room' then message._roomId = config._targetId | ||
else return false | ||
|
||
requestAsync | ||
method: 'POST' | ||
url: config.webhookUrl | ||
json: true | ||
body: message | ||
|
||
.catch (err) -> logger.warn err.stack | ||
|
||
_sendCronData = (cronData) -> | ||
|
||
return -> | ||
|
||
return unless bot.isActive() | ||
return unless config.webhookUrl and config._targetId and cronData.msg | ||
|
||
message = content: msg | ||
|
||
switch config.targetType | ||
when 'story' then message._storyId = config._targetId | ||
when 'room' then message._roomId = config._targetId | ||
else return false | ||
|
||
console.log "Send message", | ||
method: 'POST' | ||
url: config.webhookUrl | ||
json: true | ||
body: message | ||
|
||
requestAsync | ||
method: 'POST' | ||
url: config.webhookUrl | ||
json: true | ||
body: message | ||
.catch (err) -> logger.warn err.stack | ||
|
||
module.exports = (app) -> | ||
|
||
checkinData = | ||
_creatorId: req.body.creator._id | ||
name: req.body.creator.name | ||
time: Date.now() | ||
app.post '/incoming', (req, res) -> | ||
_messageHandler req, res | ||
|
||
model.addCheckin checkinData | ||
app.use (err, req, res, next) -> | ||
res.status(500).send error: err.message | ||
|
||
.then -> res.status(200).send ok: 1 | ||
new CronJob '0 0 10 * * 1-5', _sendCheckinSummary | ||
|
||
.catch (err) -> res.status(400).send error: err.message | ||
if rules.crons | ||
for cronRule, cronData of rules.crons | ||
new CronJob cronRule, _sendCronData(cronData) | ||
|
||
bot |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
moment = require 'moment' | ||
|
||
module.exports = rules = | ||
replies: [ | ||
match: /.*/ | ||
msg: [ | ||
'%welcome,安排一下今天的计划吧~' | ||
'%welcome,我是偷工减料的签到机器人' | ||
'我实在是找不出还有什么话能回复了' | ||
'您先忙着,我去去就来' | ||
'你是猴子请来的救兵吗' | ||
'我喊你一声你敢应吗' | ||
] | ||
] | ||
# 列表中的成员如果没有签到,会在 10 点收到通知 | ||
members: [ | ||
'博深' | ||
'陈涌' | ||
'丹青' | ||
'品章' | ||
'砰砰' | ||
'王连杰' | ||
'王卫' | ||
'晶鑫' | ||
'王艺霖' | ||
'徐亮' | ||
'郁飞' | ||
'晓连' | ||
'俊官' | ||
] | ||
# 替换 msg 中的字符串 | ||
replaces: | ||
'%welcome': -> | ||
txt = '' | ||
hour = moment().hour() | ||
switch | ||
when hour > 7 and hour < 9 then txt = '早上好' | ||
when hour >= 9 and hour < 11 then txt = '上午好' | ||
when hour >= 11 and hour < 13 then txt = '中午好' | ||
when hour >=13 and hour < 18 then txt = '下午好' | ||
else txt = '晚上好' | ||
txt | ||
crons: | ||
'0 0 18 * * 1-5': | ||
msg: '忙碌了一天,大家都辛苦啦,好好休息吧' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters