React native 和 IBM Watson

React native and IBM Watson

我一直在使用 expo 构建 React 本机应用程序,并希望将 IBM Watson chatbot 集成到我的平台上。但是,当我导入模块时,我收到很多错误消息作为核心节点模块,例如 os and fs seem to be missing,但没有使用 node.js 下载] 出于某种原因。当我尝试手动添加这些时,HTTPS 模块缺少 index.js 文件。我有什么办法可以找到这个文件或用其他方法解决这个问题吗?

从你的问题中还不完全清楚,但我假设你正在使用能够使用 ios 和 android 代码与文件系统交互的 Node SDK for Watson Assistant. This is designed to be run in a Node.js environment which a react native JavaScript bundle is not (with or without expo). That's why you are missing key libraries like os and fs which the Node SDK expects. Installing fs won't resolve your problem because it also expects a Node.js environment to work, hence why there are react native specific fs libraries phone.

您应该尝试的是 运行在独立服务器上使用 Node SDK 并使用像 axios or for more robust production systems graphql 这样的库 运行 使用简单的 api 请求,以便您的架构将近似此高级设计。

a high level architecture diagram which shows a phone connected by an arrow reading axios api request to another box labelled cloud hosted server. From this box another arrow labelled Node SDK is pointing to another box labelled Watson Assistant

Web 应用程序同样受到限制。用户浏览器上的代码运行不能直接使用Watson Assistant SDK,这些对Watson Assistant的请求需要通过服务器运行。有一个 example starter Watson Assistant web application 可以做到这一点。如果您 运行 或托管此应用程序,您可以使用相同的服务器来处理您的请求(但请记住,这个简单的应用程序和共享流量可能无法扩展,只能用于概念验证)。

因此,与其 运行 直接向 Watson Assistant 发送 api 请求,不如 运行 将它们发送到服务器的这个域,然后是必要的端点。示例应用程序中的服务器设置为接受在 <your domain>/api/session 启动 session 并在 <your domain>/api/message

发送消息的请求

您可以选择 运行 从没有 SDK 的 React 本机应用直接 api 调用 Watson Assistant。这是不可取的,因为您需要将私钥存储在任何人都可以查看的设备上。

这里是一个功能组件,可以在没有SDK的情况下使用消息工具v1直接完成api对Watson Assistant的调用。但不建议这样做,因为我必须不安全地存储我的密钥。

import React, { useState } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import axios from 'axios';
import base64 from 'react-native-base64';

const workspace = ''; //replace with your own workspace id
const key = ''; //replace with your own key
const encodedKey = base64.encode(`apikey:${key}`);
// the following url will be different depending on where you host your Watson Assistant
// this is for Frankfurt as an example hence eu-de in the domain name
const assistantInstance =
  'https://api.eu-de.assistant.watson.cloud.ibm.com/instances/<This is your own>/v1'; //replace with your own

const ExampleComponent = () => {
  const [response, setResponse] = useState('');
  const sendMessage = () => {
    axios
      .post(
        `${assistantInstance}/workspaces/${workspace}/message?version=2018-09-20`,
        {
          input: { text: 'This is the message' },
        },
        {
          headers: {
            Authorization: `Basic ${encodedKey}`,
            'Content-Type': 'application/json',
          },
        },
      )
      .then((data: any) => {
        console.log(data);
        setResponse('Got response');
      })
      .catch((err: any) => {
        console.log(err);
        setResponse('Got an error');
      });
  };
  return (
    <View>
      <Text>{response}</Text>
      <TouchableOpacity
        onPress={() => {
          sendMessage();
        }}
      >
        Send message
      </TouchableOpacity>
    </View>
  );
};

export default ExampleComponent;

您会发现的下一个复杂问题是您需要添加代码来存储响应中返回的上下文,否则您的状态将丢失。您的 body 最终会看起来像

        {
          input: { text: 'This is the message' },
          context: savedContextObject
        },

API 的较新版本有一个有状态的版本,您可能想改用它。您可以使用此 axios 作为构建您喜欢的任何请求的模式。

第三次也是最后一次,请不要像我在这里那样将您的 API 密钥保存到 JS 文件中。这仅作为示例和概念证明。任何下载您的应用程序的人都可以解压缩您的 apk 并在未加密的情况下读取您生成的 JS 包中的这些字符串!