目的
hubot等のbotでslackのメッセージを送信するときに下のような折りたためる形で送りたい。
罠
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
メッセージの送信が非同期に行われるため、区切って送った時に順番が入れ替わるおそれがある。このため、遅延を入れて送信している。ダサい。