繁体   English   中英

如何在 twilio 对话中使用 React 正确发送消息?

[英]How to send properly a message in twilio conversation with react?

我有一个 nextjs 项目,我想用 twilio 对话替换 twilio 可编程聊天。

我做了以下步骤:

  1. 我做了一个 API创建或获取(如果已经创建)对话并向客户端返回 c 对话唯一名称令牌

  2. 一旦我有了对话的唯一名称和令牌,我想向客户端发送一条消息。

为此,我执行了以下操作 function:

import { Client, State } from '@twilio/conversations';
import toast from 'react-hot-toast';

const sendMessageToConversation = async (
  token: string,
  room: string,
  message: string
) => {
  const client = new Client(token);
  client.on('stateChanged', async (state: State) => {
    if (state === 'initialized') {
      try {
        const conversation = await client.getConversationByUniqueName(room);
        await conversation.join();
        if (message && String(message).trim()) {
          await conversation.sendMessage(message);
        }
      } catch {
        toast.error('Unable to create conversation, please reload this page');
      }
    }
  });
};

问题似乎是const conversation = await client.getConversationByUniqueName(room); 这给出了以下错误:

在此处输入图像描述

你觉得我做错了什么?

构建一个 API 以这种方式发送消息也是一个更好的主意吗? 由于服务器可能的开销,我会避免这种情况

更新

我试图通过 API发送消息。 它有效并返回我所期望的。 有关更多详细信息,我还将在后端放置生成令牌和对话的代码。

我为客户端生成令牌:

import Twilio from 'twilio';
import { config } from '../config';
const client = require('twilio')(
  config.TWILIO_ACCOUNT_SID,
  config.TIWLIO_AUTH_TOKEN
);

const AccessToken = Twilio.jwt.AccessToken;
const ChatGrant = AccessToken.ChatGrant;
const SyncGrant = AccessToken.SyncGrant;

export const tokenGenerator = (identity: string) => {
  const token = new AccessToken(
    config.TWILIO_ACCOUNT_SID,
    config.TWILIO_API_KEY,
    config.TWILIO_API_SECRET
  );

  token.identity = identity || 'unknown';

  if (config.TWILIO_CHAT_SERVICE_SID) {
    const chatGrant = new ChatGrant({
      serviceSid: config.TWILIO_CHAT_SERVICE_SID,
      pushCredentialSid: config.TWILIO_FCM_CREDENTIAL_SID,
    });
    token.addGrant(chatGrant);
  }

  if (config.TWILIO_SYNC_SERVICE_SID) {
    const syncGrant = new SyncGrant({
      serviceSid: config.TWILIO_SYNC_SERVICE_SID || 'default',
    });
    token.addGrant(syncGrant);
  }

  return {
    identity: token.identity,
    token: token.toJwt(),
  };
};

我创建对话:

const client = require('twilio')(
  config.TWILIO_ACCOUNT_SID,
  config.TIWLIO_AUTH_TOKEN
);

export const createTwilioConversation = async (
  partecipantsProfiles: Partial<User>[],
  identity: string
) => {
  const friendlyName: string = partecipantsProfiles
    .map((el) => `${el.first_name} ${el.last_name}`)
    .join(' - ');

  const conversation = (await client.conversations.conversations.create({
    friendlyName,
    uniqueName: uuidv4(),
  })) as TwilioConversationResponse;

  await client.conversations
    .conversations(conversation.sid)
    .participants.create({ identity });

  return conversation;
};

我为了发送消息所做的流程是:

  • 如果我想发送一条消息,我会通过调用 API 创建一个对话,执行上面的函数并返回房间的唯一名称和令牌。 我还将房间唯一名称、参与者和其他信息存储到我的数据库中。 我只对第一条消息这样做。 如果一个用户已经与另一个用户聊天,那么我不再创建对话,但我返回存储的唯一名称 + 生成的令牌,并在客户端获取/发送消息

我也尝试过通过 API 发送消息并且它有效。 我不明白为什么我仍然无法通过客户端的唯一名称进行对话。 也许我应该以不同的方式生成令牌?

这是发送消息服务器端的方法:

export const sendMessage = async (
  conversationSid: string,
  author: string,
  body: string
) => {
  return await client.conversations
    .conversations(conversationSid)
    .messages.create({ author, body });
};

您的问题是您没有使用默认的对话服务,但您没有将服务器端的 API 调用范围限定为您需要的服务。

因此,在pages/api/utils/conversations中,您需要将.services(config.TWILIO_CHAT_SERVICE_SID)添加到所有 API 调用中。 见下文:

export const createTwilioConversation = async (
  chatTo: string,
  myIdentity: string
) => {
  const uniqueName = uuidv4();

  const conversation = (await client.conversations
    .services(config.TWILIO_CHAT_SERVICE_SID)
    .conversations.create({
      friendlyName: `Chat created by ${myIdentity}`,
      uniqueName,
    })) as TwilioConversationResponse;

  await client.conversations
    .services(config.TWILIO_CHAT_SERVICE_SID)
    .conversations(conversation.sid)
    .participants.create({ identity: chatTo });

  await client.conversations
    .services(config.TWILIO_CHAT_SERVICE_SID)
    .conversations(conversation.sid)
    .participants.create({ identity: myIdentity });

  return conversation;
};

export const sendMessage = async (
  conversationSid: string,
  author: string,
  body: string
) => {
  return await client.conversations
    .services(config.TWILIO_CHAT_SERVICE_SID)
    .conversations(conversationSid)
    .messages.create({ author, body });
};

完成此操作后,您还需要做另一件事。 因为您使用 REST API 将您的参与者添加到对话中,所以您不需要在前端join对话。 所以你可以删除该行

await conversation.join();

来自src/twilio/index.ts

最后一件事,如果您注销error.body而不仅仅是errorerror.message ,您可以在前端获得更好的错误消息。

      try {
        const conversation = await client.getConversationByUniqueName(room);
        if (message && String(message).trim()) {
          await conversation.sendMessage(message);
        }
      } catch (error) {
        console.log("error", error);
        console.log("error body", error.body);
        toast.error("Unable to create conversation, please reload this page");
      }

Twilio 有官方博客Build a Chat App with Twilio Programmable Chat and React.js ,请查看一次,

这是链接 - https://www.twilio.com/blog/build-a-chat-app-with-twilio-programmable-chat-and-react

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM