簡體   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