【问题标题】:How to integrate Dialogflow v2 with javascript frontend (Vue.js)如何将 Dialogflow v2 与 javascript 前端 (Vue.js) 集成
【发布时间】:2018-11-05 06:22:52
【问题描述】:

我正在尝试根据文档的示例 HTTP 请求:https://dialogflow.com/docs/reference/v2-auth-setup 和 detectIntent:https://dialogflow.com/docs/reference/api-v2/rest/v2beta1/projects.agent.sessions/detectIntent,将 Dialogflow 与 Vue.js(和 axios)集成。

我设置了一个具有足够权限的服务帐户,并为其提供了文档中所示的路径参数和请求正文,但在调用 detectIntent API 时,我不断收到“错误:请求失败,状态码为 400”。

不过,有几件事我不确定:

  1. 如何获得 sessionId?目前我只是从 Firebase 函数日志中复制 sessionId,该日志在直接通过 Dialogflow 控制台输入查询时显示。

  2. 如何在 javascript 代码中实际实现 $(gcloud auth print-access-token)?目前我正在终端中运行命令并将令牌粘贴到代码中,只是为了测试API是否有效,但我不知道它应该如何实现。

(也许有用,我在函数文件夹中设置了实现,效果很好。)

提前致谢!

<script>
import axios from 'axios'

export default {
  name: 'myChatBot',
  mounted () {

    // Authorization: Bearer $(gcloud auth print-access-token)
    
    const session = 'projects/mychatbot/agent/sessions/some-session-id'
    const token = 'xxxxxxxxxxxx'
    axios.defaults.baseURL = 'https://dialogflow.googleapis.com'
    axios.defaults.headers.common['Authorization'] = `Bearer ${token}`
    axios.defaults.headers.post['Content-Type'] = 'application/json'
    
    axios
      .post(`/v2beta1/${session}:detectIntent`, {
        "queryInput": {
          "text": "add buy milk to inbox",
          "languageCode": "en-US"
        }
      })
      .then(response => console.log(response))
      .catch(error => console.log(error))
  }

}
</script>

【问题讨论】:

    标签: javascript vue.js axios dialogflow-es http-status-code-400


    【解决方案1】:

    sessionId 是您可以提供的标识符,它将向 Dialogflow 指示后续请求是否属于用户交互的同一“会话” (see docs)。

    对于客户端对 API 的第一次请求,您可以生成一个随机数以用作会话 ID。对于来自同一客户的后续请求(例如,如果用户继续与您的代理交谈),您可以重复使用相同的号码。

    只要您使用的服务帐户具有适当的访问权限(因为此令牌可能允许任何人向 Google Cloud API 发出请求),您的令牌管理实现看起来就很好。为了提高安全性,您可以考虑通过自己的服务器将请求代理到 Dialogflow,而不是从客户端进行调用。

    【讨论】:

    • 经过研究我发现JS SDK目前不适用于V2。正如下面的答案提到的,我们也可以使用 JWT,而不是直接使用令牌。你有什么建议,应该如何实施。因为使用它们似乎都不安全。如果我们中间使用nodejs,恐怕会增加延迟,尤其是如果我们使用音频流。
    【解决方案2】:

    您可以使用 JWT 授权来处理您的 #2 问题。您只需要将 JSON 文件放在安全的地方。 https://developers.google.com/identity/protocols/OAuth2ServiceAccount#jwt-auth

    您获得代码 400 的原因是您的参数有点偏离。这是您的帖子的外观(我还添加了一些额外的代码来处理令牌生成):

    <script>
    import axios from 'axios'
    import { KJUR } from 'jsrsasign'
    
    const creds = require('./YOUR_JSON_FILE')  
    
    export default {
      name: 'myChatBot',
      data() {
        return {
          token: undefined,
          tokenInterval: undefined
        }
      },
      created() {
        // update the tokens every hour
        this.tokenInterval = setInterval(this.generateToken, 3600000)
        this.generateToken()
      },
      mounted () {
        this.detectIntent('add buy milk to inbox')
      },
      beforeDestroy() {
        clearInterval(this.tokenInterval)
      },
      methods: {
        generateToken() {
          // Header
          const header = {
            alg: 'RS256',
            typ: 'JWT',
            kid: creds.private_key_id
          }
    
          // Payload
          const payload = {
            iss: creds.client_email,
            sub: creds.client_email,
            iat: KJUR.jws.IntDate.get('now'),
            exp: KJUR.jws.IntDate.get('now + 1hour'),
            aud: 'https://dialogflow.googleapis.com/google.cloud.dialogflow.v2.Sessions'
          }
          
          const stringHeader = JSON.stringify(header)
          const stringPayload = JSON.stringify(payload)
          this.token = KJUR.jws.JWS.sign('RS256', stringHeader, stringPayload, creds.private_key)
        },
        detectIntent(text, languageCode = 'en-US') {
          if (!this.token) {
            // try again
            setTimeout(this.detectIntent, 300, text, languageCode)
            return
          }
          
          // error check for no text, etc.
    
          const session = 'projects/mychatbot/agent/sessions/some-session-id'
          axios.defaults.baseURL = 'https://dialogflow.googleapis.com'
          axios.defaults.headers.common['Authorization'] = `Bearer ${this.token}`
          axios.defaults.headers.post['Content-Type'] = 'application/json'
    
          axios
            .post(`/v2beta1/${session}:detectIntent`, {
              queryInput: {
                text: {
                  text,
                  languageCode
                }
              }
            })
            .then(response => console.log(response))
            .catch(error => console.log(error))
        }
      }
    }
    </script>

    您可以看到,在 QueryInput 中,它采用了 3 种不同类型的对象中的 1 种(“文本”就是其中之一)。

    【讨论】:

      【解决方案3】:

      在link 中,HTTP 请求会话路径参数下声明“由 API 调用者选择适当的会话 ID。 它可以是随机数或某种类型的用户标识符(最好是散列)。

      对于与 Dialogflow V2 的集成,这里有一个 example,用于使用易于集成和开始使用的第三方工具。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-27
        • 2020-07-20
        • 1970-01-01
        • 1970-01-01
        • 2019-10-25
        • 1970-01-01
        • 1970-01-01
        • 2016-09-03
        相关资源
        最近更新 更多