たまには実用的なものをつくろうと思って、Go+Luaで置くだけで動くチャットボットを作ってみました。Slack, IRC, Hipchatをサポートしています。
チャットボットといえばHubotだと思いますが、もっとさくっと動かしたいという方におすすめです。置けばうごきます。
特徴は以下です。
- Goなので置けば動く
- それでいてLuaでスクリプトを書ける
- 最初からマルチスレッド(複数goroutine)を考慮している
- HTTP(S)サーバ機能があるのでWEBHOOKも一緒に作れる
- 定期ジョブも流せる
1function main()
2 local bot = golbot.newbot("Slack", { token = "xxxxx" })
3
4 bot:respond([[\s*(\d+)\s*\+\s*(\d+)\s*]], function(m, e) -- 3
5 bot:say(e.target, tostring(tonumber(m[2]) + tonumber(m[3])))
6 end)
7
8 bot:serve(function(msg)
9 if msg.type == "say" then
10 bot:say(msg.channel, msg.message)
11 respond(msg, true)
12 end
13 end)
14end
こんな感じのよくあるAPIです。特徴的なのがworkerの仕組みで
1function main()
2 bot:respond([[deploy]], function(m, e)
3 bot:say(e.target, "accepted")
4 goworker({target=e.target, type="deploy"})
5 end)
6
7 bot:serve(function(msg)
8 if msg.type == "say" then
9 bot:say(msg.target, msg.message)
10 end
11 end)
12end
13
14function worker(msg)
15 if msg.type == "deploy" then
16 do_deploy()
17 notifymain({type="say", target=msg.target, message="your deployment has been completed"})
18 end
19end
このように goworker
でLuaからGoroutineをつくって重い処理などをWorkerで実行することができます。Workerからは notifymain
でメインGroutineにメッセージをおくることができます。
HTTPサーバ機能では以下のような関数を定義するだけで簡単にWEBHOOKが作れます。
1function http(r)
2 if r.method == "POST" and r.URL.path == "/webhook" then
3 local data = assert(json.decode(r:readbody()))
4 local message = data.item.message.message
5 local user = data.item.message.from.name
6 local room = data.item.room.name
7
8 local ret = {
9 message = "hello! from webhook",
10 message_format = "html"
11 }
12
13 return 200, headers, json.encode(ret)
14 end
15 return 400, headers, json.encode({result="not found"})
16end
定期ジョブは以下のような感じ。
1function main()
2 golbot.newbot("Null", {
3 http = "0.0.0.0:6669" ,
4 crons = {
5 { "0 * * * * * ", "job1"}
6 }
7 }):serve(function() end)
8end
9
10function job1()
11 print "hello!"
12end
チャットボットのためだけにNode.jsとnpmはちょっと・・・という場合にぜひ。