ハッカソンで動くものができたので、メモ。
全ソースは以下です。
https://github.com/hiranoi/kuidaore_bot
INDEX
- この記事のゴール
- Rails Heroku × lineapiでオウム返しするbotを作る
- Rails Heroku × Repl-AIで会話できるbotを作る
- Repl-AIの会話を大阪弁に変換すして返すbotを作る
この記事のゴール
Rails Heroku × lineapiでオウム返しするbotを作る
- 以下の記事を全て参考にさせていただきました。本当にありがとうございます。
http://qiita.com/Arahabica/items/98e3d0d5b65269386dc4
Rails Heroku × Repl-AIで会話できるbotを作る
- こちらは本家リファレンスを参考にライブラリ作成
https://repl-ai.jp/references/registration.html
https://repl-ai.jp/references/dialogue.html
/lib/repl_ai_client.rb
require "faraday"
require "faraday_middleware"
require "json"
require "pp"
class ReplAiClient
URL_HEAD = 'https://api.repl-ai.jp'
def initialize(api_key, bot_id = 'normal', scenario ='greeting')
@api_key = api_key
@bot_id = bot_id
@scenario = scenario
end
def get_user_id
res = post('/v1/registration',{
botId: @bot_id
})
res.body
end
def get_message(user_id, message, flag = true)
res = post('/v1/dialogue',{
appUserId: user_id,
botId: @bot_id,
voiceText: message,
initTalkingFlag: flag,
initTopicId: @scenario,
appRecvTime: Time.now.strftime('%Y/%m/%d %H:%M:%S'),
appSendTime: Time.now.strftime('%Y/%m/%d %H:%M:%S'),
})
res.body
end
private
def post(path, data)
client = Faraday.new(:url => URL_HEAD) do |conn|
conn.request :json
conn.response :json, :content_type => /\bjson$/
conn.adapter Faraday.default_adapter
# conn.proxy @proxy
end
res = client.post do |request|
request.url path
request.headers = {
'Content-type' => 'application/json; charset=UTF-8',
'x-api-key' => @api_key
}
request.body = data
end
res
end
end
/app/controllers/webhook_controller.rb
class WebhookController < ApplicationController
protect_from_forgery except: :callback # CSRF対策無効化
CHANNEL_ID = ENV['LINE_CHANNEL_ID']
CHANNEL_SECRET = ENV['LINE_CHANNEL_SECRET']
CHANNEL_MID = ENV['LINE_CHANNEL_MID']
OUTBOUND_PROXY = ENV['LINE_OUTBOUND_PROXY']
REPL_API_KEY = ENV['REPL_API_KEY']
def callback
unless is_validate_signature
render :nothing => true, status: 470
end
result = params[:result][0]
logger.info({from_line: result})
req_message = result['content']['text']
from_mid = result['content']['from']
repl_client = ReplAiClient.new(REPL_API_KEY)
res_message = repl_client.get_message('TODO:USER_IDを入れる', req_message)
client = LineClient.new(CHANNEL_ID, CHANNEL_SECRET, CHANNEL_MID, OUTBOUND_PROXY)
res = client.send([from_mid], res_message['systemText']['expression'])
if res.status == 200
logger.info({success: res})
else
logger.info({fail: res})
end
render :nothing => true, status: :ok
end
private
# LINEからのアクセスか確認.
# 認証に成功すればtrueを返す。
# ref) https://developers.line.me/bot-api/getting-started-with-bot-api-trial#signature_validation
def is_validate_signature
signature = request.headers["X-LINE-ChannelSignature"]
http_request_body = request.raw_post
hash = OpenSSL::HMAC::digest(OpenSSL::Digest::SHA256.new, CHANNEL_SECRET, http_request_body)
signature_answer = Base64.strict_encode64(hash)
signature == signature_answer
end
end
terminal上で
# 定数を設定する
$ heroku config:add REPL_API_KEY="XXXXXXXXXXXXXXXXXXX"
※注意
- ハッカソンの時間の都合上、ユーザごとにID払い出す処理を行っていません。(LINEのIDとRepl-AIのIDを紐付けるのが面倒だった)そのため、ユーザAの会話情報がユーザBにも引き継がれます。
Repl-AIの会話を大阪弁に変換すして返すbotを作る
- ここを参考にRubyに変換する
http://www.geocities.co.jp/Hollywood/4078/osaka/osakajs.html
/lib/convert_to_osaka.rb
require 'yaml'
class ConvertToOsaka
def initialize(tm)
@tm = tm
end
def convert
d = YAML.load_file("#{Rails.root}/lib/osaka.yml")
# 文章にhashのキーが含まれているかを確認する
d.each do |k, v|
# 一致すればvalueに置換する
@tm.gsub!(k, v)
end
@tm
end
end
- センスはないが、標準語→大阪弁の対応表はHashで持つ
/lib/osaka.yml
ありがとうございました: おおきに
あなた: あんさん
あんな: あないな
りますので: るさかいに
りますから: るさかいに
あります: あるんや
あるいは: せやなかったら
或いは: せやなかったら
ありません: おまへん
ありました: おました
いない: おらへん
いまどき: きょうび
いわゆる: なんちうか,ようみなはんいわはるとこの
・
・
・ # 長いので割愛
/app/controllers/webhook_controller.rb
# 以下の部分を編集
res = client.send([from_mid], ConvertToOsaka.new(res_message['systemText']['expression']).convert)
こんな感じです。まだまだ改善の余地はありますが、一旦これで動きます。