你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
本文介绍如何将现有的 Twilio 对话实现迁移到 Azure 通信服务聊天 SDK。 Twilio 对话和 Azure 通信服务聊天 SDK 都是基于云的平台,可让开发人员将聊天功能添加到其 Web 应用程序。
但它们之间存在一些主要差异,可能会影响你对平台的选择,或者如果你决定迁移,则需要对现有代码进行一些更改。 在 Twilio 中,聊天嵌入到多通道实例的对话中。 Azure 通信服务聊天 SDK 是用于聊天的单一通道。 在本文中,我们将比较这两个平台的主要特性和功能,并提供有关如何将现有 Twilio 对话聊天实现迁移到 Azure 通信服务聊天 SDK 的一些指导。
本文不介绍如何创建服务层来管理聊天应用程序的令牌。 有关聊天体系结构的详细信息,请参阅聊天概念。 有关用户访问令牌的详细信息,请参阅用户访问令牌。
重要注意事项
身份验证和安全
Azure 通信服务与标识管理的 Microsoft Entra ID 深度集成。 Twilio 使用自己的标识系统。 你可能需要修改处理用户身份验证的方式。
事件处理
与 ACS 的事件驱动模型相比,Twilio 基于 Webhook 的方法可能需要不同的体系结构。
其他服务
如果应用程序依赖于其他 Twilio 服务(如短信、语音等),则需要查找等效的 Azure 服务或维护混合式解决方案。
迁移不仅涉及替换 API 调用,还涉及重新考虑应用程序在应用程序体系结构更广泛的上下文中如何与这些通信服务交互。
Azure 通信服务聊天 SDK 中提供的主要功能
功能 | JavaScript SDK | iOS SDK | Android SDK | .NET SDK | Java SDK | Python SDK |
---|---|---|---|---|---|---|
安装 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
导入 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
身份验证 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
实时消息传送 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
更新发送的消息 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
组对话 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
直接(一对一)对话 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
更新聊天会话的主题 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
添加或删除参与者 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
聊天会话中参与者的列表 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
删除聊天会话 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
共享历史聊天记录 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
媒体支持(图像、文件等) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
消息传递回执 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
键入指示符 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
阅读回执 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
推送通知 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
多设备支持 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
消息搜索 | - | - | - | - | - | - |
消息编辑 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
消息删除 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
用户角色和权限 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
对话审查 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
参与者管理 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
与其他 Azure 服务集成 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
客户端加密 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
服务器端消息存储 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
机器人集成 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
自定义消息元数据 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
用户当前状态 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
本地化和多语言支持 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
功能组 | 功能 | Azure CLI | JavaScript | Java | .NET | Python | iOS | Android |
---|---|---|---|---|---|---|---|---|
核心功能 | 创建 2 个或更多个用户之间的聊天会话 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
更新聊天会话的主题 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
在聊天会话中添加或删除参与者 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
选择是否要与正在添加的参与者共享聊天消息历史记录 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
获取聊天会话中参与者的列表 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
删除聊天会话 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
对于给定通信用户,获取该用户所属聊天会话的列表 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
获取特定聊天会话的信息 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
在聊天会话中发送和接收消息 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
更新已发送消息的内容 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
删除以前发送的消息 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
读取聊天中已被其他参与者阅读的消息的收件人 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
当参与者在聊天会话中积极键入消息时获得通知 | ❌ | ✔️ | ❌ | ❌ | ❌ | ✔️ | ✔️ | |
获取聊天会话中的所有消息 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
将 Unicode 表情符号随附消息内容一起发送 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
向聊天消息添加元数据 | ❌ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
将显示名称添加到键入指示器通知 | ❌ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
实时通知(由专用信号包**启用) | 聊天客户端可以通过订阅获取聊天会话中的传入消息和其他操作的实时更新。 若要查看实时通知支持的更新的列表,请参阅聊天概念 | ❌ | ✔️ | ❌ | ❌ | ❌ | ✔️ | ✔️ |
使用通知中心的移动推送通知 | 聊天 SDK 提供 API,通过连接 Azure 通知中心到通信服务资源,可以通知客户端聊天会话中的传入消息和其他操作。 如果你的移动应用不是在前台运行,可以使用触发弹出式通知(“toast”)的模式来通知最终用户,请参阅聊天概念。 | ❌ | ❌ | ❌ | ❌ | ❌ | ✔️ | ✔️ |
报告 (此信息可在 Azure 门户上“通信服务”资源的“监视”选项卡下找到) |
通过监视 Azure 指标资源管理器中已发布的指标并设置警报以检测异常,了解聊天应用中的 API 流量 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
通过启用资源的诊断日志记录来监视和调试通信服务解决方案 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
先决条件
- Azure 帐户: 确保 Azure 帐户处于活动状态。 新用户可以在 Microsoft Azure 创建免费帐户。
- Node.js 18:确保系统上安装了 Node.js 18。 从 Node.js 下载。
- 通信服务资源:通过 Azure 门户设置通信服务资源并记下连接字符串。
- Azure CLI:按照说明在 Windows.上安装 Azure CLI。
- 用户访问令牌:生成用户访问令牌以实例化聊天客户端。 可以使用 Azure CLI 创建一个,如下所示:
az communication identity token issue --scope voip --connection-string "yourConnectionString"
有关详细信息,请参阅使用 Azure CLI 创建和管理访问令牌。
安装
安装 Azure 通信服务聊天 SDK
使用 npm install
命令安装适用于 JavaScript 的 Azure 通信服务 SDK。
npm install @azure/communication-chat --save
--save
选项将该库作为 package.json 文件中的依赖项列出。
从项目中删除 Twilio SDK
可以通过卸载包从项目中删除 Twilio SDK。
npm uninstall twilio-conversations
对象模型
以下类和接口用于处理适用于 JavaScript 的 Azure 通信服务聊天 SDK 的某些主要功能。
名称 | 描述 |
---|---|
ChatClient |
聊天功能需要此类。 使用订阅信息来实例化此类,并使用此类来创建、获取和删除会话及订阅聊天事件。 |
ChatThreadClient |
聊天会话功能需要此类。 通过 ChatClient 获取实例,并使用它来发送/接收/更新/删除消息、添加/删除/获取用户、发送键入通知和阅读回执。 |
初始化聊天客户端
Twilio
/* Initialization */
import { Client } from '@twilio/conversations';
const token = await fetch(token_url);
const client = new Client(token);
client.on('stateChanged', (state) => {
if (state === 'failed') {
// The client failed to initialize
return;
}
if (state === 'initialized') {
// Use the client
}
});
Azure 通信服务
与 Twilio 类似,第一步是获取在先决条件步骤中生成的访问令牌和通信服务终结点。 替换代码中的占位符。
import { ChatClient } from '@azure/communication-chat';
import { AzureCommunicationTokenCredential } from '@azure/communication-common';
// Your unique Azure Communication service endpoint
let endpointUrl = '<replace with your resource endpoint>';
// The user access token generated as part of the pre-requisites
let userAccessToken = '<USER_ACCESS_TOKEN>';
let chatClient = new ChatClient(endpointUrl, new AzureCommunicationTokenCredential(userAccessToken));
console.log('Azure Communication Chat client created!');
启动聊天会话
Twilio
在 Twilio 对话中启动聊天会话。 用于 FriendlyName
为此对话提供人类可读的名称。
let conversation = await client.createConversation({
friendlyName: "Testing Chat"
});
await conversation.join();
Azure 通信服务
使用 createThread
方法创建聊天会话。
使用 createThreadRequest
描述会话请求:
- 使用
topic
为此聊天指定主题。 使用UpdateThread
函数创建聊天会话后更新topic
。 - 使用
participants
列出要添加到聊天会话的参与者。
解析时,createChatThread
方法返回 CreateChatThreadResult
。 此模型包含 chatThread
属性,可在其中访问新创建会话的 id
。 然后使用 id
获取 ChatThreadClient
的实例。 接下来使用 ChatThreadClient
在会话中执行操作,如发送消息或列出参与者。
async function createChatThread() {
const createChatThreadRequest = {
topic: "Hello, World!"
};
const createChatThreadOptions = {
participants: [
{
id: { communicationUserId: '<USER_ID>' },
displayName: '<USER_DISPLAY_NAME>'
}
]
};
const createChatThreadResult = await chatClient.createChatThread(
createChatThreadRequest,
createChatThreadOptions
);
const threadId = createChatThreadResult.chatThread.id;
return threadId;
}
获取聊天会话客户端
Twilio
在 Twilio 中获取聊天会话(对话)。
if (selectedConversation) {
conversationContent = (
<Conversation
conversationProxy={selectedConversation}
myIdentity={this.state.name}
/>
);
} else if (status !== "success") {
conversationContent = "Loading your conversation!";
} else {
conversationContent = "";
}
Azure 通信服务
getChatThreadClient
方法返回已存在的会话的 chatThreadClient
。 使用它对创建的会话执行操作:添加参与者、发送消息等。
threadId
是现有聊天会话的唯一 ID。
let chatThreadClient = chatClient.getChatThreadClient(threadId);
console.log(`Chat Thread client for threadId:${threadId}`);
添加此代码以代替 client.js 中的 <CREATE CHAT THREAD CLIENT>
注释,刷新浏览器选项卡并检查控制台。 应会看到:
Chat Thread client for threadId: <threadId>
将用户作为参与者添加到聊天会话
创建聊天会话后,可在其中添加和删除用户。 通过添加用户,可以向他们授予访问权限,使其能够在聊天会话中发送消息,以及添加/删除其他参与者。
Twilio
将参与者添加到聊天会话。
// add chat participant to the conversation by its identity
await conversation.add('identity');
// adds yourself as a conversations sdk user to this conversation
// use after creating the conversation from the SDK
await conversation.join();
conversation.on('participantJoined', (participant) => {
// fired when a participant has joined the conversation
});
Azure 通信服务
在调用 addParticipants
方法之前,请务必获取该用户的新访问令牌和标识。 用户需要访问令牌才能初始化其聊天客户端。
addParticipantsRequest
描述请求对象,其中 participants
列出要添加到聊天会话的参与者:
-
id
(必需)是要添加到聊天会话的通信标识符。 -
displayName
(可选)是会话参与者的显示名称。 -
shareHistoryTime
(可选)是开始与参与者共享聊天历史记录的时间。 若要在聊天会话开始后共享历史记录,请将此属性设置为等于或小于会话创建时间的任何日期。 若在添加参与者之前不共享任何历史记录,请将其设置为当前日期。 若要共享部分历史记录,请将其设置为所选日期。
const addParticipantsRequest =
{
participants: [
{
id: { communicationUserId: '<NEW_PARTICIPANT_USER_ID>' },
displayName: 'Jane'
}
]
};
await chatThreadClient.addParticipants(addParticipantsRequest);
将 NEW_PARTICIPANT_USER_ID 替换为新用户 ID
向聊天会话发送消息
与 Twilio 不同,Azure 通信服务没有用于发送短信或媒体的单独功能。
Twilio
在 Twilio 中发送短信。
// Send Text Message
await conversation
.prepareMessage()
.setBody('Hello!')
.setAttributes({foo: 'bar'})
.build()
.send();
在 Twilio 中发送媒体。
const file =
await fetch("https://v.fastcdn.co/u/ed1a9b17/52533501-0-logo.svg");
const fileBlob = await file.blob();
// Send a media message
const sendMediaOptions = {
contentType: file.headers.get("Content-Type"),
filename: "twilio-logo.svg",
media: fileBlob
};
await conversation
.prepareMessage()
.setBody('Here is some media!')
.addMedia(sendMediaOptions);
Azure 通信服务
使用 sendMessage
方法将消息发送到由 threadId 标识的会话。
sendMessageRequest
用于描述消息请求:
- 使用
content
提供聊天消息内容。
使用 sendMessageOptions
描述操作可选参数:
- 使用
senderDisplayName
指定发送方的显示名称。 - 使用
type
指定消息类型,例如text
或html
。
在 Twilio 中重新创建“媒体”属性。
- 可以选择使用
metadata
来包含想随消息一起发送的任何其他数据。 此字段使开发人员能够扩展聊天消息功能并为用例添加自定义信息。 例如,在消息中共享文件链接时,你可能希望在元数据中添加hasAttachment: true
,以便接收方的应用程序可分析并相应显示。 有关详细信息,请参阅文件共享。
SendChatMessageResult
是发送消息后返回的响应。 它包含一个 ID,这是消息的唯一 ID。
const sendMessageRequest =
{
content: 'Please take a look at the attachment'
};
let sendMessageOptions =
{
senderDisplayName : 'Jack',
type: 'text',
metadata: {
'hasAttachment': 'true',
'attachmentUrl': 'https://contoso.com/files/attachment.docx'
}
};
const sendChatMessageResult = await chatThreadClient.sendMessage(sendMessageRequest, sendMessageOptions);
const messageId = sendChatMessageResult.id;
console.log(`Message sent!, message id:${messageId}`);
从聊天会话接收聊天消息
与 Twilio 不同,Azure 通信服务没有用于接收短信或媒体的单独功能。 Azure 通信服务使用 Azure 事件网格来处理事件。 有关详细信息,请参阅事件处理。
Twilio
在 Twilio 中接收短信。
// Receive text message
let paginator =
await conversation.getMessages(
30,0,"backwards"
);
const messages = paginator.items;
在 Twilio 中接收媒体。
// Receive media
// Return all media attachments (possibly empty array), without temporary urls
const media = message.attachedMedia;
// Get a temporary URL for the first media returned by the previous method
const mediaUrl = await media[0].getContentTemporaryUrl();
Azure 通信服务
使用实时信令,你可以订阅以侦听新的传入消息并相应更新内存中的当前消息。 Azure 通信服务支持你可以订阅的事件列表。
// open notifications channel
await chatClient.startRealtimeNotifications();
// subscribe to new notification
chatClient.on("chatMessageReceived", (e) => {
console.log("Notification chatMessageReceived!");
// your code here
});
或者可以通过按指定间隔轮询 listMessages
方法来检索聊天消息。
const messages = chatThreadClient.listMessages();
for await (const message of messages) {
// your code here
}
listMessages
返回可以通过 chatMessage.type
识别的不同类型的消息。
有关详细信息,请参阅消息类型。
订阅实时通知的连接状态
与 Twilio 类似,使用 Azure 通信服务可以订阅事件通知。
订阅事件 realTimeNotificationConnected
和 realTimeNotificationDisconnected
后,你可以知道与呼叫服务器的连接何时处于活动状态。
// subscribe to realTimeNotificationConnected event
chatClient.on('realTimeNotificationConnected', () => {
console.log("Real time notification is now connected!");
// your code here
});
// subscribe to realTimeNotificationDisconnected event
chatClient.on('realTimeNotificationDisconnected', () => {
console.log("Real time notification is now disconnected!");
// your code here
});
先决条件
创建具有活动订阅的 Azure 帐户。 有关详细信息,请参阅免费创建帐户。
安装 Visual Studio。
创建 Azure 通信服务资源。 有关详细信息,请参阅创建 Azure 通信服务资源。 记录资源终结点和连接字符串。
用户访问令牌。 请确保将范围设置为“聊天”,并记下令牌字符串和 user_id 字符串。 可以使用 Azure CLI,并通过连接字符串运行以下命令来创建用户和访问令牌。
az communication identity token issue --scope chat --connection-string "yourConnectionString"
有关详细信息,请参阅使用 Azure CLI 创建和管理访问令牌。
概念差异
Twilio 对话和 Azure 通信服务聊天都提供类似的功能,但由于周围的生态系统和基础平台理念,二者的实现有所不同。 Twilio 对话提供多通道通信 API。 Azure 通信服务聊天主要侧重于 Azure 生态系统中的聊天。 本迁移指南提供 Twilio 中的常见操作与 Azure 通信服务聊天中的对等操作之间的基本对应情况,可帮助你转换 .NET 代码。
标识
Twilio
Twilio 对话直接使用标识字符串。
Azure 通信服务
Azure 通信服务需要通过 CommunicationIdentityClient
创建用户。
设置
安装包
若要开始从 Twilio 对话聊天迁移,第一步是将用于 .NET 的 Azure 通信服务聊天 SDK 安装到项目中。
dotnet add package Azure.Communication.Chat
对象模型
以下类用于处理适用于 C# 的 Azure 通信服务聊天 SDK 的某些主要功能。
名称 | 说明 |
---|---|
ChatClient |
聊天功能需要此类。 使用订阅信息实例化此类,并使用它来创建、获取和删除会话。 |
ChatThreadClient |
聊天会话功能需要此类。 通过 ChatClient 获取实例,并使用它来发送/接收/更新/删除消息、添加/删除/获取参与者、发送键入通知和阅读回执。 |
创建聊天客户端
Twilio
Twilio 要求使用帐户凭据设置 Twilio 客户端:
var twilio = new TwilioRestClient(accountSid, authToken);
Azure 通信服务
若要在 Azure 通信服务中创建聊天客户端,请使用通信服务终结点以及在先决条件步骤中生成的访问令牌。 你需要使用标识 SDK 中的 CommunicationIdentityClient
类来创建用户,并颁发要传递到聊天客户端的令牌。
详细了解用户访问令牌。
// Your unique Azure Communication service endpoint
Uri endpoint = new Uri("<replace with your resource endpoint>");
CommunicationTokenCredential communicationTokenCredential = new CommunicationTokenCredential(<Access_Token>);
ChatClient chatClient = new ChatClient(endpoint, communicationTokenCredential);
启动聊天会话
Twilio 对话
var conversation = ConversationResource.Create(
friendlyName: "My Conversation",
messagingServiceSid: "<MessagingServiceSid>"
);
Azure 通信服务
在 Azure 通信服务中,创建一个与 Twilio 中的对话等效的会话。
若要创建聊天会话,请在 chatClient 上使用 createChatThread
方法:
- 使用
topic
为该聊天提供一个主题;在创建聊天会话后可使用UpdateTopic
函数更新topic
。 - 使用
participants
属性传递要添加到聊天会话的ChatParticipant
对象的列表。 使用CommunicationIdentifier
对象初始化ChatParticipant
对象。CommunicationIdentifier
可以是CommunicationUserIdentifier
、MicrosoftTeamsUserIdentifier
或PhoneNumberIdentifier
类型。 例如,若要获取CommunicationIdentifier
对象,需要按照创建用户的说明传递创建的访问 ID。
createChatThread
方法的 response 对象包含 chatThread
详细信息。 若要与聊天会话操作(例如添加参与者、发送消息、删除消息,等等)进行交互,需要在 ChatClient
客户端上使用 GetChatThreadClient
方法将 chatThreadClient
客户端实例实例化。
var chatParticipant = new ChatParticipant(identifier: new CommunicationUserIdentifier(id: "<Access_ID>"))
{
DisplayName = "UserDisplayName"
};
CreateChatThreadResult createChatThreadResult = await chatClient.CreateChatThreadAsync(topic: "Hello world!", participants: new[] { chatParticipant });
ChatThreadClient chatThreadClient = chatClient.GetChatThreadClient(threadId: createChatThreadResult.ChatThread.Id);
string threadId = chatThreadClient.Id;
获取聊天会话客户端
Twilio
在 Twilio 对话中,使用会话的 SID(唯一标识符)直接与聊天交互。 下面介绍了通常如何获取对话并与之交互:
var conversationSid = "<CONVERSATION_SID>";
var conversation = ConversationResource.Fetch(pathSid: conversationSid);
// Example: Fetching all messages in the conversation
var messages = MessageResource.Read(pathConversationSid: conversationSid);
foreach (var message in messages)
{
Console.WriteLine(message.Body);
}
Azure 通信服务
GetChatThreadClient
方法返回某个已存在的会话的会话客户端。 可以使用它对创建的会话执行操作,例如添加成员、发送消息等。
threadId
是现有聊天会话的唯一 ID。
string threadId = "<THREAD_ID>";
ChatThreadClient chatThreadClient = chatClient.GetChatThreadClient(threadId: threadId);
列出所有聊天会话
Twilio
在 Twilio 对话中,可以通过查询 UserConversations
资源来检索用户作为参与者的所有对话。 此资源为特定用户提供对话列表。
/ Initialize Twilio Client
string accountSid = "<YOUR_ACCOUNT_SID>";
string authToken = "<YOUR_AUTH_TOKEN>";
TwilioClient.Init(accountSid, authToken);
// The identity of the user you're querying
string userIdentity = "user@example.com";
// Retrieve all conversations the user is part of
var userConversations = UserConversationResource.Read(pathUserSid: userIdentity);
foreach (var userConversation in userConversations)
{
Console.WriteLine($"Conversation SID: {userConversation.ConversationSid}");
// You can fetch more details about the conversation if needed
var conversation = Twilio.Rest.Conversations.V1.ConversationResource.Fetch(pathSid: userConversation.ConversationSid);
Console.WriteLine($"Conversation Friendly Name: {conversation.FriendlyName}");
}
Azure 通信服务
使用 GetChatThreads
可检索用户所属的所有聊天线程。
AsyncPageable<ChatThreadItem> chatThreadItems = chatClient.GetChatThreadsAsync();
await foreach (ChatThreadItem chatThreadItem in chatThreadItems)
{
Console.WriteLine($"{ chatThreadItem.Id}");
}
向聊天会话发送消息
Twilio
以下代码片段演示如何发送短信。
var message = MessageResource.Create(
body: "Hello, world!",
from: "user@example.com",
pathConversationSid: conversation.Sid
);
以下代码片段演示如何发送媒体文件。
// The SID of the conversation you want to send the media message to
string conversationSid = "<CONVERSATION_SID>";
// The URL of the media file you want to send
var mediaUrl = new List<Uri>
{
new Uri("https://example.com/path/to/media/file.jpg") // Replace with your actual media URL
};
// Send the media message
var message = MessageResource.Create(
body: "Here is an image for you!",
from: "user@example.com", // Sender's identity (optional)
mediaUrl: mediaUrl,
pathConversationSid: conversationSid
);
Azure 通信服务
与 Twilio 不同,Azure 通信服务没有单独的功能来发送短信或媒体。
使用 SendMessage
向会话发送消息。
- 使用
content
提供消息的内容,这是必需的。 - 使用
type
表示消息的内容类型,例如Text
或Html
。 如果未指定,则Text
为默认类型。 - 使用
senderDisplayName
指定发送方的显示名称。 如果未指定,则空字符串为默认值。 - 可以选择使用
metadata
来包含想随消息一起发送的任何其他数据。 此字段为开发人员提供了一种机制,可用于扩展聊天消息功能并为用例添加自定义信息。 例如,在消息中共享文件链接时,你可能希望在元数据中添加hasAttachment:true
,以便接收方的应用程序可分析并相应显示。
SendChatMessageOptions sendChatMessageOptions = new SendChatMessageOptions()
{
Content = "Please take a look at the attachment",
MessageType = ChatMessageType.Text
};
sendChatMessageOptions.Metadata["hasAttachment"] = "true";
sendChatMessageOptions.Metadata["attachmentUrl"] = "https://contoso.com/files/attachment.docx";
SendChatMessageResult sendChatMessageResult = await chatThreadClient.SendMessageAsync(sendChatMessageOptions);
string messageId = sendChatMessageResult.Id;
从聊天会话接收聊天消息
Twilio
Twilio 通常使用 Webhook 来通知服务器有传入消息:
以下代码片段演示如何接收短信。
public IActionResult ReceiveMessage()
{
var incomingMessage = Request.Form["Body"];
// Process the incoming message
return Ok();
}
以下代码片段演示如何接收媒体文件。
for (var i = 0; i < numMedia; i++)
{
var mediaUrl = Request.Form[$"MediaUrl{i}"];
Trace.WriteLine(mediaUrl);
var contentType = Request.Form[$"MediaContentType{i}"];
var filePath = GetMediaFileName(mediaUrl, contentType);
await DownloadUrlToFileAsync(mediaUrl, filePath);
}
Azure 通信服务
与 Twilio 不同,Azure 通信服务没有单独的功能来接收短信或媒体。
你可以使用 Azure 通信服务聊天直接在应用程序中订阅事件。
可以通过按指定间隔在聊天会话客户端上轮询 GetMessages
方法来检索聊天消息。
AsyncPageable<ChatMessage> allMessages = chatThreadClient.GetMessagesAsync();
await foreach (ChatMessage message in allMessages)
{
Console.WriteLine($"{message.Id}:{message.Content.Message}");
}
GetMessages
采用可选的 DateTimeOffset
参数。 如果指定了该偏移量,你将收到在其之后接收、更新或删除的消息。 系统还会返回在偏移时间之前收到但在该时间之后编辑过或删除的消息。
GetMessages
返回最新版本的消息,包括使用 UpdateMessage
和 DeleteMessage
对消息执行的任何编辑或删除。 对于已删除的消息,chatMessage.DeletedOn
返回日期/时间值,该值指示该消息删除的时间。 对于已编辑的消息,chatMessage.EditedOn
返回一个日期/时间值,指示编辑该消息的时间。 可使用 chatMessage.CreatedOn
访问消息创建的原始时间,还可用它来对消息进行排序。
GetMessages
返回可以通过 chatMessage.Type
识别的不同类型的消息。 这些类型包括:
Text
:会话成员发送的普通聊天消息。Html
:格式化文本消息。 请注意,通信服务用户当前无法发送RichText
消息。 在 Teams Interop 方案中,此消息类型支持将消息从 Teams 用户传递到通信服务用户。TopicUpdated
:指示主题已更新的系统消息。 (只读)ParticipantAdded
:指示一个或多个参与者已添加到聊天会话的系统消息。 (只读)ParticipantRemoved
:指示已从聊天会话中删除参与者的系统消息。
有关详细信息,请参阅消息类型。
将用户作为参与者添加到聊天会话
Twilio
var participant = ParticipantResource.Create(
pathConversationSid: conversation.Sid,
identity: "user@example.com"
);
Azure 通信服务
在 Azure 通信服务中,在创建聊天会话时或之后添加参与者:
创建会话后,可以添加和删除用户。 通过添加用户,可以向他们授予访问权限,使其能够在会话中发送消息,以及添加/删除其他参与者。 在调用 AddParticipants
之前,请确保已获取该用户的新访问令牌和标识。 用户需要访问令牌才能初始化聊天客户端。
使用 AddParticipants
将一个或多个参与者添加到聊天会话。 下面是对每个会话参与者支持的属性:
-
communicationUser
,必需,是会话参与者的标识。 -
displayName
(可选)是会话参与者的显示名称。 -
shareHistoryTime
,可选,是开始与参与者共享聊天历史记录的时间。
var josh = new CommunicationUserIdentifier(id: "<Access_ID_For_Josh>");
var gloria = new CommunicationUserIdentifier(id: "<Access_ID_For_Gloria>");
var amy = new CommunicationUserIdentifier(id: "<Access_ID_For_Amy>");
var participants = new[]
{
new ChatParticipant(josh) { DisplayName = "Josh" },
new ChatParticipant(gloria) { DisplayName = "Gloria" },
new ChatParticipant(amy) { DisplayName = "Amy" }
};
await chatThreadClient.AddParticipantsAsync(participants: participants);
获取会话参与者
Twilio
在 Twilio 对话中,使用 ConversationResource
检索特定对话的参与者。 然后,你可以列出与该对话关联的所有参与者。
// The SID of the conversation you want to retrieve participants from
string conversationSid = "<CONVERSATION_SID>";
// Retrieve all participants in the conversation
var participants = ParticipantResource.Read(pathConversationSid: conversationSid);
// Output details of each participant
foreach (var participant in participants)
{
Console.WriteLine($"Participant SID: {participant.Sid}");
}
Azure 通信服务
使用 GetParticipants
检索聊天会话的参与者。
AsyncPageable<ChatParticipant> allParticipants = chatThreadClient.GetParticipantsAsync();
await foreach (ChatParticipant participant in allParticipants)
{
Console.WriteLine($"{((CommunicationUserIdentifier)participant.User).Id}:{participant.DisplayName}:{participant.ShareHistoryTime}");
}
发送阅读回执
Twilio
// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
string accountSid = Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID");
string authToken = Environment.GetEnvironmentVariable("TWILIO_AUTH_TOKEN");
TwilioClient.Init(accountSid, authToken);
var message = await MessageResource.FetchAsync(
pathConversationSid: "CHXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
pathSid: "IMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
Console.WriteLine(message.Delivery);
}
Azure 通信服务
使用 SendReadReceipt
通知其他参与者用户已阅读该消息。
await chatThreadClient.SendReadReceiptAsync(messageId: messageId);
先决条件
- Azure 帐户: 确保 Azure 帐户处于活动状态。 新用户可以在 Microsoft Azure 创建免费帐户。
- 通信服务资源:通过 Azure 门户设置通信服务资源并记下连接字符串。
- Azure CLI:按照说明在 Windows.上安装 Azure CLI。
- 用户访问令牌:生成用户访问令牌以实例化呼叫客户端。 可以使用 Azure CLI 创建一个,如下所示:
az communication identity token issue --scope voip --connection-string "yourConnectionString"
有关详细信息,请参阅使用 Azure CLI 创建和管理访问令牌。
安装
安装库
若要开始从 Twilio 对话聊天迁移,第一步是将用于 iOS 的 Azure 通信服务聊天 SDK 安装到项目中。 可以使用CocoaPods
配置这些参数。
- 为应用程序创建 Podfile。 打开终端,导航到项目文件夹,然后运行:
pod init
- 将以下代码添加到 Podfile 并保存(确保“目标对象”与项目名称匹配):
pod 'AzureCommunicationChat', '~> 1.3.5'
- 设置
.xcworkspace
项目:
pod install
- 使用 Xcode 打开 pod install 创建的
.xcworkspace
。
向 SDK 进行身份验证
为了能够使用 Azure 通信服务聊天 SDK,需要使用访问令牌进行身份验证。
Twilio
以下代码片段假定 Twilio 服务的有效访问令牌的可用性。
static func getTokenUrlFromDefaults(identity: String, password: String) -> URL? {
// Get token service absolute URL from settings
guard let tokenServiceUrl = UserDefaults.standard.string(forKey: "ACCESS_TOKEN_SERVICE_URL"), !tokenServiceUrl.isEmpty else {
return nil
}
return constructLoginUrl(tokenServiceUrl, identity: identity, password: password)
}
Azure 通信服务
以下代码片段需要有效的访问令牌来启动 CallClient
。
需要有效的令牌。 有关详细信息,请参阅创建和管理访问令牌。
// Create an instance of CallClient
let callClient = CallClient()
// A reference to the call agent, it will be initialized later
var callAgent: CallAgent?
// Embed the token in a CommunicationTokenCredential object
let userCredential = try? CommunicationTokenCredential(token: "<USER_TOKEN>")
// Create a CallAgent that will be used later to initiate or receive calls
callClient.createCallAgent(userCredential: userCredential) { callAgent, error in
if error != nil {
// Raise the error to the user and return
}
self.callAgent = callAgent
}
初始化聊天客户端
Twilio
以下代码片段初始化 Twilio 中的聊天客户端。
func fetchAccessTokenAndInitializeClient() {
let identity = "user_identity" // Replace with actual user identity
let urlString = "http://localhost:3000/token?identity=\(identity)"
guard let url = URL(string: urlString) else { return }
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
print("Error fetching token: \(String(describing: error))")
return
}
do {
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
let token = json["token"] as? String {
self.initializeConversationsClient(withToken: token)
}
} catch {
print("Error parsing token JSON: \(error)")
}
}
task.resume()
}
```m = TwilioVideoSDK.connect(options: connectOptions, delegate: self)
Azure 通信服务
若要创建聊天客户端,你需要使用通信服务终结点以及在先决条件步骤中生成的访问令牌。
将 <ACS_RESOURCE_ENDPOINT>
替换为 Azure 通信服务资源的终结点。 将 <ACCESS_TOKEN>
替换为有效的通信服务访问令牌。
let endpoint = "<ACS_RESOURCE_ENDPOINT>"
let credential =
try CommunicationTokenCredential(
token: "<ACCESS_TOKEN>"
)
let options = AzureCommunicationChatClientOptions()
let chatClient = try ChatClient(
endpoint: endpoint,
credential: credential,
withOptions: options
)
对象模型
以下类和接口用于处理适用于 iOS 的 Azure 通信服务聊天 SDK 的某些主要功能。
名称 | 描述 |
---|---|
ChatClient |
聊天功能需要此类。 你使用订阅信息来实例化此类,使用此类来创建、获取和删除会话,以及订阅聊天事件。 |
ChatThreadClient |
聊天会话功能需要此类。 通过 ChatClient 获取实例,并使用它来发送、接收、更新和删除消息。 此外,可用它来添加、删除和获取用户,还可发送键入通知和已读回执。 |
启动聊天会话
Twilio
以下代码片段使你能够创建新的聊天会话。
// the unique name of the conversation you create
private let uniqueConversationName = "general"
// For the quickstart, this will be the view controller
weak var delegate: QuickstartConversationsManagerDelegate?
// MARK: Conversations variables
private var client: TwilioConversationsClient?
private var conversation: TCHConversation?
private(set) var messages: [TCHMessage] = []
private var identity: String?
func conversationsClient(_ client: TwilioConversationsClient, synchronizationStatusUpdated status: TCHClientSynchronizationStatus) {
guard status == .completed else {
return
}
checkConversationCreation { (_, conversation) in
if let conversation = conversation {
self.joinConversation(conversation)
} else {
self.createConversation { (success, conversation) in
if success, let conversation = conversation {
self.joinConversation(conversation)
}
}
}
}
Azure 通信服务
从创建聊天会话返回的响应是 CreateChatThreadResult
。
它包含 chatThread
属性(ChatThreadProperties
对象)。 此对象包含的 threadId
可用于获取 ChatThreadClient
,后者用于对创建的会话执行各种操作:添加参与者、发送消息等。
将注释 <CREATE A CHAT THREAD>
替换为以下代码片段:
let request = CreateChatThreadRequest(
topic: "Quickstart",
participants: [
ChatParticipant(
id: CommunicationUserIdentifier("<USER_ID>"),
displayName: "Jack"
)
]
)
var threadId: String?
chatClient.create(thread: request) { result, _ in
switch result {
case let .success(result):
threadId = result.chatThread?.id
case .failure:
fatalError("Failed to create thread.")
}
semaphore.signal()
}
semaphore.wait()
将 <USER_ID>
替换为有效的通信服务用户 ID。
在此处使用信号灯等待完成事件处理器,然后再继续。 在后续步骤中,将使用返回到完成事件处理器的响应中的 threadId
。
获取聊天会话客户端
Twilio
以下代码片段演示如何在 Twilio 中获取聊天会话客户端。
func conversationsClient(_ client: TwilioConversationsClient, synchronizationStatusUpdated status: TCHClientSynchronizationStatus) {
guard status == .completed else {
return
}
checkConversationCreation { (_, conversation) in
if let conversation = conversation {
self.joinConversation(conversation)
} else {
self.createConversation { (success, conversation) in
if success, let conversation = conversation {
self.joinConversation(conversation)
}
}
}
}
}
Azure 通信服务
createClient
方法返回已存在的会话的 ChatThreadClient
。 你可以使用它对创建的会话执行操作:添加参与者、发送消息等。
threadId
是现有聊天会话的唯一 ID。
使用下面的代码替换 <GET A CHAT THREAD CLIENT>
注释:
let chatThreadClient = try chatClient.createClient(forThread: threadId!)
向聊天会话发送消息
与 Twilio 不同,Azure 通信服务没有单独的功能来发送短信或媒体。
Twilio
在 Twilio 中发送常规短信。
func sendMessage(_ messageText: String,
completion: @escaping (TCHResult, TCHMessage?) -> Void) {
let messageOptions = TCHMessageOptions().withBody(messageText)
conversation?.sendMessage(with: messageOptions, completion: { (result, message) in
completion(result, message)
})
}
在 Twilio 中发送媒体:
/ The data for the image you would like to send
let data = Data()
// Prepare the message and send it
self.conversation.prepareMessage
.addMedia(data: data, contentType: "image/jpeg", filename: "image.jpg", listener: .init(onStarted: {
// Called when upload of media begins.
print("Media upload started")
}, onProgress: { bytes in
// Called as upload progresses, with the current byte count.
print("Media upload progress: \(bytes)")
}, onCompleted: { sid in
// Called when upload is completed, with the new mediaSid if successful.
// Full failure details will be provided through sendMessage's completion.
print("Media upload completed")
}, onFailed: { error in
// Called when upload is completed, with the new mediaSid if successful.
// Full failure details will be provided through sendMessage's completion.
print("Media upload failed with error: \(error)")
}))
.buildAndSend { result, message in
if !result.isSuccessful {
print("Creation failed: \(String(describing: result.error))")
} else {
print("Creation successful")
}
}
Azure 通信服务
使用 send
方法将消息发送到由 threadId
标识的会话。
使用 SendChatMessageRequest
描述消息请求:
- 使用
content
提供聊天消息内容。 - 使用
senderDisplayName
指定发送方的显示名称。 - 使用
type
指定消息类型,例如text
或html
。 - 可以选择使用
metadata
来包含想随消息一起发送的任何信息。 此字段为开发人员提供了一种机制,可用于扩展聊天消息功能并为用例添加自定义信息。 例如,在消息中共享文件链接时,你可能希望在元数据中添加hasAttachment:true
,以便接收方的应用程序可分析并相应显示。
发送消息后返回的响应是 SendChatMessageResult
。 它包含一个 ID,这是消息的唯一 ID。
将注释 <SEND A MESSAGE>
替换为以下代码片段:
let message = SendChatMessageRequest(
content: "Hello!",
senderDisplayName: "Jack",
type: .text,
metadata: [
"hasAttachment": "true",
"attachmentUrl": "https://contoso.com/files/attachment.docx"
]
)
var messageId: String?
chatThreadClient.send(message: message) { result, _ in
switch result {
case let .success(result):
print("Message sent, message id: \(result.id)")
messageId = result.id
case .failure:
print("Failed to send message")
}
semaphore.signal()
}
semaphore.wait()
从聊天会话接收聊天消息
与 Twilio 不同,Azure 通信服务没有单独的功能来接收短信或媒体。
Twilio
以下代码片段演示如何在 Twilio 中接收短信。
// Called whenever a conversation we've joined receives a new message
func conversationsClient(_ client: TwilioConversationsClient, conversation: TCHConversation,
messageAdded message: TCHMessage) {
messages.append(message)
// Changes to the delegate should occur on the UI thread
DispatchQueue.main.async {
if let delegate = self.delegate {
delegate.reloadMessages()
delegate.receivedNewMessage()
}
}
}
在 Twilio 中接收媒体:
conversationsClient.getTemporaryContentUrlsForMedia(message.attachedMedia) { result, mediaSidToUrlMap in
guard result.isSuccessful else {
print("Couldn't get temporary urls with error: \(String(describing: result.error))")
return
}
for (sid, url) in sidToUrlMap {
print("\(sid) -> \(url)")
}
}
Azure 通信服务
使用实时信令,你可以订阅以侦听新的传入消息并相应更新内存中的当前消息。 Azure 通信服务支持你可以订阅的事件列表。
使用以下代码替换 <RECEIVE MESSAGES>
注释。 启用通知后,请尝试发送新消息以查看 ChatMessageReceivedEvents
。
chatClient.startRealTimeNotifications { result in
switch result {
case .success:
print("Real-time notifications started.")
case .failure:
print("Failed to start real-time notifications.")
}
semaphore.signal()
}
semaphore.wait()
chatClient.register(event: .chatMessageReceived, handler: { response in
switch response {
case let .chatMessageReceivedEvent(event):
print("Received a message: \(event.message)")
default:
return
}
})
或者可以通过按指定间隔轮询 listMessages
方法来检索聊天消息。 请查看以下适用于 listMessages
的代码片段。
chatThreadClient.listMessages { result, _ in
switch result {
case let .success(messagesResult):
guard let messages = messagesResult.pageItems else {
print("No messages returned.")
return
}
for message in messages {
print("Received message with id: \(message.id)")
}
case .failure:
print("Failed to receive messages")
}
semaphore.signal()
}
semaphore.wait()
推送通知
与 Twilio 类似,Azure 通信服务支持推送通知。 推送通知可在移动应用未在前台运行时通知客户端,向其显示聊天会话中的传入消息。
目前 iOS SDK 1.3.0 版本支持使用通知中心发送聊天推送通知。
有关详细信息,请参阅在聊天应用中启用推送通知。
先决条件
创建具有活动订阅的 Azure 帐户。 有关详细信息,请参阅创建免费账户。
安装 Visual Studio。
创建 Azure 通信服务资源。 有关详细信息,请参阅创建 Azure 通信服务资源。 记录资源终结点和连接字符串。
用户访问令牌。 请确保将范围设置为“聊天”,并记下令牌字符串和 user_id 字符串。 可以使用 Azure CLI,并通过连接字符串运行以下命令来创建用户和访问令牌。
az communication identity token issue --scope chat --connection-string "yourConnectionString"
有关详细信息,请参阅使用 Azure CLI 创建和管理访问令牌。
概念差异
Twilio 对话和 Azure 通信服务聊天都提供类似的功能,但由于周围的生态系统和基础平台理念,二者的实现有所不同。 Twilio 对话提供多通道通信 API。 Azure 通信服务聊天主要侧重于 Azure 生态系统中的聊天。 本迁移指南提供 Twilio 中的常见操作与 Azure 通信服务聊天中的对等操作之间的基本对应情况,可帮助你转换 .NET 代码。
标识
Twilio
Twilio 对话直接使用标识字符串。
Azure 通信服务
Azure 通信服务需要通过 CommunicationIdentityClient
创建用户。
设置
安装包
若要开始从 Twilio 对话聊天迁移,第一步是将用于 .NET 的 Azure 通信服务聊天 SDK 安装到项目中。
dotnet add package Azure.Communication.Chat
对象模型
以下类用于处理适用于 C# 的 Azure 通信服务聊天 SDK 的某些主要功能。
名称 | 说明 |
---|---|
ChatClient |
聊天功能需要此类。 使用订阅信息实例化此类,并使用它来创建、获取和删除会话。 |
ChatThreadClient |
聊天会话功能需要此类。 通过 ChatClient 获取实例,并使用它来发送/接收/更新/删除消息、添加/删除/获取参与者、发送键入通知和阅读回执。 |
创建聊天客户端
Twilio
Twilio 要求使用帐户凭据设置 Twilio 客户端:
var twilio = new TwilioRestClient(accountSid, authToken);
Azure 通信服务
若要在 Azure 通信服务中创建聊天客户端,请使用通信服务终结点以及在先决条件步骤中生成的访问令牌。 你需要使用标识 SDK 中的 CommunicationIdentityClient
类来创建用户,并颁发要传递到聊天客户端的令牌。
详细了解用户访问令牌。
// Your unique Azure Communication service endpoint
Uri endpoint = new Uri("<replace with your resource endpoint>");
CommunicationTokenCredential communicationTokenCredential = new CommunicationTokenCredential(<Access_Token>);
ChatClient chatClient = new ChatClient(endpoint, communicationTokenCredential);
启动聊天会话
Twilio 对话
var conversation = ConversationResource.Create(
friendlyName: "My Conversation",
messagingServiceSid: "<MessagingServiceSid>"
);
Azure 通信服务
在 Azure 通信服务中,创建一个与 Twilio 中的对话等效的会话。
若要使用 chatClient
上的 createChatThread
方法创建聊天会话,请执行以下操作:
- 使用
topic
为该聊天提供一个主题;在创建聊天会话后可使用UpdateTopic
函数更新topic
。 - 使用
participants
属性传递要添加到聊天会话的ChatParticipant
对象的列表。 使用CommunicationIdentifier
对象初始化ChatParticipant
对象。CommunicationIdentifier
可以是CommunicationUserIdentifier
、MicrosoftTeamsUserIdentifier
或PhoneNumberIdentifier
类型。 例如,若要获取CommunicationIdentifier
对象,需要按照创建用户的说明传递创建的访问 ID。
createChatThread
方法的 response 对象包含 chatThread
详细信息。 若要与聊天会话操作(例如添加参与者、发送消息、删除消息,等等)进行交互,需要在 ChatClient
客户端上使用 GetChatThreadClient
方法将 chatThreadClient
客户端实例实例化。
var chatParticipant = new ChatParticipant(identifier: new CommunicationUserIdentifier(id: "<Access_ID>"))
{
DisplayName = "UserDisplayName"
};
CreateChatThreadResult createChatThreadResult = await chatClient.CreateChatThreadAsync(topic: "Hello world!", participants: new[] { chatParticipant });
ChatThreadClient chatThreadClient = chatClient.GetChatThreadClient(threadId: createChatThreadResult.ChatThread.Id);
string threadId = chatThreadClient.Id;
获取聊天会话客户端
Twilio
在 Twilio 对话中,使用会话的 SID(唯一标识符)直接与聊天交互。 下面介绍了通常如何获取对话并与之交互:
var conversationSid = "<CONVERSATION_SID>";
var conversation = ConversationResource.Fetch(pathSid: conversationSid);
// Example: Fetching all messages in the conversation
var messages = MessageResource.Read(pathConversationSid: conversationSid);
foreach (var message in messages)
{
Console.WriteLine(message.Body);
}
Azure 通信服务
GetChatThreadClient
方法返回某个已存在的会话的会话客户端。 可以使用它对创建的会话执行操作,例如添加成员、发送消息等。
threadId
是现有聊天会话的唯一 ID。
string threadId = "<THREAD_ID>";
ChatThreadClient chatThreadClient = chatClient.GetChatThreadClient(threadId: threadId);
列出所有聊天会话
Twilio
在 Twilio 对话中,可以通过查询 UserConversations
资源来检索用户作为参与者的所有对话。 此资源为特定用户提供对话列表。
/ Initialize Twilio Client
string accountSid = "<YOUR_ACCOUNT_SID>";
string authToken = "<YOUR_AUTH_TOKEN>";
TwilioClient.Init(accountSid, authToken);
// The identity of the user you're querying
string userIdentity = "user@example.com";
// Retrieve all conversations the user is part of
var userConversations = UserConversationResource.Read(pathUserSid: userIdentity);
foreach (var userConversation in userConversations)
{
Console.WriteLine($"Conversation SID: {userConversation.ConversationSid}");
// You can fetch more details about the conversation if needed
var conversation = Twilio.Rest.Conversations.V1.ConversationResource.Fetch(pathSid: userConversation.ConversationSid);
Console.WriteLine($"Conversation Friendly Name: {conversation.FriendlyName}");
}
Azure 通信服务
使用 GetChatThreads
可检索用户所属的所有聊天线程。
AsyncPageable<ChatThreadItem> chatThreadItems = chatClient.GetChatThreadsAsync();
await foreach (ChatThreadItem chatThreadItem in chatThreadItems)
{
Console.WriteLine($"{ chatThreadItem.Id}");
}
向聊天会话发送消息
Twilio
以下代码片段演示如何发送短信。
var message = MessageResource.Create(
body: "Hello, world!",
from: "user@example.com",
pathConversationSid: conversation.Sid
);
以下代码片段演示如何发送媒体文件。
// The SID of the conversation you want to send the media message to
string conversationSid = "<CONVERSATION_SID>";
// The URL of the media file you want to send
var mediaUrl = new List<Uri>
{
new Uri("https://example.com/path/to/media/file.jpg") // Replace with your actual media URL
};
// Send the media message
var message = MessageResource.Create(
body: "Here is an image for you!",
from: "user@example.com", // Sender's identity (optional)
mediaUrl: mediaUrl,
pathConversationSid: conversationSid
);
Azure 通信服务
与 Twilio 不同,Azure 通信服务没有单独的功能来发送短信或媒体。
使用 SendMessage
向会话发送消息。
- 使用
content
提供消息的内容,这是必需的。 - 使用
type
表示消息的内容类型,例如Text
或Html
。 如果未指定,则Text
为默认类型。 - 使用
senderDisplayName
指定发送方的显示名称。 如果未指定,则空字符串为默认值。 - 可以选择使用
metadata
来包含想随消息一起发送的任何其他数据。 此字段为开发人员提供了一种机制,可用于扩展聊天消息功能并为用例添加自定义信息。 例如,在消息中共享文件链接时,你可能希望在元数据中添加hasAttachment:true
,以便接收方的应用程序可分析并相应显示。
SendChatMessageOptions sendChatMessageOptions = new SendChatMessageOptions()
{
Content = "Please take a look at the attachment",
MessageType = ChatMessageType.Text
};
sendChatMessageOptions.Metadata["hasAttachment"] = "true";
sendChatMessageOptions.Metadata["attachmentUrl"] = "https://contoso.com/files/attachment.docx";
SendChatMessageResult sendChatMessageResult = await chatThreadClient.SendMessageAsync(sendChatMessageOptions);
string messageId = sendChatMessageResult.Id;
从聊天会话接收聊天消息
Twilio
Twilio 通常使用 Webhook 来通知服务器有传入消息:
以下代码片段演示如何接收短信。
public IActionResult ReceiveMessage()
{
var incomingMessage = Request.Form["Body"];
// Process the incoming message
return Ok();
}
以下代码片段演示如何接收媒体文件。
for (var i = 0; i < numMedia; i++)
{
var mediaUrl = Request.Form[$"MediaUrl{i}"];
Trace.WriteLine(mediaUrl);
var contentType = Request.Form[$"MediaContentType{i}"];
var filePath = GetMediaFileName(mediaUrl, contentType);
await DownloadUrlToFileAsync(mediaUrl, filePath);
}
Azure 通信服务
与 Twilio 不同,Azure 通信服务没有单独的功能来接收短信或媒体。
你可以使用 Azure 通信服务聊天直接在应用程序中订阅事件。
可以通过按指定间隔在聊天会话客户端上轮询 GetMessages
方法来检索聊天消息。
AsyncPageable<ChatMessage> allMessages = chatThreadClient.GetMessagesAsync();
await foreach (ChatMessage message in allMessages)
{
Console.WriteLine($"{message.Id}:{message.Content.Message}");
}
GetMessages
采用可选的 DateTimeOffset
参数。 如果指定了该偏移量,你将收到在其之后接收、更新或删除的消息。 系统还会返回在偏移时间之前收到但在该时间之后编辑过或删除的消息。
GetMessages
返回最新版本的消息,包括使用 UpdateMessage
和 DeleteMessage
对消息执行的任何编辑或删除。 对于已删除的消息,chatMessage.DeletedOn
返回日期/时间值,该值指示该消息删除的时间。 对于已编辑的消息,chatMessage.EditedOn
返回一个日期/时间值,指示编辑该消息的时间。 可使用 chatMessage.CreatedOn
访问消息创建的原始时间,还可用它来对消息进行排序。
GetMessages
返回可使用 chatMessage.Type
标识的不同类型的消息。 这些类型包括:
Text
:会话成员发送的普通聊天消息。Html
:格式化文本消息。 通信服务用户当前无法发送RichText
消息。 在 Teams Interop 方案中,此消息类型支持将消息从 Teams 用户传递到通信服务用户。TopicUpdated
:指示主题已更新的系统消息。 (只读)ParticipantAdded
:指示一个或多个参与者已添加到聊天会话的系统消息。 (只读)ParticipantRemoved
:指示已从聊天会话中删除参与者的系统消息。
有关详细信息,请参阅消息类型。
将用户作为参与者添加到聊天会话
Twilio
var participant = ParticipantResource.Create(
pathConversationSid: conversation.Sid,
identity: "user@example.com"
);
Azure 通信服务
在 Azure 通信服务中,在创建聊天会话时或之后添加参与者:
创建会话后,可以添加和删除用户。 通过添加用户,可以向他们授予访问权限,使其能够在会话中发送消息,以及添加/删除其他参与者。 在调用 AddParticipants
之前,请确保已获取该用户的新访问令牌和标识。 用户需要访问令牌才能初始化聊天客户端。
使用 AddParticipants
将一个或多个参与者添加到聊天会话。 下面是对每个会话参与者支持的属性:
-
communicationUser
,必需,是会话参与者的标识。 -
displayName
(可选)是会话参与者的显示名称。 -
shareHistoryTime
,可选,是开始与参与者共享聊天历史记录的时间。
var josh = new CommunicationUserIdentifier(id: "<Access_ID_For_Josh>");
var gloria = new CommunicationUserIdentifier(id: "<Access_ID_For_Gloria>");
var amy = new CommunicationUserIdentifier(id: "<Access_ID_For_Amy>");
var participants = new[]
{
new ChatParticipant(josh) { DisplayName = "Josh" },
new ChatParticipant(gloria) { DisplayName = "Gloria" },
new ChatParticipant(amy) { DisplayName = "Amy" }
};
await chatThreadClient.AddParticipantsAsync(participants: participants);
获取会话参与者
Twilio
在 Twilio 对话中,使用 ConversationResource
检索特定对话的参与者。 然后,你可以列出与该对话关联的所有参与者。
// The SID of the conversation you want to retrieve participants from
string conversationSid = "<CONVERSATION_SID>";
// Retrieve all participants in the conversation
var participants = ParticipantResource.Read(pathConversationSid: conversationSid);
// Output details of each participant
foreach (var participant in participants)
{
Console.WriteLine($"Participant SID: {participant.Sid}");
}
Azure 通信服务
使用 GetParticipants
检索聊天会话的参与者。
AsyncPageable<ChatParticipant> allParticipants = chatThreadClient.GetParticipantsAsync();
await foreach (ChatParticipant participant in allParticipants)
{
Console.WriteLine($"{((CommunicationUserIdentifier)participant.User).Id}:{participant.DisplayName}:{participant.ShareHistoryTime}");
}
发送阅读回执
Twilio
// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
string accountSid = Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID");
string authToken = Environment.GetEnvironmentVariable("TWILIO_AUTH_TOKEN");
TwilioClient.Init(accountSid, authToken);
var message = await MessageResource.FetchAsync(
pathConversationSid: "CHXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
pathSid: "IMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
Console.WriteLine(message.Delivery);
}
Azure 通信服务
使用 SendReadReceipt
通知其他参与者用户已阅读该消息。
await chatThreadClient.SendReadReceiptAsync(messageId: messageId);
先决条件
具有活动订阅的 Azure 帐户。 免费创建帐户。
Java 开发工具包 (JDK) 8 或更高版本。
创建 Azure 通信服务资源。 有关详细信息,请参阅创建 Azure 通信服务资源。 需要记录资源终结点和连接字符串。
用户访问令牌。 请确保将范围设置为“聊天”,并记下令牌字符串和 user_id 字符串。 可以使用 Azure CLI,并通过连接字符串运行以下命令来创建用户和访问令牌。
az communication identity token issue --scope chat --connection-string "yourConnectionString"
有关详细信息,请参阅使用 Azure CLI 创建和管理访问令牌。
设置
添加聊天 SDK 的包引用
Twilio
若要在 Java 应用程序中使用 Twilio 对话聊天 API,请在 pom.xml 中添加以下依赖项:
<dependencies>
<!-- Twilio Java SDK -->
<dependency>
<groupId>com.twilio.sdk</groupId>
<artifactId>twilio</artifactId>
<version>8.31.1</version>
</dependency>
</dependencies>
Azure 通信服务
在 POM 文件中,使用聊天 API 引用 azure-communication-chat
包:
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-communication-chat</artifactId>
<version><!-- Please refer to https://search.maven.org/artifact/com.azure/azure-communication-chat for the latest version --></version>
</dependency>
若要进行身份验证,客户端需引用 azure-communication-common
包:
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-communication-common</artifactId>
<version><!-- Please refer to https://search.maven.org/artifact/com.azure/azure-communication-common for the latest version --></version>
</dependency>
对象模型
以下类和接口用于处理适用于 Java 的 Azure 通信服务聊天 SDK 的某些主要功能。
名称 | 描述 |
---|---|
ChatClient |
聊天功能需要此类。 使用订阅信息实例化此类,并使用它来创建、获取和删除会话。 |
ChatAsyncClient |
异步聊天功能需要此类。 使用订阅信息实例化此类,并使用它来创建、获取和删除会话。 |
ChatThreadClient |
聊天会话功能需要此类。 通过 ChatClient 获取实例,并使用它来发送/接收/更新/删除消息、添加/删除/获取用户、发送键入通知和阅读回执。 |
ChatThreadAsyncClient |
异步聊天会话功能需要此类。 通过 ChatAsyncClient 获取实例,并使用它来发送/接收/更新/删除消息、添加/删除/获取用户、发送键入通知和阅读回执。 |
导入
Twilio
import com.twilio.Twilio;
import com.twilio.rest.conversations.v1.Conversation;
Azure 通信服务
package com.communication.quickstart;
import com.azure.communication.chat.*;
import com.azure.communication.chat.models.*;
import com.azure.communication.common.*;
import com.azure.core.http.rest.PagedIterable;
import java.io.*;
import java.util.*;
创建聊天客户端
Twilio
在 Twilio 中,使用帐户 SID 和身份验证令牌初始化客户端。 下面展示通常如何初始化客户端。
String accountSid = "<YOUR_ACCOUNT_SID>";
String authToken = "<YOUR_AUTH_TOKEN>";
// Initialize Twilio client
Twilio.init(accountSid, authToken);
Azure 通信服务
若要创建聊天客户端,需使用通信服务终结点以及在前提步骤中生成的访问令牌。 使用用户访问令牌可以生成直接对 Azure 通信服务进行身份验证的客户端应用程序。 在服务器上生成这些令牌后,将它们传回客户端设备。 需要使用通用 SDK 中的 CommunicationTokenCredential
类将令牌传递给聊天客户端。
详细了解聊天体系结构
添加 import 语句时,请务必仅添加来自 com.azure.communication.chat
和 com.azure.communication.chat.models
命名空间的导入,而不是来自 com.azure.communication.chat.implementation
命名空间的导入。 在通过 Maven 生成的 App.java
文件中,你可以使用以下代码开始操作:
// Your unique Azure Communication service endpoint
String endpoint = "<replace with your resource endpoint>";
// User access token fetched from your trusted service
String userAccessToken = "<USER_ACCESS_TOKEN>";
// Create a CommunicationTokenCredential with the given access token, which is only valid until the token is valid
CommunicationTokenCredential userCredential = new CommunicationTokenCredential(userAccessToken);
// Initialize the chat client
final ChatClientBuilder builder = new ChatClientBuilder();
builder.endpoint(endpoint)
.credential(userCredential);
ChatClient chatClient = builder.buildClient();
启动聊天会话
Twilio
使用 Conversation.creator()
方法在 Twilio 中创建对话非常简单。
使用 setFriendlyName
为此聊天指定主题。
// Create a new conversation
Conversation conversation = Conversation.creator().setFriendlyName("New Conversation").create();
System.out.println(conversation.getSid());
Azure 通信服务
使用 createChatThread
方法创建聊天会话。
- 使用
createChatThreadOptions
描述会话请求。 - 使用构造函数的
topic
参数提供此聊天主题;在使用UpdateThread
函数创建聊天会话后更新“主题”。 - 使用
participants
列出要添加到会话的会话参与者。ChatParticipant
使用你在用户访问令牌快速入门中创建的用户。
CreateChatThreadResult
是从创建聊天线程返回的响应。
它包含一个返回 ChatThread
对象的 getChatThread()
方法,该对象可用于获取会话客户端。你可以从该客户端获取 ChatThreadClient
,以便执行相关操作:添加参与者、发送消息等。
ChatThread
对象还包含 getId()
方法,该方法能检索会话的唯一 ID。
CommunicationUserIdentifier identity1 = new CommunicationUserIdentifier("<USER_1_ID>");
CommunicationUserIdentifier identity2 = new CommunicationUserIdentifier("<USER_2_ID>");
ChatParticipant firstThreadParticipant = new ChatParticipant()
.setCommunicationIdentifier(identity1)
.setDisplayName("Participant Display Name 1");
ChatParticipant secondThreadParticipant = new ChatParticipant()
.setCommunicationIdentifier(identity2)
.setDisplayName("Participant Display Name 2");
CreateChatThreadOptions createChatThreadOptions = new CreateChatThreadOptions("Topic")
.addParticipant(firstThreadParticipant)
.addParticipant(secondThreadParticipant);
CreateChatThreadResult result = chatClient.createChatThread(createChatThreadOptions);
String chatThreadId = result.getChatThread().getId();
列出聊天会话
Twilio
使用 Java 列出 Twilio 中的所有对话:
public static void main(String[] args) {
// List all conversations
ResourceSet<Conversation> conversations = Conversation.reader().read();
for (Conversation conversation : conversations) {
System.out.println("Conversation SID: " + conversation.getSid());
System.out.println("Friendly Name: " + conversation.getFriendlyName());
System.out.println("Date Created: " + conversation.getDateCreated());
}
}
Azure 通信服务
使用 listChatThreads
方法检索现有聊天会话的列表。
PagedIterable<ChatThreadItem> chatThreads = chatClient.listChatThreads();
chatThreads.forEach(chatThread -> {
System.out.printf("ChatThread id is %s.\n", chatThread.getId());
});
获取聊天会话客户端
Twilio
下面介绍如何使用 Java 在 Twilio 中检索特定对话并与之交互:
// Retrieve a specific conversation by its SID
Conversation conversation = Conversation.fetcher(conversationSid).fetch();
System.out.println("Retrieved Conversation SID: " + conversation.getSid());
System.out.println("Friendly Name: " + conversation.getFriendlyName())
Azure 通信服务
getChatThreadClient
方法返回某个已存在的会话的会话客户端。 使用它对创建的会话执行操作:添加参与者、发送消息等。
chatThreadId
是现有聊天会话的唯一 ID。
ChatThreadClient chatThreadClient = chatClient.getChatThreadClient(chatThreadId);
向聊天会话发送消息
Twilio
在 Twilio 中发送消息将使用 Message.creator()
方法。
import com.twilio.rest.conversations.v1.conversation.Message;
Message message = Message.creator(conversationSid)
.setBody("Hello, World!")
.create();
System.out.println("Message SID: " + message.getSid());
你可以通过 Twilio 在发送消息时提供媒体 URL 来发送媒体文件。
List<URI> mediaUrls = Arrays.asList(URI.create("https://example.com/image.jpg"));
Message message = Message.creator(conversationSid)
.setBody("Check out this image!")
.setMediaUrl(mediaUrls)
.create();
System.out.println("Message SID: " + message.getSid());
Azure 通信服务
与 Twilio 不同,Azure 通信服务没有单独的功能来发送媒体。
使用 sendMessage
方法将消息发送到你创建的且由 chatThreadId
标识的会话。
使用 sendChatMessageOptions
描述聊天消息请求。
- 使用
content
提供聊天消息内容。 - 使用
type
指定聊天消息内容类型(TEXT
或HTML
)。 - 使用
senderDisplayName
指定发送方的显示名称。 - 可以选择使用
metadata
来包含想随消息一起发送的任何数据。 此字段使开发人员能够扩展聊天消息功能并为用例添加自定义信息。 例如,在消息中共享文件链接时,你可能希望在元数据中添加hasAttachment:true
,以便接收方的应用程序可分析并相应显示。
响应 sendChatMessageResult
包含 id
(消息的唯一 ID)。
Map<String, String> metadata = new HashMap<String, String>();
metadata.put("hasAttachment", "true");
metadata.put("attachmentUrl", "https://contoso.com/files/attachment.docx");
SendChatMessageOptions sendChatMessageOptions = new SendChatMessageOptions()
.setContent("Please take a look at the attachment")
.setType(ChatMessageType.TEXT)
.setSenderDisplayName("Sender Display Name")
.setMetadata(metadata);
SendChatMessageResult sendChatMessageResult = chatThreadClient.sendMessage(sendChatMessageOptions);
String chatMessageId = sendChatMessageResult.getId();
从聊天会话接收聊天消息
Twilio
Twilio 对话使用 Webhook 来接收消息。 通常在 Twilio 控制台中设置 Webhook URL。
// This would be handled by a servlet or similar in a Java web application
public void handleIncomingMessage(HttpServletRequest request, HttpServletResponse response) {
String body = request.getParameter("Body");
System.out.println("Received message: " + body);
}
在 Twilio 中接收媒体文件。
private static final Logger logger = Logger.getLogger(TwilioWebhookServlet.class.getName());
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Get the number of media items attached to the message
String numMedia = request.getParameter("NumMedia");
int mediaCount = Integer.parseInt(numMedia);
if (mediaCount > 0) {
// Loop through each media file received
for (int i = 0; i < mediaCount; i++) {
// Get the media URL from the request
String mediaUrl = request.getParameter("MediaUrl" + i);
String mediaContentType = request.getParameter("MediaContentType" + i);
logger.info("Received media file: " + mediaUrl + " with content type: " + mediaContentType);
// Process the media file (e.g., download, store, etc.)
// Example: Download and save the file, or send it to another service
}
} else {
// Handle a message with no media
String messageBody = request.getParameter("Body");
logger.info("Received text message: " + messageBody);
}
Azure 通信服务
可以通过按指定间隔在聊天会话客户端上轮询 listMessages
方法来检索聊天消息。
chatThreadClient.listMessages().forEach(message -> {
System.out.printf("Message id is %s.\n", message.getId());
});
listMessages
返回最新版本的消息,包括使用 .editMessage()
和 .deleteMessage()
对消息执行的任何编辑或删除。 对于已删除的消息,chatMessage.getDeletedOn()
返回一个 datetime
值,它指示删除该消息的时间。 对于已编辑的消息,chatMessage.getEditedOn()
返回一个日期/时间值,指示编辑该消息的时间。 可以使用 chatMessage.getCreatedOn()
访问消息创建的原始时间,还可使用它对消息进行排序。
单击此处了解有关消息类型的详细信息:消息类型。
发送阅读回执
Twilio
Twilio 对话没有直接用于发送已读回执的 API。 Twilio 对话自动管理已读回执。
Azure 通信服务
sendReadReceipt
方法可用于代表用户将阅读回执事件发布到会话。
chatMessageId
是已读聊天消息的唯一 ID。
String chatMessageId = message.getId();
chatThreadClient.sendReadReceipt(chatMessageId);
列出聊天参与者
Twilio
要检索 Twilio 对话中的参与者,请执行以下操作:
ResourceSet<Participant> participants = Participant.reader(conversationSid).read();
for (Participant participant : participants) {
System.out.println("Participant SID: " + participant.getSid());
}
Azure 通信服务
使用 listParticipants
检索包含由 chatThreadId 标识的聊天线程参与者的分页集合。
PagedIterable<ChatParticipant> chatParticipantsResponse = chatThreadClient.listParticipants();
chatParticipantsResponse.forEach(chatParticipant -> {
System.out.printf("Participant id is %s.\n", ((CommunicationUserIdentifier) chatParticipant.getCommunicationIdentifier()).getId());
});
将用户作为参与者添加到聊天会话
Twilio
使用 Participant.creator() 方法将参与者添加到对话。
import com.twilio.rest.conversations.v1.conversation.Participant;
Participant participant = Participant.creator(conversationSid)
.setIdentity("user@example.com")
.create();
System.out.println("Participant SID: " + participant.getSid());
Azure 通信服务
创建聊天会话后,可以在其中添加和删除用户。 通过添加用户,可以向他们授予访问权限,使其能够在聊天会话中发送消息,以及添加/删除其他参与者。 首先获取该用户的新访问令牌和标识。 在调用 addParticipants
方法之前,请确保已获取该用户的新访问令牌和标识。 用户需要访问令牌才能初始化其聊天客户端。
使用 addParticipants
方法将参与者添加到该会话中。
-
communicationIdentifier
(必需)是在用户访问令牌快速入门中使用CommunicationIdentityClient
创建的CommunicationIdentifier
。 -
displayName
(可选)是会话参与者的显示名称。 -
shareHistoryTime
(可选)是开始与参与者共享聊天历史记录的时间。 若要在聊天会话开始后共享历史记录,请将此属性设置为等于或小于会话创建时间的任何日期。 若在添加参与者之前不共享任何历史记录,请将其设置为当前日期。 若要共享部分历史记录,请将其设置为所需日期。
List<ChatParticipant> participants = new ArrayList<ChatParticipant>();
CommunicationUserIdentifier identity3 = new CommunicationUserIdentifier("<USER_3_ID>");
CommunicationUserIdentifier identity4 = new CommunicationUserIdentifier("<USER_4_ID>");
ChatParticipant thirdThreadParticipant = new ChatParticipant()
.setCommunicationIdentifier(identity3)
.setDisplayName("Display Name 3");
ChatParticipant fourthThreadParticipant = new ChatParticipant()
.setCommunicationIdentifier(identity4)
.setDisplayName("Display Name 4");
participants.add(thirdThreadParticipant);
participants.add(fourthThreadParticipant);
chatThreadClient.addParticipants(participants);