はじめに
この記事はGo言語のSlackライブラリを用いてBotでメッセージを送信する方向けです。
使用ライブラリ nlopes/slack バージョン 0.5.0
メッセージ送信に不具合が?
Botは落ちないのにメッセージが送られていないことが今までに何度かあり、気になって調べてみたところ
日本語文字数が1334以上のメッセージを送信しようとする際に何もなかったようにメッセージが送信されなくなる事が発覚。
(ちなみにアルファベットだと4000文字でもしっかり発話してくれる🤔)
実際に自分のSlackアカウントで試したところ、4000文字までは日本語でも問題なく投稿できたので、Bot側に問題がありそうです。
最終的には解消できたのですが、いくつか罠があったので似たような問題で躓かないようにメモ書きとして残しておきます。
その1
ライブラリ側のメッセージ送信時の文字数判定が len(string) > 4000
という条件式になっていた
つまり、文字数ではなくバイト数で判定するというアレなことになっています
よくよく最新のライブラリを見ると修正されていた!
https://github.com/nlopes/slack/commit/9e37c90c58901e134c8bf22e97accc72eeab171e#diff-bdeefded79c795ae396d7cde5c980706
→Slackライブラリを最新(0.5.0)にアップデートにすることで解消。
ここで終わらなかった…
その2
ライブラリを最新にした後、同様にbotから日本語4000字送信させようとすると今度はログにエラーが発生
Error: websocket: close 1006 (abnormal closure): unexpected EOF
なんだこれ
調べてみたところ、未解決状態のIssueに辿りつきました。
そして、Issue上で議論された解決策は
rtmのwebsocket関連は、標準のSendMessageがサポートしていることすべてをサポートしているわけではない
slack.RTM.SendMessageではなく標準のSendMessageであるslack.Client.PostMessageに変更してはどうか
という内容。
確かに今は RTM.SendMessage
を使って送信している…
実際に Client.PostMessage
に変更したところ、4000文字の日本語を送信することに成功
func SendMessage(rtm *slack.RTM, channel, text string) {
msg := rtm.NewOutgoingMessage(text, channel)
rtm.SendMessage(msg)
}
func SendMessage(client *slack.Client, channel, text string) {
params := slack.PostMessageParameters {
Markdown: true,
EscapeText: true,
AsUser: true,
UnfurlMedia: true,
UnfurlLinks: true,
}
opt1 := slack.MsgOptionPostMessageParameters(params)
opt2 := slack.MsgOptionText(text, false)
client.PostMessage(channel, opt1, opt2)
}
まとめ
Go言語のライブラリを使用してSlackにメッセージを送る手段として
・slack.Client.PostMessage
・slack.RTM.SendMessage
の2通りありますが
大量の文字列送信を想定する場合は slack.RTM.SendMessage
ではなく slack.Client.PostMessage
を使うのが無難のようです