ChatGPT 彩蝶信使
现在,跟朋友保持联系太费时间了。在社交媒体和消息应用出现前,你实际上必须和人们在现实生活中相处一段时间。虽然现在你可以发短信,但想要想好要说什么和和他们互动仍然很痛苦。
现在有一个解决方案!你不再需要思考,可以与你的朋友通过人工智能聊天!
当然,我们只是开玩笑:你肯定还是要和朋友一起出去,不要把你的关系外包给人工智能。但这仍然是一个很酷的用例,可以用于回复机器人,甚至在谈话变得有点枯燥时帮助你保持对话。
在本文中,我们将介绍如何使用声网聊天构建自己的聊天应用程序,然后通过添加ChatGPT使其更加华丽。
您可以在这里找到完整的代码。
声网聊天
Agora Chat 可以让您与您的朋友通信,包括文本、图像、GIF、表情和其他媒体。Agora Chat 可以作为独立应用程序使用,也可以集成到您现有的实时通信 (RTC) 应用程序中,例如视频通话。
ChatGPT
OpenAI的ChatGPT是他们的AI模型,可以生成非常逼真的消息回复。我们将使用OpenAI API向模型发送请求,获取我们将插入到聊天中的回复。
安装配置
为了与这些服务进行交互,我们需要在Agora和OpenAI上创建账户并获取一些令牌。
如何检索Agora Chat信息
- 在Agora.io上创建一个账户。
- 创建项目
- 向下滚动至聊天,然后单击启用/配置。
- 点击切换按钮,复制并粘贴AppKey。
- 在操作管理下选择用户,在左侧创建两个用户。(记下用户ID。)
- 返回基本信息选项卡下的应用程序信息,在“聊天用户临时令牌”字段中输入每个用户的用户ID。单击“生成”。将令牌和用户ID复制并粘贴到consts.dart文件中,保持HTML结构不变。
如何获取OpenAI令牌
- 创建一个OpenAI账户。
- 在右上角单击您的图像并选择查看 API 密钥。
- 创建一个新的秘钥,复制并粘贴到consts.dart文件中。
聊天页面
我们需要进入聊天页面,带有当前用户的ID、令牌,以及你想发送消息的用户的ID。有多种方法可以实现这一点,但是在本例中,我只创建了两个按钮,您可以以每个个人用户的身份登录。您可以在main.dart文件中查看更多信息。
当我们进入聊天页面时,我们需要完成三件事才能初始化我们的聊天。由于我们没有使用 Agora Chat SDK 进行设置,我们需要初始化 SDK,然后为消息添加监听器,最后将当前用户登录,以使聊天应用程序完全准备好使用。这三个功能需要在 initState 中调用。
void _initSDK() async {
ChatOptions options = ChatOptions(
appKey: widget.chatKey,
autoLogin: false,
);
await ChatClient.getInstance.init(options);
await ChatClient.getInstance.startCallback();
}
void _addChatListener() {
ChatClient.getInstance.chatManager.addMessageEvent(
"UNIQUE_HANDLER_ID",
ChatMessageEvent(
onSuccess: (msgId, msg) {
debugPrint(
"send message succeed: ${(msg.body as ChatTextMessageBody).content}");
_addMessage(
DemoMessage(
text: (msg.body as ChatTextMessageBody).content,
senderId: widget.userId),
);
},
onProgress: (msgId, progress) {
debugPrint("send message succeed");
},
onError: (msgId, msg, error) {
debugPrint(
"send message failed, code: ${error.code}, desc: ${error.description}",
);
},
));
ChatClient.getInstance.chatManager.addEventHandler(
"UNIQUE_HANDLER_ID",
ChatEventHandler(onMessagesReceived: onMessagesReceived),
);
}
void _signIn() async {
try {
await ChatClient.getInstance.loginWithAgoraToken(
widget.userId,
widget.agoraToken,
);
debugPrint("login succeed, userId: ${widget.userId}");
} on ChatError catch (e) {
debugPrint("login failed, code: ${e.code}, desc: ${e.description}");
}
}
由于我们在这里有签入的方法,让我们也创建我们的签出方法。这会在释放方法中调用。
void _signOut() async {
ChatClient.getInstance.chatManager.removeMessageEvent("UNIQUE_HANDLER_ID");
ChatClient.getInstance.chatManager.removeEventHandler("UNIQUE_HANDLER_ID");
try {
await ChatClient.getInstance.logout(true);
debugPrint("sign out succeed");
} on ChatError catch (e) {
debugPrint(
"sign out failed, code: ${e.code}, desc: ${e.description}");
}
}
您会注意到在聊天监听器中调用的一些函数没有显示:
- _addMessage将传入的消息添加到可见消息列表中。
- debugPrint将传入的消息添加到控制台日志中。
- onMessagesReceived是一个在收到消息时调用的函数。(我们还将使用_addMessage来保持双方的列表。)
以下是这些函数的定义。
void onMessagesReceived(List<ChatMessage> messages) {
for (var msg in messages) {
switch (msg.body.type) {
case MessageType.TXT:
{
ChatTextMessageBody body = msg.body as ChatTextMessageBody;
debugPrint(
"receive text message: ${body.content}, from: ${msg.from}",
);
_addMessage(
DemoMessage(text: body.content, senderId: msg.from),
);
}
break;
default:
break;
}
}
}
void _addMessage(DemoMessage message) {
_messages.add(message);
setState(() {
scrollController.jumpTo(scrollController.position.maxScrollExtent + 40);
});
}
展示聊天记录
一个ListView.builder会显示_messages列表中的所有信息。您还需要在屏幕底部添加一个TextField,以便我们发送信息。
ListView.builder(
controller: scrollController,
itemCount: _messages.length,
itemBuilder: (_, index) {
//show first 10 characters
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 2),
if (widget.userId != _messages[index].senderId)
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.lightBlue[100],
borderRadius: BorderRadius.circular(10),
),
child: Text(
_messages[index].text!,
),
)
else
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Flexible(
child: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.lightGreen[100],
borderRadius: BorderRadius.circular(10),
),
child: Text(
_messages[index].text!,
),
),
),
],
),
],
);
},),
发送消息
要发送消息,我们需要从声网聊天 SDK 中调用 sendMessage 函数。此函数接受 ChatMessage 对象作为参数。我们还需要传递要发送消息的人的用户 ID。
void _sendMessage(String sentTo, String? message) async {
if (message == null) {
debugPrint("single chat id or message content is null");
return;
}
var msg = ChatMessage.createTxtSendMessage(
targetId: sentTo,
content: message,
);
ChatClient.getInstance.chatManager.sendMessage(msg);
setState(() {
_messageController.text = "";
});
}
我们现在拥有完全功能的Agora聊天应用程序。最后一步是集成ChatGPT以启用人工智能生成的响应。
ChatGPT
为了使用ChatGPT,我们首先需要连接到API。我们还需要声明一个isWaitingResponse变量,该变量用于在我们等待API的响应时禁用发送按钮。
一旦变量被声明,我们可以设置函数来向其他用户的最后一条消息发送快乐或愤怒的回应。
final openAI = OpenAI.instance.build(
token: openAIToken,
baseOption: HttpSetup(receiveTimeout: const Duration(seconds: 30)),
isLog: true);
var _isWaitingResponse = false;
void _onTapSendHappyMessage() async {
final List<DemoMessage> otherMessages = _messages
.where((element) => element.senderId != widget.userId)
.toList();
_reset();
_sendAIMessage(
"Give me a happy response to the message: ${otherMessages.last.text}",
).then((value) {
setState(() {
_isWaitingResponse = false;
_messageController.text = value.trim();
});
});
}
void _onTapSendAngryMessage() async {
final List<DemoMessage> otherMessages = _messages
.where((element) => element.senderId != widget.userId)
.toList();
_reset();
_sendAIMessage(
"Give me an angry response to the message: ${otherMessages.last.text}",
).then((value) {
setState(() {
_isWaitingResponse = false;
_messageController.text = value.trim();
});
});
}
void _reset() {
setState(() {
_isWaitingResponse = true;
});
}
Future<String> _sendAIMessage(String message) async {
final request = CompleteText(
prompt: message,
model: Model.textDavinci3,
maxTokens: 200,
);
final response = await openAI.onCompletion(
request: request,
);
return response!.choices.first.text;
}
那就是我们应用的全部功能。现在您可以添加生成这些响应的按钮,并将它们放入TextField的TextController.value中,以便用户发送。
感谢阅读。单击此处了解更多关于声网的信息。