INPUTしたらOUTPUT!

忘れっぽいんでメモっとく

LINE Messaging APIでLINE botを作る(1) 対話実装

ビール片手にLT大会 vol.3 (at WeWork日比谷) - connpassでLTした通り、自分の部屋を擬人化したLINE botを作った。

f:id:tak95:20190530211520p:plain
アヤメ(俺の部屋bot

もともと掃除・片付けが苦手で部屋を擬人化することで掃除後に「きれいになったね」とメッセージすると「ありがとう」などのリプライがあることで掃除のモチベーションを上げたいというのがbot作成のきっかけ。

botの機能としては以下の通り。

  • メッセージに対してUserlocalの全自動会話APIのレスポンスをリプライする
  • メッセージに「掃除」「片付け」が含まれているとHabiticaの「部屋の掃除」タスクのスコアを上げる
  • メッセージに「おやすみ」が含まれていると消灯する
  • メッセージに「気温」「何度」が含まれていると部屋の気温/湿度/照度をリプライする

f:id:tak95:20190530213056p:plain

f:id:tak95:20190530213124p:plain

f:id:tak95:20190530213202p:plain


対話機能の実装

まずは以下を参照してメッセージをおうむ返しするbotを作成する。

qiita.com

基本的にechoman()にメッセージに応じた処理を追加していくだけ。

// 追加
async function echoman(ev) {
  const pro =  await client.getProfile(ev.source.userId);
  return client.replyMessage(ev.replyToken, {
    type: "text",
    text: `${pro.displayName}さん、今「${ev.message.text}」って言いました?`
  })
}


対話はUserlocalの全自動会話APIを活用して行う。

レスポンスがstatusとresultの2つだけという超絶シンプルなAPIとなっている。

$ curl 'https://chatbot-api.userlocal.jp/api/chat?message=おはよう&key=**********'
{"status":"success","result":"OHAYO"}
$


上記のレスポンスをそのままリプライするだけだがnode.jsは基本的に非同期で処理されるためHTTP GETの内容を同期して返す関数requestSync()を実装する。

function requestSync (options) {
  return new Promise(function (resolve, reject) {
    request(options, function (error, respons, body) {
      if (error) {
        console.log('[in]requestAsync(): error.')
        reject(error) // errがあればrejectを呼び出す
        return
      }
      console.log('[in]requestAsync(): ok.')
      resolve(body) // errがなければ成功とみなしresolveを呼び出す
    })
  })
}


次にUserlocalのAPIを実行する関数conversation()を実装する。

async function conversation (message) {
  let options = {
    url: 'https://chatbot-api.userlocal.jp/api/chat',
    qs: {
      message: message,
      key: userlocalKey
    },
    method: 'GET',
    json: true
  }
  let body = await requestSync(options)
  let msg = body.result
  console.log(`[in]conversation(): msg = ${msg}`)
  return msg
}


あとはechoman()conversation()を呼び出すだけ。

~ 略 ~
const request = require('request')
const userlocalKey = process.env.USERLOCAL_KEY

~ 略 ~

async function echoman (ev) {
  // const pro = await client.getProfile(ev.source.userId)
  let msg = await conversation(ev.message.text)
  return client.replyMessage(ev.replyToken, {
    type: 'text',
    text: msg
  })
}


herokuにデプロイするとbotと対話できるようになる。

f:id:tak95:20190530223028p:plain



  • 部屋を擬人化することで拭き掃除とか想像しながら行うと捗るかと思ったが自分はそこまで変態ではなかった

ということで次は習慣をゲーミフィケーションするサービス「Habitica - Gamify Your Life」との連携を行う。