Go言語でIRC-BOTを動かしてみる

Go言語でIRC-BOTを動かしてみる

  • このエントリーをはてなブックマークに追加

こんにちは、ムックです。

BOTといえば、node.jsのHubotのようなbotフレームワークがありますが、今回は、Go言語のIRC-BOTライブラリを使って以下の機能を持つIRC-BOTを実装したいと思います。

  • 順番を決めるようなダイス機能
  • メンバーの中からランダムで一人選ぶ機能
  • MTG、提出物などのリマインダ機能

IRC-BOT
http://waterpigs.co.uk/articles/a-simple-go-irc-bot/

時刻処理
https://godoc.org/github.com/robfig/cron

ライブラリを利用させてもらいました。

IRC-BOTの生成

まずは、IRC-BOTの生成

	ircobj := irc.IRC("my_nick", "my_name")
	ircobj.UseTLS    = true
	ircobj.TLSConfig = &tls.Config{InsecureSkipVerify: true}
	ircobj.Password  = "passwd"
	if err := ircobj.Connect("172.16.1.100:6667"); err != nil {
		fmt.Println(err)
	}

1行目、ニックネーム、名前の指定。
2,3行目、SSL接続を利用する場合はUseTLSをtrueに、configに任意の設定をします。
4行目、パスワードを指定。
最後に、Connectでホスト名、ポートを指定でします。

続きを読む

コールバック処理

	// ウェルカム処理
	ircobj.AddCallback("001", func (e *irc.Event) {
		ircobj.Join("#system_channel")
	})

AddCallbackで、トリガーとなるメッセージと第二引数に実行される関数を記述します。
上記では、RPL_WELCOMEを受け取ったらJOIN処理を行っています。

irc.Eventは以下の様な構造になります。

type Event struct {
	Code      string
	Raw       string
	Nick      string //<nick>
	Host      string //<nick>!<usr>@<host>
	Source    string //<host>
	User      string //<usr>
	Arguments []string
}

Welcomeメッセージ

	ircobj.AddCallback("JOIN", func (e *irc.Event) {
		time.Sleep(100 * time.Millisecond)
		ircobj.Notice("#system_channel", fmt.Sprintf("こんにちは、%sさん\n", e.Nick))
		if !strings.Contains(e.Nick, my_nick) {
			member[e.Nick] = e.Nick
		}
	})

e *irc.Eventを使って、ニックネームを取得しています。
4-6行目は入室しているメンバーを保持しておくものです。

順番を決めるようなダイス機能

     ircobj.AddCallback("PRIVMSG", func (e *irc.Event) {
	// ダイス
	if e.Message() == ":dice" {
            time.Sleep(100 * time.Millisecond)
	    ircobj.Notice("#system_channel", fmt.Sprintf("%sさんの出目は、%dです\n", e.Nick, rand.Intn(100)))
	}
    }

ものすごくシンプルです。
AddCallbackでPRIVMSGを受け取り、特定文字列”:dice”だった場合ランダムで0-99の数を返します。
プレゼン発表の順番やなにかの当番の順番など決めたりできます。

メンバーの中からランダムで一人選ぶ機能

	// メンバー
	member := make(map[string]string)

	ircobj.AddCallback("PRIVMSG", func (e *irc.Event) {

        if e.Message() == ":decide" {
			dice := rand.Intn(len(member))
			ii   := 0
			for _,v := range member {
				if (ii == dice) {
					ircobj.Notice("#system_channel", fmt.Sprintf("%sさんが選ばれました\n", v))
					break
				}
				ii += 1
			}
		}

入室時に保持したメンバーのマップからランダムで1人選びます。
Go言語のマップはアクセスするたびに取り出す順番が変わりますが偏りがあるためここでもrandを使います。
こちらは、メンバーの中から1人決めたいとき、議事録当番なんかを決めたりできます。

MTG、提出物などのリマインダ機能

    // 毎週月曜
	c := cron.New()
	c.AddFunc("0 50 16 * * MON", func() {
			ircobj.Notice("#system_channel", "---------------------------")
			ircobj.Notice("#system_channel", "- システムMTG 10分前 です -")
			ircobj.Notice("#system_channel", "---------------------------")
		})

    // 毎月
	c.AddFunc("0 5 11 1 * *", func() {
			ircobj.Notice("#system_channel", "------------------------")
			ircobj.Notice("#system_channel", "- 本日経費提出期限です -")
			ircobj.Notice("#system_channel", "------------------------")
		})

	c.Start()

cronライブラリで実行時刻を設定しNotice通知させます。
cronライブラリはとても良く出来ていて標準のcron表記も出来ますが
毎n時n分、毎月などは”@hourly”、”@every 1h30m”のような指定も出来ます。

出力結果

1人botと戯れる…。
irc-bot

終わりに

ただGo言語を使いたい!と練習がてら書いてみました。
業務では、ほぼ100%PHPなのですが時間を見つけてGo言語も使っていきたいです。
Goルーチンを使った並列処理を使ってなにか作りたいです。

  • このエントリーをはてなブックマークに追加

記事作成者の紹介

mukku(システムエンジニア)

生活を豊かにするWebサービスが大好きでそんなシステムに携わり続けていきたいと思いながら、日々の業務に励んでおります。

関連するSONICMOOVのサービス

システムエンジニア募集中!

×

SNSでも情報配信中!ぜひご登録ください。

×

SNSでも
情報配信中!
SONICMOOV Facebookページ SONICMOOV Twitter
Wantedly 採用情報はこちら

新着の記事

mautic is open source marketing automation