其の五:hubotの文字化けを直す
前回、hubotが無事インストールできたので、文字化けを対策する。
hubotで扱う文字コードはUTF-8が前提となっており、会社で使っているISO-2022-JPのチャットサーバーだと、文字化けを起こしてしまう。
以前perlのnkfモジュールを用いて対策を行ったことがあったが、coffeeスクリプトで対策できることが分かったので、そちらで対策する。
まずは、hubotをインストールしたディレクトリに移動して、必要なモジュール(jschardet、iconv)を追加インストールする。
$ cd ~/hubot $ npm install jschardet $ npm install iconv次に、irc.coffeeに修正を加える。
$ cd ~/hubot/node_modules/hubot-irc/src $ cp irc.coffee irc.coffee.org $ vi irc.coffee修正内容(diffイメージ)は以下で、最初にrequireで追加したモジュールをロード。
日本語のチャンネル名が指定された場合に備えて、チャンネル名をUTF8からISO-2022-JPに変更する処理を追加。
sendメソッドとnoticeメソッドに文字コードをUTF-8からISO-2022-JPに変更する処理を追加。messageやchannelを受け取るbotListener(message,notice等)に受け取った文字をUTF-8に変更する処理を追加。
ちなみに、iconv生成時のパラメータで指定している『TRANSLIT//IGNORE』はコード変換失敗時にエラーを無視するためのおまじないみたい。
# Irc library Irc = require 'irc' +# for ISO-2022-JP +Jschardet = require 'jschardet' +Iconv = (require 'iconv').Iconv + class IrcBot extends Adapter send: (envelope, strings...) -> # Use @notice if SEND_NOTICE_MODE is set @@ -15,6 +19,8 @@ return console.log "ERROR: Not sure who to send to. envelope=", envelope for str in strings + iconv = new Iconv('UTF-8','ISO-2022-JP//TRANSLIT//IGNORE') + str = iconv.convert(str).toString() @bot.say target, str topic: (envelope, strings...) -> @@ -52,6 +58,8 @@ if not str? continue + iconv = new Iconv('UTF-8','ISO-2022-JP//TRANSLIT//IGNORE') + str = iconv.convert(str).toString() @bot.notice target, str reply: (envelope, strings...) -> @@ -131,11 +139,15 @@ do @checkCanStart + iconv = new Iconv('UTF-8','ISO-2022-JP//TRANSLIT//IGNORE') + roomsValue = iconv.convert(process.env.HUBOT_IRC_ROOMS).toString() + options = nick: process.env.HUBOT_IRC_NICK or @robot.name realName: process.env.HUBOT_IRC_REALNAME port: process.env.HUBOT_IRC_PORT - rooms: process.env.HUBOT_IRC_ROOMS.split(",") +# rooms: process.env.HUBOT_IRC_ROOMS.split(",") + rooms: roomsValue.split(",") ignoreUsers: process.env.HUBOT_IRC_IGNORE_USERS?.split(",") or [] server: process.env.HUBOT_IRC_SERVER password: process.env.HUBOT_IRC_PASSWORD @@ -189,15 +201,27 @@ if options.connectCommand? bot.addListener 'registered', (message) -> + detectResult = Jschardet.detect(message) + iconv = new Iconv(detectResult.encoding,'UTF-8//TRANSLIT//IGNORE') + message = iconv.convert(message).toString() + # The 'registered' event is fired when you are connected to the server strings = options.connectCommand.split " " self.command strings.shift(), strings... bot.addListener 'names', (channel, nicks) -> + detectResult = Jschardet.detect(channel) + iconv = new Iconv(detectResult.encoding,'UTF-8//TRANSLIT//IGNORE') + channel = iconv.convert(channel).toString() + for nick of nicks self.createUser channel, nick bot.addListener 'notice', (from, to, message) -> + detectResult = Jschardet.detect(message) + iconv = new Iconv(detectResult.encoding,'UTF-8//TRANSLIT//IGNORE') + message = iconv.convert(message).toString() + if from in options.ignoreUsers console.log('Ignoring user: %s', from) # we'll ignore this message if it's from someone we want to ignore @@ -209,6 +233,10 @@ self.receive new TextMessage(user, message) bot.addListener 'message', (from, to, message) -> + detectResult = Jschardet.detect(message) + iconv = new Iconv(detectResult.encoding,'UTF-8//TRANSLIT//IGNORE') + message = iconv.convert(message).toString() + if options.nick.toLowerCase() == to.toLowerCase() # this is a private message, let the 'pm' listener handle it return @@ -231,6 +259,10 @@ self.receive new TextMessage(user, message) bot.addListener 'action', (from, to, message) -> + detectResult = Jschardet.detect(message) + iconv = new Iconv(detectResult.encoding,'UTF-8//TRANSLIT//IGNORE') + message = iconv.convert(message).toString() + console.log " * From #{from} to #{to}: #{message}" if from in options.ignoreUsers @@ -247,9 +279,17 @@ self.receive new TextMessage(user, message) bot.addListener 'error', (message) -> + detectResult = Jschardet.detect(message) + iconv = new Iconv(detectResult.encoding,'UTF-8//TRANSLIT//IGNORE') + message = iconv.convert(message).toString() + console.error('ERROR: %s: %s', message.command, message.args.join(' ')) bot.addListener 'pm', (nick, message) -> + detectResult = Jschardet.detect(message) + iconv = new Iconv(detectResult.encoding,'UTF-8//TRANSLIT//IGNORE') + message = iconv.convert(message).toString() + console.log('Got private message from %s: %s', nick, message) if process.env.HUBOT_IRC_PRIVATE @@ -267,21 +307,37 @@ self.receive new TextMessage({reply_to: nick, name: nick}, message) bot.addListener 'join', (channel, who) -> + detectResult = Jschardet.detect(channel) + iconv = new Iconv(detectResult.encoding,'UTF-8//TRANSLIT//IGNORE') + channel = iconv.convert(channel).toString() + console.log('%s has joined %s', who, channel) user = self.createUser channel, who user.room = channel self.receive new EnterMessage(user) bot.addListener 'part', (channel, who, reason) -> + detectResult = Jschardet.detect(channel) + iconv = new Iconv(detectResult.encoding,'UTF-8//TRANSLIT//IGNORE') + channel = iconv.convert(channel).toString() + console.log('%s has left %s: %s', who, channel, reason) user = self.createUser '', who user.room = channel self.receive new LeaveMessage(user) bot.addListener 'kick', (channel, who, _by, reason) -> + detectResult = Jschardet.detect(channel) + iconv = new Iconv(detectResult.encoding,'UTF-8//TRANSLIT//IGNORE') + channel = iconv.convert(channel).toString() + console.log('%s was kicked from %s by %s: %s', who, channel, _by, reason) bot.addListener 'invite', (channel, from) -> + detectResult = Jschardet.detect(channel) + iconv = new Iconv(detectResult.encoding,'UTF-8//TRANSLIT//IGNORE') + channel = iconv.convert(channel).toString() + console.log('%s invited you to join %s', from, channel) if from in options.ignoreUsers本来なら、環境変数もしくはコマンドパラメータで変換する文字コードを指定すべきだが、今回はそこまでやってない。
上記修正が正しく動作するか確認するために、hubot-scriptsのhttp-post-say.coffeeを使ったため、それの設定方法も残しておく。
まず、hubotインストールディレクトリに移動して、hubot-scripts.jsonを編集。
$ cd ~/hubot $ vi hubot-scripts.jsonhubot-scripts.jsonの内容は以下。他に追加したいスクリプトがあればカンマ(,)区切りで追加すればよい。
["http-post-say.coffee"]hubotの待ち受けポートは、デフォルト8080になっている。変更する場合には、以下のようにhubot起動スクリプトに環境変数PORTの設定処理を追加し、起動すればよい。
$ vi runbot.sh
#!/bin/bash # hubot http port setting export PORT=9999 # runhubot export HUBOT_IRC_NICK="hubot" export HUBOT_IRC_ROOMS="#test01,#test02" export HUBOT_IRC_SERVER="localhost" #export HUBOT_IRC_PASSWORD="hoge" bin/hubot -a irc
$ .runbot.shhttp-post-say.coffeeを使って、http経由でhubotに発言させるにはcurlコマンド等で以下のようにすればよい。
$ curl -X POST http://localhost:9999/hubot/say -d message=文字化けた? -d room='#test01'ISO-2022-JPのチャットサーバって、世の中一般では、レアなんですかね。。。うちの会社だけなのかなぁ。。。。
あと、おまけで、hubotの発言をnoticeにする方法がわかった。すごく簡単で、起動時に環境変数HUBOT_IRC_SEND_NOTICE_MODEにtrueを設定するだけだった。イメージは以下。
#!/bin/bash # hubot http port setting export PORT=9999 # runhubot export HUBOT_IRC_NICK="hubot" export HUBOT_IRC_ROOMS="#test01,#test02" export HUBOT_IRC_SERVER="localhost" #export HUBOT_IRC_PASSWORD="hoge" export HUBOT_IRC_SEND_NOTICE_MODE="true" bin/hubot -a irc
0 件のコメント :
コメントを投稿