使用ESP32接入Coze API实现聊天机器人的教程

本示例将使用ESP32开发板通过WiFi接入 Coze API,实现一个简单的聊天机器人功能。用户可以通过串口向机器人输入问题,ESP32将通过Coze API与智能体进行通信,并返回对应的回复。本文将详细介绍了如何通过HTTP请求和JSON解析来与API进行交互,并给出完整的代码示例。

一、准备工作

首先我们要获取Coze API 访问令牌和机器人 ID

在扣子(Coze)平台上,API 访问令牌(API Access Token)和机器人 ID(Bot ID)是两个关键的参数,它们用于身份验证和区分不同的机器人。

API 访问令牌(API Access Token)

API 访问令牌是一种安全机制,用于验证你的身份,确保你有权访问扣子平台的 API。每个令牌都是唯一的,并且与你的扣子账户相关联。

获取 API 访问令牌的步骤

  1. 登录扣子平台。
    https://www.coze.cn/home

  2. 注册进入账户 然后点击API 管理部分。
    在这里插入图片描述

  3. 查找生成 API 访问令牌的选项,点击生成新的访问令牌。
    在这里插入图片描述

  4. 系统会为你生成一个访问令牌,通常会有一个复制按钮,复制该令牌,保存起来。

✨注意事项

  • 访问令牌通常包含字母和数字,长度较长,需要妥善保管,不要泄露给他人。
  • 访问令牌一旦生成,通常无法再次查看,只能重新生成。如果丢失,需要重新生成新的令牌,并更新所有使用旧令牌的地方。

机器人 ID(Bot ID)

机器人 ID 是一个用于区分不同机器人的唯一标识符。在扣子平台上,每个机器人都有一个唯一的 ID。

获取机器人 ID 的步骤

  1. 进入你的机器人列表。
    在这里插入图片描述

  2. 点击你想要接入 API 的机器人,查看此时的URL bot/后面的一串数字就是机器人 ID。
    在这里插入图片描述

下面是我用python requests库搭建的请求示例,可以作为参考,这里我使用的v2发起对话接口,关于接口的详细信息可以看下官方文档 ➡️ 发起对话(V2)

import requests
# coze LLM
def send_coze(messages, user_profile):
    api_access_token:str = "pat_ugo1Q9BN1sPvc9dDNQawLtr*******************";  # API 访问令牌
    chat_bot_id:str = "74202200*********";  # 机器人 ID,用于区分不同的聊天机器人

    url = "https://api.coze.cn/open_api/v2/chat"
    headers = {
        "Authorization": f"Bearer {api_access_token}",
        "Content-Type": "application/json"
    }

    payload = {
        "bot_id": chat_bot_id,
        "user": "123123123", #user可随意修改
        "query": user_profile,
        "stream": False
    }
    try:
        response = requests.post(url, headers=headers, json=payload)
        response.raise_for_status()  # 检查请求是否成功
        response_data = response.json()

        messages = response_data.get('messages', [])
        for message in messages:
            message_content = message.get('content', '')
            if not message_content.startswith("{") and not message_content.startswith("RPCError"):
                print(f"coze answer:{message_content}")
                return message_content

    except requests.exceptions.RequestException as e:
        print('Request failed:', e)
        raise e
# 测试函数
def test_send_coze():
    messages = ""
    user_profile = "你好啊"
    response = send_coze(messages, user_profile)
    print("Final Response:", response)
# 运行测试
if __name__ == "__main__":
    test_send_coze()

二、示例代码中的使用

在 ESP32 代码中,API 访问令牌和机器人 ID 被用于构建 HTTP 请求,以便与扣子平台的 API 进行通信。

const String api_access_token = "pat_ugo1Q9BN1sPvc9dDNQawLtrY***********************";  // API 访问令牌
const String chat_bot_id = "74202200**********";  // 机器人 ID

在发送 HTTP 请求时,API 访问令牌被添加到请求头中,用于身份验证:

http_client.addHeader("Authorization", "Bearer " + api_access_token);

机器人 ID 被添加到请求体中,用于指定请求发送到哪个机器人:

json_request["bot_id"] = chat_bot_id;

这样,当 ESP32 发送请求到扣子平台时,平台能够验证请求的合法性,并将其正确地路由到指定的机器人进行处理。

完整代码 arduino框架

#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>

const char* wifi_ssid = "";            // WiFi 网络名称
const char* wifi_password = "";        // WiFi 密码

const String api_access_token = "pat_ugo1Q9BN1sPvc9dDNQawLtr**************";  // API 访问令牌
const String chat_bot_id = "742022000*******";  // 机器人 ID,用于区分不同的聊天机器人

void setup() {
  Serial.begin(9600);

  // 第1步:连接到 WiFi
  WiFi.begin(wifi_ssid, wifi_password);
  while (WiFi.status() != WL_CONNECTED) {  // 如果尚未连接到 WiFi,等待并继续尝试连接
    delay(1000);
    Serial.println("正在连接到WiFi...");
  }
  Serial.println("已连接到WiFi");

  Serial.print("请输入问题: ");
}

void loop() {
  // 第2步:检查是否有用户输入
  if (Serial.available()) {
    String user_input = Serial.readStringUntil('\n');  // 读取用户输入直到遇到换行符
    user_input.trim();  // 去除输入前后的空白字符,确保输入干净

    Serial.println(user_input);  // 在串口打印用户输入的内容

    // 检查 WiFi 是否连接
    if (WiFi.status() != WL_CONNECTED) {
      Serial.println("错误: WiFi 未连接");
      return;
    }

    // 第3步:创建 HTTPClient 对象并配置请求
    HTTPClient http_client;  // 创建 HTTPClient 对象,管理 HTTP 请求
    http_client.begin("https://api.coze.cn/open_api/v2/chat");  
    http_client.addHeader("Authorization", "Bearer " + api_access_token);
    http_client.addHeader("Content-Type", "application/json");  // 设置请求头,指定内容类型为 JSON

    // 第4步:创建 JSON 请求体
    DynamicJsonDocument json_request(1024);
    json_request["bot_id"] = chat_bot_id;
    json_request["user"] = "123123123";
    json_request["query"] = user_input;
    json_request["stream"] = false;

    String request_body;  // 存储 JSON 
    serializeJson(json_request, request_body);  // JSON 文档序列化为字符串

    // 第5步:发送 HTTP POST 请求并获取响应
    int http_response_code = http_client.POST(request_body);  // 发送 POST 请求

    String server_response;
    if (http_response_code > 0) {
      server_response = http_client.getString(); 
    } else {
      Serial.print("POST请求出错: ");
      Serial.println(http_response_code);
      server_response = "错误: " + String(http_response_code);
    }
    http_client.end();

    // 第6步:解析并处理服务器响应
    DynamicJsonDocument json_response(1024);  // 创建用于解析响应的 JSON 文档
    DeserializationError json_error = deserializeJson(json_response, server_response);  // 解析服务器响应的 JSON 数据

    if (json_error) {  // 如果解析失败
      Serial.print("解析JSON失败: ");
      Serial.println(json_error.c_str()); 
      return; 
    }

    // 第7步:提取并输出消息内容
    JsonArray messages = json_response["messages"];  // 获取响应中的消息数组
    for (JsonVariant message : messages) {  // 遍历每个消息获取消息内容
      String message_content = message["content"].as<String>();  
      if (!message_content.startsWith("{") && !message_content.startsWith("RPCError")) {
        Serial.println(message_content);
      }
    }
    Serial.print("请输入问题: ");
  }
}

三、总结

参考资料:扣子 API快速文档

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