【ESP32】如何使用Atom Echo给企业微信发送“语音”消息!

瞎讲

上周在m5stack用户群里,看到一老哥使用Atom Echo给企业微信发消息,觉得还蛮有意思的,原本是要集成到UiFlow里面的,不过自己先使用Arduino测试了一下接口,觉得应该还可以做一些小应用之类的,所以就简单写个教程分享给大家,不过不是什么非常高深的操作,就是普通的http请求,相信大家一看就懂~

准备

硬件

软件

大概就需要准备这些东西吧,Atom Echo大家不了解的可以直接点击上面的链接查看,购买的话可以某宝。

原理(或者叫流程?)

Atom Echo是一款非常迷你的ESP32开发板,集成了数字麦克风和喇叭,不过我们这里只用到了麦克风,我们对麦克风讲话,然后用官方的语音转文本代码,就可以获取到讲的话的文本内容,然后我们在根据企业微信的API就可以将消息推送给企业微信内的用户了,这里要注意的是目前的接口仅支持企业微信内的应用给用户发消息,不支持两个用户之间或者用户给应用发消息(具体的大家可以再仔细看看,我也没太仔细看)。这就是大概的一个流程,画个简单的图给大家看一下:
流程

流程图
其中最重要的一步音频转文本处理是在m5stack的后台处理的,这些都已经封装成库了,使用起来也非常方便。

步骤

注册企业微信

要想使用企业微信的接口,我们是需要注册一下企业微信的,现在注册没什么限制,大家都可以随便注册:
企业微信注册链接

获取企业ID(corpid)

我们后面需要用这个ID来请求token,所以是非常重要的,注册好后登录,可以在我的企业最下边看到:

新建应用&获取corpsecret和AgentId

大家可以在应用管理->应用->自建看到创建应用选项,按照要求填写就可以,可见范围的话,自己选择就可以,你想这个应用可以给谁发消息就选择谁,也可以选择整个部门。
注册完成后就能够看见你的corpsecretAgentId了,记录一下,后面我们会用到。

获取m5stack的token

要使用m5stack的音频转文本服务也是需要一个token的,不过这个就相对简单了,大家可以使用上面我讲到的M5Burner软件一键获取。

代码修改&下载

代码非常简单,大家直接将下面部分的代码替换为上面我们一步步得到的ID或者key的就好了,其中Wi-Fi名称这个当然是填你自己的。

// Wi-Fi & m5stack token
const char *WifiSSID = "XXXXXXXXXX";
const char *WifiPWD = "XXXXXXXXXX";
const char *m5stack_token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
// 企业微信
#define WX_CORPID      "XXXXXXXXXXXXXXXXXXXX"
#define WX_CORPSECRET  "XXXXXXXXXXXXXXXXXXXXXXXXXXX"
#define WX_AGANTID     99999999
#define WX_USERID      "XXXXXXXXX" // 多用户用 “|” 分隔,如 "user1|user2|user3"

测试

修改完代码并下载好后,长按住中间按键讲话,就应该能够在企业微信上收到刚才你讲话的内容了,当然识别率可能会没那么高,毕竟是音频转文本。目前只支持录制几秒,音频太长的话ESP32暂时处理不过来。

关键代码

int getWXtoken(void)
{
  int ret = 0;
  {
    HTTPClient https;
    sprintf(buf, WX_REQUEST_TOKEN_API, WX_CORPID, WX_CORPSECRET);
    Serial.print("[HTTPS] begin...\n");
    if (https.begin((String)buf)) {  // HTTPS
      Serial.print("[HTTPS] GET...\n");
      // start connection and send HTTP header
      int httpCode = https.GET();
      // httpCode will be negative on error
      if (httpCode > 0) {
        // HTTP header has been send and Server response header has been handled
        Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
        // file found at server
        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
          String payload = https.getString();
//          Serial.println(payload);
          deserializeJson(WX_json_decode, payload);
          int errcode =  WX_json_decode["errcode"].as<int>();
          String errmsg =  WX_json_decode["errmsg"].as<String>();
          if ( errcode == 0 && strcmp((char *)&errmsg, "ok") == 0) {
            access_token_buf = WX_json_decode["access_token"].as<String>();
//            Serial.println(access_token_buf);
            ret = 1;
          }
          else {
            Serial.println("json fail!");
            ret = 0;
          }
        }
      } else {
        Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
        ret = -1;
      }
      https.end();
    } else {
      Serial.printf("[HTTPS] Unable to connect\n");
      ret = -2;
    }
  }
  return ret;
}
int sendWXmsg(String msg)
{
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    sprintf(buf, WX_SEND_MSG_API, (char *)access_token_buf.c_str());
    http.begin(buf);
    http.addHeader("Content-Type", "application/json;charset=UTF-8");
    sprintf(buf, WX_TEXT_CONTENT, WX_USERID, WX_AGANTID, (char *)msg.c_str());
    int httpResponseCode = http.POST(buf);
//    Serial.print("HTTP Response code: ");
//    Serial.println(httpResponseCode);
    // Free resources
    http.end();
  }
}

这两个函数是用来请求企业微信的access_token和发送文本消息到企业微信,第一个是Get请求,第二个是Post请求。这地方怎么去写,其实完全是根据官方的API来的,API中都有介绍也有例子,大家可以看看还有哪些好玩的API,然后去自己写一下(是支持发语音消息,不如看看?)。

End

呀,写完了,貌似没啥别的要讲的了,最近有点懒,好久没写点文章或者教程了,最后给大家放个演示视频看看吧。

源码链接:Github

请我喝一罐冰阔乐 (^o^)/