最近話題のDiscord Botを作ってみたので、ノンプログラマの友達と遊べるDiscord Botという名目で公開しました。
github.com/aimof/discatにソースをMITライセンスで公開中です。
デモ
一日の始まりは挨拶から!
というわけで、文書に予め決めておいたランダム返答を返します。
機能
- 人口無能的に決められた単語をトリガーに決められた返答を返す機能。
- 発言数に応じてレベルが上がっていく機能(下)
レベルが上がったり下がったりしているのはdockerのストレージ永続化に失敗しているからです。
どの辺がノンプログラマーと一緒に楽しめるの?
なんとこのボット、セリフをGoogle SpreadSheetで編集できるようにしました。(自動デプロイはまだないので手動でcsvを移植する必要があります)
設定ファイルはこんな感じ
ライブラリ
ライブラリとしても利用でき、シンプルに上の機能だけ返すようになっています。
技術的ないろいろ
技術面で考えたことを書いていきます。あんまり難しいことはしていないので、書くことは多くないかも
ライブラリのメイン
package discat
type Discat struct {
speaker speaker
level level
}
func Init(dict [][]string, expMap map[string]int) Discat {
return Discat{
speaker: newSpeaker(dict),
level: level{exp: expMap},
}
}
func (d Discat) Speak(input string) string {
return d.speaker.speak(input)
}
func (d Discat) GainExp(name string, exp int) {
d.level.gainExp(name, exp)
}
func (d Discat) ShowLevel(name string) (exp, level, rest int) {
return d.level.showLevel(name)
}
func (d Discat) Output() map[string]int { return d.level.output() }
Goっぽく書くことを意識したらこうなったのですが、これでいいのだろうか…。ライブラリは、ただ文字列をもらって文字列や数字を返すだけのシンプルなものにしました。それ以上の機能はコマンド側で実装
インタラプトを受け取るよくあるアレ
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGHUP, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM)
_ = <-ch
err = session.Close()
if err != nil {
log.Fatalln(err)
}
// 正常終了処理
インタラプトシグナルからセッションを正常に終了させるやつです。
話す部分は愚直に実装
func (s speaker) speak(sentenceIn string) string {
for key, value := range s.table {
if strings.Contains(sentenceIn, key) {
return value[rand.Intn(len(value))]
}
}
return ""
}
入ってきた文章に対し、持っている単語とかぶっている箇所があれば、対応するレスポンスをリターンします。
同じ文言でもセリフが変わって楽しめます。
tableというフィールド名のmapがあるのは気持ち悪いですね…(今気づいた)
docker-composeでボリュームをマウントできない問題
FROM golang:1.10.3-alpine
LABEL maintainer "aimof <aimof.aimof@gmail.com>"
RUN apk update --no-cache && \
apk add --no-cache git && \
go get -u github.com/golang/dep/cmd/dep
COPY . /go/src/github.com/aimof/discat/
WORKDIR /go/src/github.com/aimof/discat/cmd/discat/
RUN dep ensure && \
go build
CMD ./discat
version: "3"
services:
discat:
build: .
volumes:
- /home/ubuntu/discat/cmd/discat/data:/go/src/github.com/aimof/discat/cmd/discat/data
logging:
options:
max-size: "10m"
max-file: "5"
volumes:
data:
リポジトリをubuntuユーザーホーム直下に置く想定で、こんなdocker-compose.yml
を書いたのですが、なぜかボリュームのマウントに失敗。ローカルでは成功したのだが…
まとめ
Discordボット開発楽しいです。プログラムかけない友達もセリフを考えるところなら参加してもらえるので、もしご興味あれば利用してみてください。
なお、まだプロト段階ですので、まだ使いづらいです。ちょっとずつ改善していきます。