LoginSignup
4
5

More than 5 years have passed since last update.

slackで折りたためるメッセージをhubotから送信

Posted at

目的

hubot等のbotでslackのメッセージを送信するときに下のような折りたためる形で送りたい。

attachment_text.png

slack attachmentを使うとできるが、slack attachmentはメッセージ(text)が8000byte(8000文字ではない)で打ち切られるという罠が存在するので、長いメッセージを送るときは8000byteごとに区切って(できれば改行など区切りのいいところで切って)送信する必要がある。

回避コード

toUtf8String = (str) ->
  return unescape(encodeURIComponent(str))

toJSString = (str) ->
  return decodeURIComponent(escape(str))

sendAttachmentMessage = (robot, msg, pretext, text, delay) ->
  setTimeout ->
    robot.emit 'slack.attachment',
    message: msg.message
    content:
      # see https://api.slack.com/docs/attachments
      pretext: pretext
      text: text
      fallback: "Attachment fallback"
  , delay


# robot : hubotのインスタンス
# msg : msgインスタンス
# message : 送信するメッセージ(string)
# reply : 返信かどうか(bool)
module.exports.longMessage = (robot, msg, message, reply) ->
  delay = 0
  if reply
    reply_to = "@#{msg.message.user.name}"
  else
    reply_to = ""

  # slackのattachmentsは8000byteで打ち切られるため、その対策
  message_utf8 = toUtf8String(message)
  while message_utf8.length > 0
    if message_utf8.length >= 8000
      idx = message_utf8.lastIndexOf('\n', 8000)
      if idx < 0
        idx = 8000
      else
        idx = idx + 1
    else
      idx = message_utf8.length
    tmp = message_utf8.substr(0, idx)
    message_utf8 = message_utf8.substr(idx)
    # メッセージ毎に1秒遅延を入れる(順番入れ替わり対策)
    sendAttachmentMessage(robot, msg, reply_to, toJSString(tmp), delay)
    reply_to = ""
    delay += 1000

メッセージの送信が非同期に行われるため、区切って送った時に順番が入れ替わるおそれがある。このため、遅延を入れて送信している。ダサい。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5