使用Google App Script 发送文件并支持中文名 – Telegram 机器人示例

  • fennng 

我在使用 Google App Script 给我的机器人发送文档的时候,发现发不了中文名, 使用UrlEncoded 过的中文名的话,

显示的是Encoded 后的字串, 而使用中文名的话, 中文名就完全不见了。

给Telegram 机器人发送文件和网页上传文件用的是一模一样的原理, 所以这篇文章也适用于任何使用 multipart/form-data上传文件的情况。

首先, 要使用Google App script 上传一个文档很容易, 以下代码会下载一个电子书, 然后改名, 再上传给Telegram 机器人。

function quickTest(){
    var response = UrlFetchApp.fetch("https://dev.tencent.com/u/adboys/p/ideahub/git/raw/master/%E5%88%86%E7%B1%BB%E7%B2%BE%E9%80%89-azw3/%E7%95%85%E9%94%80%E7%B2%BE%E9%80%89/PhotoShop_CS4%E5%BF%AB%E6%8D%B7%E9%94%AE%E5%A4%A7%E5%85%A8.azw3");
    var blob = response.getBlob();


    blob.setName("峰哥牛逼.azw3");

    var payload = {
        "method": "sendDocument",
        "chat_id": "@fengdrawbottest",
        "document": blob,
    };


    var options = {
        "method": "post",
        "payload": payload
    }

    UrlFetchApp.fetch("https://api.telegram.org/bot717031367:xxx", options);

}

以上代码可以工作, 但是中文名会不见, 最后Telegram 端收到的文件名是 azw3, 前面的 中文和那个点都不见了。 如何使用英文名就不会有问题。

通过技术手段拿到Google App script 发送出来的 Request 是这样的

中文名的地方变成了问号。

从上图可以看到, UrlFetchApp.fetch 命令自动生成的 multipart/form-data request body

没有办法支持中文。 所以解决方案就是不要使用它的自动生成。而是手动的生成multipart/form-data , 这样我们就可以完全控制我们的文件名。

以下是手动生成 multipart/form-data 的代码

function quickTest(){

    var response = UrlFetchApp.fetch("https://dev.tencent.com/u/adboys/p/ideahub/git/raw/master/%E5%88%86%E7%B1%BB%E7%B2%BE%E9%80%89-azw3/%E7%95%85%E9%94%80%E7%B2%BE%E9%80%89/PhotoShop_CS4%E5%BF%AB%E6%8D%B7%E9%94%AE%E5%A4%A7%E5%85%A8.azw3");
    var blob = response.getBlob();
    var filename = "峰哥牛逼.azw3";


    var metadata = {
        "method": "sendDocument",
        "chat_id": "@fengdrawbottest",
    };

    var boundary = "-----zHW0BJecQWMezOLfDmhujjAovfkaD22DJyepDlfCrqSw3aqPZH";
    var data = "";
    for (var i in metadata) {
        data += "--" + boundary + "\r\n";
        data += "Content-Disposition: form-data; name=\"" + i + "\"; \r\n\r\n" + metadata[i] + "\r\n";
    }
    data += "--" + boundary + "\r\n";
    data += "Content-Disposition: form-data; name=\"document\"; filename=\"" + filename + "\"\r\n";
    data += "Content-Type:" + "application/octet-stream" + "\r\n\r\n";
    var payload = Utilities.newBlob(data).getBytes()
        .concat(blob.getBytes())
        .concat(Utilities.newBlob("\r\n--" + boundary + "--\r\n").getBytes());
    var options = {
method : "post",
         contentType : "multipart/form-data; boundary=" + boundary,
         payload : payload,
         muteHttpExceptions: false,
    };


    UrlFetchApp.fetch("https://api.telegram.org/bot717031367:xxx/", options);



}

这样, 中文名的发送就没有问题了

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注