GeekFactory

int128.hatenablog.com

Hubot+IRCの文字化けを解決する

HubotはGitHubが開発したbotフレームワークで、SlackやHipChat、IRCなどの多くのプロトコルに対応しています。そのため、ローカルネットワークのIRCサーバにbotを導入する用途にも使えます。

古くから運用されているIRCサーバの中には、文字コードISO-2022-JP(JISコード)に設定されているものがあります。HubotはUTF-8を前提にしているため、ISO-2022-JPで運用しているIRCサーバでHubotを使うと文字化けが発生します。

解決策

Hubotの文字化けを解決するには以下の方法があります。

  1. IRCサーバやIRCクライアントの設定をUTF-8に変更します。設定変更が簡単にできる場合はこの方法が最適です*1
  2. IRCプロキシで文字化けを解決します。この方法は、運用管理の対象が増えるデメリットがあります。
  3. Hubot側で文字コードを変換します。この方法は、Hubotのスクリプトに手を入れる必要があるというデメリットがあります。

本稿では、3のHubot側で文字コードを変換する方法を説明します。

文字コード変換の方法

HubotはNode.jsで動作します。Node.jsで文字コードを変換するにはiconvを使います。以下の送受信のタイミングで文字コード変換を行うようにします。

  • Hubotが受け取ったメッセージをISO-2022-JPからUTF-8に変換します。
  • Hubotが送信するメッセージをUTF-8からISO-2022-JPに変換します。

具体例

ここではYeomanでHubotを生成した状態を想定します。プロンプトでIRCを選択するとhubot-ircが自動的に追加されます。

npm install -g generator-hubot
yo hubot

npmでiconvをインストールします。

npm install iconv --save

botスクリプトにiconvを追加します。具体的には、robot.hearで受け取った文字列やmsg.replyで送信する文字列に対して文字コードの変換を追加します。以下はオウム返しの例です。

# scripts/example.coffee

module.exports = (robot) ->
  Iconv = require('iconv').Iconv
  jis2utf = new Iconv('ISO-2022-JP', 'UTF-8')
  utf2jis = new Iconv('UTF-8', 'ISO-2022-JP')

  robot.hear /(.+)/, (msg) ->
    heard = jis2utf.convert(msg.message.text).toString()
    msg.reply utf2jis.convert(heard)

以下のようなスクリプトを作成しておくと簡単に起動できるので便利です。

#!/bin/sh
export HUBOT_IRC_SERVER=192.168.1.2
export HUBOT_IRC_ROOMS="#myroom"
export HUBOT_IRC_NICK="examplebot"
export HUBOT_IRC_UNFLOOD="true"
exec bin/hubot -a irc --name examplebot

もしくは、Dockerfileを書いておくと他のマシンでも使い回しが利くので便利です。

*1:IRCクライアントは文字コードを自動認識にしておけば大丈夫かも?