GO言語(golang)を使って適当な用途のプログラムを作ってみます。
今回は最近複数言語で書いた覚えのあるディスコードのBOT。
サーバーで動作させるまでやってみます。
ライブラリの追加
ディスコードライブラリはこれを使いました。
go get
コマンドでライブラリ追加。
1 |
go get github.com/bwmarrin/discordgo |
特に何も表示されませんが、GOPATH/pkg
に追加されてます。
(GOPATH
の確認はgo env
コマンドで見れます)
実装
サンプルを見つつ適当に書いてみる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
package main import ( "fmt" "os" "os/signal" "syscall" "strings" "github.com/bwmarrin/discordgo" ) const( TOKEN = "BOT ACCESS TOKEN" ) func main() { dg, err := discordgo.New("Bot " + TOKEN) if err != nil { fmt.Println("error:start\n", err) return } //on message dg.AddHandler(messageCreate) err = dg.Open() if err != nil { fmt.Println("error:wss\n", err) return } fmt.Println("BOT Running...") //シグナル受け取り可にしてチャネル受け取りを待つ(受け取ったら終了) sc := make(chan os.Signal, 1) signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill) <-sc dg.Close() } func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) { if m.Author.Bot { return } nick := m.Author.Username member, err := s.State.Member(m.GuildID, m.Author.ID) if err == nil && member.Nick != "" { nick = member.Nick } fmt.Println("< "+m.Content+" by "+nick) if m.Content == "ああ言えば" { s.ChannelMessageSend(m.ChannelID, "こう言う") fmt.Println("> こう言う") } if strings.Contains(m.Content,"www") { s.ChannelMessageSend(m.ChannelID, "lol") fmt.Println("> lol") } } |
ライブラリのクラス構造が他とちょっと違って少し使いにくい。
発言内容とニックネームを出力しつつ、特定ワードで反応するボットです。
サーバーで動かす
go run
でテストしたらgo build
で実行ファイルを作ります。
クロスコンパイル可能なので実行先の環境に合わせた実行ファイルを作成できます。
今回はAWSのUbuntuを対象にリリースしてみます。
1 |
env GOOS=linux GOARCH=amd64 go build -o disco-linux discoBot.go |
ついでにオプション-o
で実行ファイル名を指定。
サーバーにファイルを送ってsshログイン。
1 2 |
chmod 755 disco-linux ./disco-linux |
実行権限を付けて動かすと問題なく動作します。
GOをインストールしてなくてもちゃんと動くのはいいですね。
所感
コードはnode.jsなら1/3の行で書けそう。
書き方もPHPの方が大分わかりやすい。
でもバイナリ化が楽(あたりまえだけど)で配布しやすい部分はいい。
CやJavaのバイナリ化で色々問題が起きた記憶もあるので、肥大化した時にどうなるかが気になるところ。
そういえばGOはビルドツールに何を使うんだろう。
久々にmakefileを作ることになるのか。