読者です 読者をやめる 読者になる 読者になる

scala irc botでのbotの作り方

はじめに

この記事は、私がGitHubで公開しているscala-irc-botというプログラムの使い方とボットの書き方のチュートリアルです。 ScalaIRCボットを書きたいという需要が非常に少ない目的のために書きました。

目次

  • scala irc botの紹介
  • 使い方(デプロイ方法)
  • プラグインの作成方法
  • 設定なし
  • 設定あり

scala irc botの紹介

scala irc botってなんですか

https://github.com/scala-irc-bot

私がScalairc botを書けるように作成しているプログラムです。 実際にIRCに接続するのにはPircBotというJava製のIRCクライアントを使用しています。

現在の最新バージョンは0.2.0-SNAPSHOTです。バージョンは大きく設計が変わるときに更新されます。プラグインに影響のない修正ではバージョンを上げません(mavenリポジトリの更新が面倒だからです)。

現在の使い方は sbt run によって起動させるのを推奨しています。 性質的に常時起動しておくプログラムなのでデーモンのように使うほうがいいのかなあ。。。

irc botってなんですか

IRCでの誰かの発言などのイベントなどに反応して発言したり作業したり愛したり恋したりしてくれるプログラムです。 ときには喧嘩して殴りあったりするけれど、でもそんなお前のこと、そんなに嫌いじゃないぜ?っていう人格を持っています。

ircってなんですか

RFC1459

デプロイ方法

次のものを用意してください。

git clone

本体のコードはgithubで管理しているので、cloneで持ってきます。

git clone https://github.com/scala-irc-bot/scala-irc-bot.git

設定ファイルの記述

cloneしたディレクトリに移動し、configディレクトリの中に、Config.scalaというファイルを作成します。

Config.scala

import net.mtgto.irc.Config
import net.mtgto.irc.config.BotConfig
new Config {
  val hostname = "irc.example.com" // IRCサーバの名前
  val port = 6667 // IRCサーバのポート
  val password = None // 必要ならSome("password")のように記述する
  val encoding = "utf-8" // 使用するエンコーディング
  val messageDelay = 2000 // メッセージ間の遅延(ミリ秒)
  val timerDelay = 60000 // タイマーイベント間隔(ミリ秒)
  val nickname = "scala-irc-bot" // ボットのニックネーム
  val username = "scala-irc-bot" // ボットのログイン名
  val realname = "mtgto@example.com" // ボットのリアルネーム
  // channels
  val channels = Array("#mtgto", "#test") // JOINさせたいチャンネル
  // bots
  val bots = Array[(String, Option[BotConfig])](
    // ここにプラグインの設定を記述する
  )
}

起動する

コンソールからsbtで起動します。

sbt run

(初回のみ)コンパイルが実行され、設定ファイルやネットワークなどに問題が起きなければ、しばらく経つとIRCサーバにscala irc botが接続してきます。

ですが今のままではボットプラグインを何も入れてないので、何もしてくれません。 コンソール画面にexitと入力して終了させましょう。

プラグインの作成方法 (シンプル)

ここからはまずはシンプルなプラグインを作成していきます。 ここでいうシンプルなプラグインというのは、

  1. 設定ファイルでボットプラグインごとのオプションを設定できない

っていう前提のものです。下の方にオプションを使う方法も載せてあります。

Scala + sbtで作る

今回作る環境は、

  • sbt (バージョンはユーザの環境に依る)
  • Scala 2.10.0
  • PircBot 1.8.0

です。

最小構成では build.sbt Echobot.scala の2ファイルで構成されます。

echobot/build.sbt

// -*- scala -*-
name := "EchoBot"

organization := "net.mtgto"

version := "0.1.0-SNAPSHOT"

scalaVersion := "2.10.0"

resolvers += "mtgto repos" at "http://scala-irc-bot.github.com/scala-irc-bot/maven/"

libraryDependencies := Seq(
  "net.mtgto" %% "scala-irc-bot" % "0.2.0-SNAPSHOT" % "provided"
)

scalacOptions ++= Seq("-deprecation", "-unchecked", "-encoding", "UTF8")

echobot/Echobot.scala

package net.mtgto

