質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.80%

ラインボットでpushした後の返答を取得したいです

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 613

zfanr

score 14

前提・実現したいこと

ユーザーがラインボットに話しかけてきた後に、ラインボットがユーザーに質問をして、その回答を取得したいです。
その場合、どのように書けばいいのかわかりせん。

現状、ラインボットがユーザーに質問をする(push)ところまでは動作しています。
以下のような書き方が動作しないのは大枠として理解していますが、やりたいことはこのようなことだと思います。

app.post('/hook', function (req, res) {
//1回目のpost
 app.post('/hook', function (req, res) {
  //2回目のpost
 });
});

該当のソースコード

const express = require('express')
const request = require('request')
const bodyParser = require('body-parser');
const crypto = require("crypto");
const app = express()
const port = process.env.PORT || 3000;

app.use(bodyParser.urlencoded({
  extended: true
}));
app.use(bodyParser.json());
app.get('/', (req, res) => {
  res.send('Hello world')
})
app.post('/hook', function (req, res) {

  if (!validateSignature(req.headers['x-line-signature'], req.body)) {
    return;
  }

  const events = req.body.events;
  const userId = events[0].source.userId;
  const type = events[0].source.type;
  const message = events[0].message;

  if(type == 'user'){
    request.get( getProfileOption(userId), function (error, response, body) {
      if (!error && response.statusCode == 200) {

        const options = {
          url: 'https://api.line.me/v2/bot/message/push',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer {' + process.env.LINE_CHANNEL_ACCESS_TOKEN + '}',
          },
          json: true,
          body: {
            'to': userId,
            'messages': [{
              "type": "text",
              "text": '話しかけてくれてありがとう\nあなたのお名前を教えて'
            }]
          }
        };
        request.post(options, function (error, response, body) {
          if (!error && response.statusCode == 200) {
            app.post('/hook', function (req, res) {
              console.log('push後にユーザーが返事した場合');
            })
          }

        });
      }
    })
  }
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

function getProfileOption(userId) {
  return {
    url: 'https://api.line.me/v2/bot/profile/' + userId,
    json: true,
    headers: {
      'Authorization': 'Bearer {' + process.env.LINE_CHANNEL_ACCESS_TOKEN + '}'
    }
  };
}
function validateSignature(signature, body) {
  const hmac = crypto.createHmac('sha256', process.env.LINE_CHANNEL_SECRET);
  const data = new Buffer(JSON.stringify(body), 'utf8');
  const result = hmac.update(data).digest('base64');
  return signature == result;
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

何回めの返事なのか?とかは返ってくるメッセージに書かれていないので、送られてきたmessageを取得して、それをおうむ返しする形で整形したものを返せば良いかと思います。

なので一部ですが

body: {
            'to': userId,
            'messages': [{
              "type": "text",
              "text": 'あなたのお名前は' + message + 'ですね'
            }]
          }


みたいな形にするとかかと思います。
でも、これだと名前じゃない場合でも、「あなたのお名前は〜」になるので、ほかの文字の時にどうするか?はまた考えないといけませんが、それっぽいことはこれで良いかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/29 21:01

    私が理解している中では無いと思います。
    ボタンテンプレートとかで回答を絞った上でifするしか方法が無いかな?と思っていますが…。

    キャンセル

  • 2019/04/29 22:19

    こちらが回答として正しい方針だとおもうので別回答をたてず、こちらにコメントさせていただきます。

    1か3かを知るにはユーザとの会話履歴を保持することによってしか識別できません。ボットに送信されてきたメッセージには本文以外にも時刻・ユーザid(グループやルームidのこともある)が含まれますので、それを組合せて履歴データを必要なだけ構築しておき、ボットはこのユーザとどういう会話を進展させてきたかを、この過去の構築済みのデータから、判断する必要があります。これが構築できる仕組みがあれば、履歴がないことから状況「1」にあることが判断できます(実用されているボットは、過去履歴があっても一定時間経過すると忘れる機能もあると思います)。
    e-mailのように「返信」という操作がないので、tomomi66様が挙げられたようにボタンを作るのでなければ、どれに対する返信かは、今回送られてきた情報だけからは判断できません。

    キャンセル

  • 2019/04/29 23:02

    そうなんですね。。。

    最初に話しかけられた時にユーザIDをデータベースに保存しておいて、次に話しかけられたらそのIDをもとにデータベースに照合するという方法なのかと思っています。

    tomomi66さん、papinianusさん
    ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る