You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Java向Telegram Bot发送多张图片?

如何通过Telegram Bot发送多张图片(基于sendMediaGroup接口)

我有一个可以提交单张图片并添加说明文字的Java方法,代码如下:

public void webhook(Update update) throws IOException {
    URL url = new URL("https://api.telegram.org/bot6143090937:AAHOpW0PNMK9qROsFqQ4DE-T1F_ox-IZ0dU/sendPhoto?chat_id="
            + update.getMessage().getChatId() + "&caption=Message Message ");

    HttpsURLConnection httpConn = (HttpsURLConnection) url.openConnection();

    httpConn.setDoOutput(true);

    httpConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=boundary--");

    OutputStream outputStream = httpConn.getOutputStream();

    PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8), true);

    new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);


    writer.append("--").append("boundary--").append("\r\n");
    writer.append("Content-Disposition: form-data; name=\"")
            .append("photo")
            .append("\"; filename=\"")
            .append("image.jpg").append("\"")
            .append("\r\n");
    writer.append("\r\n");
    writer.flush();

    File uploadFile1 = new File("C:\\img\\image.jpg");

    try (FileInputStream inputStream = new FileInputStream(uploadFile1)) {
        byte[] buffer = new byte[4096];
        int byteRead;
        while ((byteRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, byteRead);
        }

        outputStream.flush();
    }

    writer.append("\r\n").flush();
    writer.append("--").append("boundary--").append("--").append("\r\n");

    writer.flush();
    writer.close();

    httpConn.getResponseCode();
}

但我不知道如何发送多张图片,也就是一组图片。Telegram提供了sendMediaGroup接口,但我不清楚怎么结合上面的代码实现。


核心思路

sendMediaGroup接口要求提交一个media数组,每个元素对应一张图片(或其他媒体);如果上传本地文件,需通过multipart/form-data格式同时提交媒体配置信息和文件内容。

实现步骤

  1. 替换请求接口:将原sendPhoto接口改为sendMediaGroup,URL仅保留chat_id参数,其余参数通过multipart提交。
  2. 构造媒体配置JSON:每个媒体元素需指定type为photo,media字段用attach://<文件名>关联待上传文件;仅数组第一个元素的caption会作为整个媒体组的说明显示。
  3. 按multipart格式提交数据:先提交media参数的JSON内容,再依次上传每张图片文件,文件的name需与attach://后的名称完全匹配。

完整代码示例

public void sendMediaGroup(Update update) throws IOException {
    // 准备请求URL
    String chatId = update.getMessage().getChatId().toString();
    URL url = new URL("https://api.telegram.org/bot6143090937:AAHOpW0PNMK9qROsFqQ4DE-T1F_ox-IZ0dU/sendMediaGroup?chat_id=" + chatId);
    
    HttpsURLConnection httpConn = (HttpsURLConnection) url.openConnection();
    httpConn.setDoOutput(true);
    // 用时间戳生成唯一边界,避免与文件内容冲突
    String boundary = "boundary--" + System.currentTimeMillis();
    httpConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
    
    OutputStream outputStream = httpConn.getOutputStream();
    PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8), true);
    
    // 构造media数组的JSON配置
    String mediaJson = "[\n" +
            "  {\"type\": \"photo\", \"media\": \"attach://image1.jpg\", \"caption\": \"这是整个媒体组的说明\"},\n" +
            "  {\"type\": \"photo\", \"media\": \"attach://image2.jpg\"},\n" +
            "  {\"type\": \"photo\", \"media\": \"attach://image3.jpg\"}\n" +
            "]";
    
    // 提交media参数
    writer.append("--").append(boundary).append("\r\n");
    writer.append("Content-Disposition: form-data; name=\"media\"").append("\r\n");
    writer.append("Content-Type: application/json").append("\r\n");
    writer.append("\r\n");
    writer.append(mediaJson).append("\r\n");
    writer.flush();
    
    // 依次上传图片文件
    uploadFile(writer, outputStream, boundary, "image1.jpg", new File("C:\\img\\image1.jpg"));
    uploadFile(writer, outputStream, boundary, "image2.jpg", new File("C:\\img\\image2.jpg"));
    uploadFile(writer, outputStream, boundary, "image3.jpg", new File("C:\\img\\image3.jpg"));
    
    // 结束multipart请求
    writer.append("\r\n").flush();
    writer.append("--").append(boundary).append("--").append("\r\n");
    writer.flush();
    writer.close();
    
    // 获取响应码,可根据需求处理响应内容
    int responseCode = httpConn.getResponseCode();
    System.out.println("请求响应码:" + responseCode);
}

// 封装文件上传逻辑,复用代码
private void uploadFile(PrintWriter writer, OutputStream outputStream, String boundary, String fileName, File file) throws IOException {
    writer.append("--").append(boundary).append("\r\n");
    writer.append("Content-Disposition: form-data; name=\"").append(fileName).append("\"; filename=\"").append(fileName).append("\"").append("\r\n");
    // 根据图片类型调整Content-Type,如png用image/png
    writer.append("Content-Type: image/jpeg").append("\r\n");
    writer.append("\r\n");
    writer.flush();
    
    try (FileInputStream inputStream = new FileInputStream(file)) {
        byte[] buffer = new byte[4096];
        int byteRead;
        while ((byteRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, byteRead);
        }
        outputStream.flush();
    }
}

关键注意事项

  • 媒体组限制:最多支持10个媒体元素,且所有元素的type必须一致(此处均为photo)。
  • 说明文字规则:仅数组第一个元素的caption会生效,作为整个媒体组的顶部说明。
  • 文件关联校验:media字段中的attach://<name>必须与文件的name参数完全一致,否则Telegram无法识别对应文件。
  • 边界唯一性:建议用随机字符串或时间戳生成边界值,避免与文件内容中的字符冲突。

内容的提问来源于stack exchange,提问作者New York is my city

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:08:32