Go+Luaのチャットボットフレームワークを作った

たまには実用的なものをつくろうと思って、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はちょっと・・・という場合にぜひ。

comments powered by Disqus