你怎么提到' Slack的这个hubot cron脚本中的用户,如果他们的通知设置打开,他们可以将其视为通知?

时间:2015-01-30 13:33:33

标签: cron hubot slack-api

我使用heroku为Slack设置了这个hubot-cron脚本。只有一个例外,效果很好。如果你在Slack中'@'某人(提及),用户将收到通知,具体取决于他们的通知设置。这样写的方式,如果在命令文本中放入用户名,Slack不会将其注册为用户,只是文本。

例如:

  

hubot新工作2 * * * * *“@everyone testing”

当每两分钟发布一次时,它可能会写@everyone,但Slack并不认为它实际上是'@everyone'。

使用此代码可以做些什么,以便您可以将作业实际指向@user?

# Description:
#   register cron jobs to schedule messages on the current channel
#
# Commands:
#   hubot new job "<crontab format>" <message> - Schedule a cron job to say something
#   hubot new job <crontab format> "<message>" - Ditto
#   hubot new job <crontab format> say <message> - Ditto
#   hubot list jobs - List current cron jobs
#   hubot remove job <id> - remove job
#   hubot remove job with message <message> - remove with message
#
# Author:
#   miyagawa

cronJob = require('cron').CronJob

JOBS = {}

createNewJob = (robot, pattern, user, message) ->
  id = Math.floor(Math.random() * 1000000) while !id? || JOBS[id]
  job = registerNewJob robot, id, pattern, user, message
  robot.brain.data.cronjob[id] = job.serialize()
  id

registerNewJobFromBrain = (robot, id, pattern, user, message, timezone) ->
  # for jobs saved in v0.2.0..v0.2.2
  user = user.user if "user" of user
  registerNewJob(robot, id, pattern, user, message, timezone)

  envelope = user: user, room: user.room
  robot.send envelope, "Job #{id} registered from brain"

storeJobToBrain = (robot, id, job) ->
  robot.brain.data.cronjob[id] = job.serialize()

  envelope = user: job.user, room: job.user.room
  robot.send envelope, "Job #{id} stored in brain asynchronously"

registerNewJob = (robot, id, pattern, user, message, timezone) ->
  job = new Job(id, pattern, user, message, timezone)
  job.start(robot)
  JOBS[id] = job

unregisterJob = (robot, id)->
  if JOBS[id]
    JOBS[id].stop()
    delete robot.brain.data.cronjob[id]
    delete JOBS[id]
    return yes
  no

handleNewJob = (robot, msg, pattern, message) ->
  try
    id = createNewJob robot, pattern, msg.message.user, message
    msg.send "Job #{id} created"
  catch error
    msg.send "Error caught parsing crontab pattern: #{error}. See http://crontab.org/ for the syntax"

updateJobTimezone = (robot, id, timezone) ->
  if JOBS[id]
    JOBS[id].stop()
    JOBS[id].timezone = timezone
    robot.brain.data.cronjob[id] = JOBS[id].serialize()
    JOBS[id].start(robot)
    return yes
  no

syncJobs = (robot) ->
  nonCachedJobs = difference(robot.brain.data.cronjob, JOBS)
  for own id, job of nonCachedJobs
    registerNewJobFromBrain robot, id, job...

  nonStoredJobs = difference(JOBS, robot.brain.data.cronjob)
  for own id, job of nonStoredJobs
    storeJobToBrain robot, id, job

difference = (obj1, obj2) ->
  diff = {}
  for id, job of obj1
    diff[id] = job if id !of obj2
  return diff

module.exports = (robot) ->
  robot.brain.data.cronjob or= {}
  robot.brain.on 'loaded', =>
    syncJobs robot

  robot.respond /(?:new|add) job "(.*?)" (.*)$/i, (msg) ->
    handleNewJob robot, msg, msg.match[1], msg.match[2]

  robot.respond /(?:new|add) job (.*) "(.*?)" *$/i, (msg) ->
    handleNewJob robot, msg, msg.match[1], msg.match[2]

  robot.respond /(?:new|add) job (.*?) say (.*?) *$/i, (msg) ->
    handleNewJob robot, msg, msg.match[1], msg.match[2]

  robot.respond /(?:list|ls) jobs?/i, (msg) ->
    text = ''
    for id, job of JOBS
      room = job.user.reply_to || job.user.room
      if room == msg.message.user.reply_to or room == msg.message.user.room
        text += "#{id}: #{job.pattern} @#{room} \"#{job.message}\"\n"
    msg.send text if text.length > 0

  robot.respond /(?:rm|remove|del|delete) job (\d+)/i, (msg) ->
    if (id = msg.match[1]) and unregisterJob(robot, id)
      msg.send "Job #{id} deleted"
    else
      msg.send "Job #{id} does not exist"

  robot.respond /(?:rm|remove|del|delete) job with message (.+)/i, (msg) ->
    message = msg.match[1]
    for id, job of JOBS
      room = job.user.reply_to || job.user.room
      if (room == msg.message.user.reply_to or room == msg.message.user.room) and job.message == message and unregisterJob(robot, id)
        msg.send "Job #{id} deleted"

  robot.respond /(?:tz|timezone) job (\d+) (.*)/i, (msg) ->
    if (id = msg.match[1]) and (timezone = msg.match[2]) and updateJobTimezone(robot, id, timezone)
      msg.send "Job #{id} updated to use #{timezone}"
    else
      msg.send "Job #{id} does not exist"

class Job
  constructor: (id, pattern, user, message, timezone) ->
    @id = id
    @pattern = pattern
    # cloning user because adapter may touch it later
    clonedUser = {}
    clonedUser[k] = v for k,v of user
    @user = clonedUser
    @message = message
    @timezone = timezone

  start: (robot) ->
    @cronjob = new cronJob(@pattern, =>
      @sendMessage robot
    , null, false, @timezone)
    @cronjob.start()

  stop: ->
    @cronjob.stop()

  serialize: ->
    [@pattern, @user, @message, @timezone]

  sendMessage: (robot) ->
    envelope = user: @user, room: @user.room
    robot.send envelope, @message

2 个答案:

答案 0 :(得分:20)

要提及特定用户,请发送以下格式之一

<@USER_ID>

<@USER_ID|user_name>

使用@everyone之类的特殊@mention命令:

  

当前定义的命令是!channel,!group和!everyone(组只是通道的同义词 - 两者都可以在通道和组中使用)。这些表示@channel,@ group或@everyone消息,并且应该导致客户端显示通知。

所以,您要发送:<!everyone>以提及所有人。

因此,如果我想发送一条提及其用户ID为U1234的stephen的消息,我会发送以下内容:

{
    "text": "Hey <@U1234|stephen> pay attention!"
}

或者如果我想提及@everyone,我会这样做:

{
    "text": "Hey <!everyone> pay attention!"
}

有关邮件格式的完整文档:https://api.slack.com/docs/formatting

答案 1 :(得分:1)

您应该使用<!>作为特殊字词。

  

某些邮件包含具有额外行为的特殊字词。对于这些,我们使用格式<!foo>,其中foo是一个特殊命令。 - Slack

在您的示例中,使用<!everyone>进行通知将起作用。