import net.mtgto.irc.{Bot, Client}
import net.mtgto.irc.event._

/**
 * 受け取ったメッセージをNOTICEで送り返すボット
 */
class Echobot extends Bot {
  /**
   * 誰かがPRIVMSGを書いた時に通知される
   */
  override def onMessage(client: Client, message: Message) = {
    // メッセージが送信されたチャンネルに同じメッセージをNOTICEで送り返す
    client.sendNotice(message.channel, message.text)
  }
}

ファイルを置いたら、

sbt package

と実行すると、 target/scala-2.10.0/echobot_2.10.0-0.1.0-SNAPSHOT.jar が作成されます。

このjarファイルがコンパイルされたプラグインです。

プラグインをインストール

まず、作成した echobot_2.10.0-0.1.0-SNAPSHOT.jarscala-irc-bot/botsフォルダの中に置いてください。 次に config/Config.scala にボットプラグインの設定を記述します。

  val bots = Array[(String, Option[BotConfig])](
    // ここにプラグインの設定を記述する
    ("net.mtgto.Echobot", None)
  )

sbt run すると画像のようにこちらの発言をNOTICEで繰り返してくれるようになります。

f:id:mtgto:20121216223101p:plain

botテンプレートを使う (g8)

giter8用のテンプレートを作ってあるので、これを使うこともできます。

g8 scala-irc-bot/bot
version [0.1.0-SNAPSHOT]:
organization [com.example]: net.mtgto
name [IRC Bot Project]: EchoBot

こちらは先ほどの手順で作成した時に加えて、テスト用にSpecs2、ビルド用にsbt-assemblyの設定をしてあります。 慣れてきた場合や他ライブラリに依存するプラグインを作るときにはこちらをおすすめします。

プラグインの作成方法 (設定可能)

設定ファイルでボットプラグインごとのオプションを設定することができます。

設定ファイルに書いたオプションを読み込むには、net.mtgto.irc.config.BotConfigを実装したクラスを作り、そのオブジェクトをプラグインのメインクラスのコンストラクタにもたせてあげればよいです。

実例を示してみます。今回は設定ファイルに書いたキーワードが書かれた時だけ反応するようにしてみましょう。 KeywordEchobotを作成します。

KeywordEchobot.scala

package net.mtgto

import net.mtgto.irc.{Bot, Client}
import net.mtgto.irc.event._
import net.mtgto.irc.config.BotConfig

/**
 * BotConfigを実装したクラスを定義する必要がある。
 */
case class KeywordEchobotConfig(
  val keywords: Seq[String]
) extends BotConfig

/**
 * 特定のメッセージをNOTICEで送り返すボット
 *
 * コンストラクタでEchobotConfigを受け取る
 */
class KeywordEchobot(val config: KeywordEchobotConfig) extends Bot {
  /**
   * 誰かがPRIVMSGを書いた時に通知される
   */
  override def onMessage(client: Client, message: Message) = {
    if (config.keywords.contains(message.text)) {
      // メッセージが送信されたチャンネルに同じメッセージをNOTICEで送り返す
      client.sendNotice(message.channel, message.text)
    }
  }
}

これを先ほどと同じように sbt package でビルドして、target/scala-2.9.2/keywordechobot_2.10.0-0.1.0-SNAPSHOT.jarscala-irc-bot/bots にコピーします。

あとは config/Config.scala に設定を書いてあげます。

val bots = Array[(String, Option[BotConfig])](
  ("net.mtgto.Echobot", Some(net.mtgto.KeywordEchobotConfig(Seq("こんばんは", "おはようございます"))))
)

Seqに好きな言葉を列挙してあげます。

あとは sbt run すると、設定ファイルにある言葉が書かれた時にだけ応答してくれるようになります。

f:id:mtgto:20121216223145p:plain

まとめ

簡単でしたが、scala irc botの導入方法とプラグインの作成方法を書きました。 多分ここまで読んでいる方はいらっしゃらないと思うのですが、さらにプラグインを作ってみたいという奇特な方がいらっしゃるようでしたらこの上なく幸せです。 まだサンプルプログラムが少ないのですが、私も幾つかプラグインを作っているのでよろしければそれを見てみてください。

https://github.com/scala-irc-bot