Dify.AI x Discord 一个小尝试

这篇文章会介绍如何使用 Dify 去做一个 Discord 群聊机器人,这里会分享一些流式处理以及Discord Command的处理

很久没有在掘金写文章啦,当然也是好久没有写文章啦,这篇文章会介绍如何使用 Dify 去做一个 Discord 群聊机器人

准备

你需要以下一些东西,

GitHub – crazywoola/hareporter: A simple discord bot

Discord

Dify

环境变量

.env 中配置前三个环境变量,cp .env.example .env

ini
复制代码
DISCORD_TOKEN=YOUR_BOT_TOKEN DISCORD_ID=YOUR_BOT_ID DIFY_API_KEY=YOUR_DIFY_API_KEY POSTGRES_USER=postgres POSTGRES_PASSWORD=botbot POSTGRES_DB=bot POSTGRES_PORT=5432 POSTGRES_HOST=db

项目目录结构

csharp
复制代码
. ├── Dockerfile ├── README.md ├── docker-compose.yml ├── package.json ├── src │ ├── commands │ │ ├── ask.js │ │ └── ping.js │ ├── db.js │ └── index.js └── yarn.lock

src/commands 目录下面是是 Discord Slash Command 的配置,db.js 是一个简单的数据库,index.js 则是这个程序主要的逻辑。

原理解释

我们主要用到了两个

Discord

我们用到了三个主要的函数

arduino
复制代码
discord.login process.env.DISCORD_TOKEN discord.once Events.ClientReady discord.on Events.InteractionCreate

Discord 的机器人也是有身份的 🆔,不过它是通过 Token 这种方式登录的,登录之后,会触发一个一次性的事件也就是 ClientReady 我们在这里会做一些初始化的操作例如

  • 获取应用的信息
  • 同步我们塑料的数据库
  • 注册我们写的 Command

Slash Command

通常一个简单的 PingPong Command 非常之简单,以下代码定义了一个叫做 ping 的命令,描述为 Replies with Pong!

css
复制代码
import { SlashCommandBuilder } from '@discordjs/builders'; export default { data: new SlashCommandBuilder() .setName('ping') .setDescription('Replies with Pong!') }

我们需要在函数 discord.on Events.InteractionCreate 中处理这个 Command,⚠️这里需要注意,需要在3s之内回复,不然就会有红色的提示告诉你机器人无响应。所以我们需要使用到以下方法

css
复制代码
await message.deferReply({ ephemeral: false }); await message.followUp({ content: '...' }); // or message.reply({ content: '...' });

第一种方式会展示一个类似于输入中的状态,而不用直接回复到用户,所以它需要特殊的方法来回复也就是 followUp 或者第二种方法是直接回复一个内容,一般如果是 ping pong 这种简单命令就可以用第二种方法回复。

我们这里使用到 Dify 的对话 API 则需要考虑流式这种方式,所以我们不能够一次性的返回出来,这样显得机器人没有什么感情 🤖️️️,所以我们还需要 message.editReply({ content: msg || '😄' });用来修改已经发送的内容。

Dify

在这个部分,我们需要特别注意的就是拼接请求参数和处理流式的返回,也就是在开始我们初始化的过程中获取的应用信息,因为有一些应用在 prompt 中自定义了参数,而我们需要把这个参数传过去,不然就会是 400 的错误❌

ini
复制代码
const response = await chatClient.createChatMessage( inputs, query, user.external_id, true, conversation.conversation_id ); const stream = response.data;

这个函数接受了上述的参数,其中 inputs user.external_id conversation.conversation_id 这三个需要特别注意⚠️不要写错了,如果第一次对话的话 conversation.conversation_id 应该是 nulluser.external_id只需要在应用内保证唯一,规则是自定义的。inputs 则需要和之前获取到的应用信息一一对应。

那么接下来就是处理 stream 了,在 Node 中处理其实是非常简单的,我们这里简单的处理了 data end两种情况。在 data chunk 中使用 toString() 方法可以获取到服务器返回的数据,大概是一个 data: { ... } 这种形式,所以我们需要获取后面 json 里面的内容也就是需要 parse,但是有时候可能会出错,所以我们这里就简单的 catch 住就行。

ini
复制代码
const completeString = chunk.toString(); parsed = JSON.parse(completeString.slice(completeString.indexOf('{')));

end 中我们可以处理一下完整的消息,再给发一遍就行。😂

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
人工智能

4种方法让你上传任何文件到ChatGPT: 总有一种适合你

2024-4-28 5:31:36

人工智能

10个爆火的AI文本工具,轻松写出高质量文案

2024-4-28 9:31:45

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索