我在使用 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); }
这样, 中文名的发送就没有问题了