首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 微信企業號開發:發送文本、圖片、語音消息完整實現

     編輯:Java 相關知識

企業號/企業微信消息發送概覽

企業號 (現企業微信) 通過 **應用發送消息 API** 向成員發送各類消息,需獲取 `access_token` (企業級,非公眾號)。

前置條件

  • 企業 ID (CorpID) 與應用 Secret
  • 獲取 `access_token`:`GET https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=xxx&corpsecret=xxx`
  • 發送介面:`POST https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=TOKEN`
  • JSON 請求體,響應 `errcode=0` 表示成功

統一發送入口

public class WechatWorkClient {
    private static final String SEND_URL = 
        "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s";
    private final String accessToken;
    private final HttpClient httpClient;
    
    public WechatWorkClient(String accessToken) {
        this.accessToken = accessToken;
        this.httpClient = HttpClientBuilder.create().build();
    }
    
    public JsonObject send(String jsonBody) throws IOException {
        HttpPost post = new HttpPost(String.format(SEND_URL, accessToken));
        post.setEntity(new StringEntity(jsonBody, ContentType.APPLICATION_JSON));
        try (CloseableHttpResponse resp = httpClient.execute(post)) {
            String result = EntityUtils.toString(resp.getEntity(), "UTF-8");
            return JsonParser.parseString(result).getAsJsonObject();
        }
    }
}

1. 發送文本消息

請求結構

{
  "touser": "UserID1|UserID2",  // 接收者,多個用 | 分隔,@all 發送給全員
  "toparty": "PartyID1|PartyID2", // 接收部門
  "totag": "TagID1|TagID2",      // 接收標籤
  "msgtype": "text",
  "agentid": 1000001,            // 應用 ID
  "text": {
    "content": "您好,這是一條測試文本消息。"
  },
  "safe": 0,                     // 0-不加密 1-加密
  "enable_id_trans": 0,          // 是否轉換 userID 為 openID
  "enable_duplicate_check": 0,   // 是否重複檢查
  "duplicate_check_interval": 1800
}

Java 構建代碼

public JsonObject sendText(String touser, String content, int agentId) {
    JsonObject msg = new JsonObject();
    msg.addProperty("touser", touser);
    msg.addProperty("msgtype", "text");
    msg.addProperty("agentid", agentId);
    
    JsonObject text = new JsonObject();
    text.addProperty("content", content);
    msg.add("text", text);
    
    return send(msg.toString());
}

2. 發送圖片消息

兩步驟:上傳素材 → 發送引用

步驟 1:上傳圖片獲取 media_id

POST https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=TOKEN&type=image
Content-Type: multipart/form-data

// 響應
{"errcode":0,"errmsg":"ok","type":"image","media_id":"3J6Y...","created_at":1234567890}

Java 上傳實現

public String uploadImage(File imageFile) throws IOException {
    String url = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=" 
        + accessToken + "&type=image";
    
    HttpPost post = new HttpPost(url);
    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addBinaryBody("media", imageFile, ContentType.IMAGE_JPEG, imageFile.getName());
    post.setEntity(builder.build());
    
    try (CloseableHttpResponse resp = httpClient.execute(post)) {
        JsonObject obj = JsonParser.parseString(
            EntityUtils.toString(resp.getEntity())).getAsJsonObject();
        return obj.get("media_id").getAsString();
    }
}

步驟 2:發送圖片消息

public JsonObject sendImage(String touser, String mediaId, int agentId) {
    JsonObject msg = new JsonObject();
    msg.addProperty("touser", touser);
    msg.addProperty("msgtype", "image");
    msg.addProperty("agentid", agentId);
    
    JsonObject image = new JsonObject();
    image.addProperty("media_id", mediaId);
    msg.add("image", image);
    
    return send(msg.toString());
}

3. 發送語音消息

格式要求

  • 格式:AMR / MP3
  • 大小:≤ 2MB
  • 時長:≤ 60秒
  • 同上:先上傳獲取 `media_id` (type=voice),再發送

發送代碼

public JsonObject sendVoice(String touser, String mediaId, int agentId) {
    JsonObject msg = new JsonObject();
    msg.addProperty("touser", touser);
    msg.addProperty("msgtype", "voice");
    msg.addProperty("agentid", agentId);
    
    JsonObject voice = new JsonObject();
    voice.addProperty("media_id", mediaId);
    msg.add("voice", voice);
    
    return send(msg.toString());
}

4. 發送圖文消息

請求結構

{
  "msgtype": "news",
  "news": {
    "articles": [
      {
        "title": "標題",
        "description": "描述",
        "url": "https://example.com/detail",
        "picurl": "https://example.com/cover.jpg"
      }
    ]
  }
}

Java 實現

public JsonObject sendNews(String touser, List
articles, int agentId) { JsonObject msg = new JsonObject(); msg.addProperty("touser", touser); msg.addProperty("msgtype", "news"); msg.addProperty("agentid", agentId); JsonObject news = new JsonObject(); JsonArray arr = new JsonArray(); for (Article a : articles) { JsonObject item = new JsonObject(); item.addProperty("title", a.getTitle()); item.addProperty("description", a.getDesc()); item.addProperty("url", a.getUrl()); item.addProperty("picurl", a.getPicUrl()); arr.add(item); } news.add("articles", arr); msg.add("news", news); return send(msg.toString()); } static class Article { String title, desc, url, picUrl; // getter/setter }

5. 發送文件消息

  • 上傳 type=file 獲取 media_id
  • 發送 msgtype=file,結構同圖片/語音
  • 支援格式廣泛,大小 ≤ 20MB

錯誤碼對照與處理

errcode含義處理建議
0成功-
40037模板不存在/參數錯誤檢查 JSON 結構、必填字段
41028media_id 失效/不存在重新上傳素材,media_id 3天有效
41029media_id 類型不匹配圖片用 image,語音用 voice,勿混用
45009接口調用超限檢查應用頻率限制,實施佇列限流
60020接收者不存在驗證 userid/partyid/tagid 有效性
81011內容含敏感詞內容審核、替換敏感詞

最佳實踐總結

  • **Token 管理**:複用第 3 篇的中控服務器方案,企業級 token 獨立緩存
  • **異步發送**:引入消息佇列,避免 HTTP 調用阻塞業務線程
  • **重試機制**:網絡錯誤指數退避重試 3 次,記錄失敗入庫人工補發
  • **素材預上傳**:圖片/語音/文件提前上傳獲取 media_id,發送時直接引用
  • **發送記錄**:落地發送日誌 (接收者、內容摘要、errcode、耗時) 便於審計追蹤
  • **安全模式**:涉密內容啟用 `safe=1`,接收端需解密

完整調用示例

@Service
public class WechatWorkNotifyService {
    @Autowired WechatWorkClient client;
    
    public void notifyText(String user, String content) {
        try {
            JsonObject result = client.sendText(user, content, 1000001);
            if (result.get("errcode").getAsInt() != 0) {
                log.error("發送失敗: {}", result.get("errmsg"));
            }
        } catch (Exception e) {
            log.error("發送異常", e);
        }
    }
    
    public void notifyWithImage(String user, String text, File image) {
        try {
            String mediaId = client.uploadImage(image);
            client.sendImage(user, mediaId, 1000001);
        } catch (Exception e) { log.error("圖片通知失敗", e); }
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved