【问题标题】:Read Images from system or url using google apps script in google sheets and post image to an API使用谷歌表格中的谷歌应用脚​​本从系统或 url 读取图像并将图像发布到 API
【发布时间】:2020-09-10 13:37:46
【问题描述】:

我是新来的。

我正在尝试使用 put 请求来上传图像,我想使用 google 表格和 google 应用程序脚本来执行此操作。我可以将图像从 url 添加到工作表,但不能添加到 api,因为它只接受 .png/.jpeg 格式,我认为目前它采用 blob 格式。不确定。

任何人都可以帮助我如何使用谷歌应用脚​​本和工作表将图像发送到 api。

当我在参数中键入图像作为键(文件类型)然后从设备上传图像时,我能够使用邮递员获得成功响应。

这是我用来实现上述目的的一些代码:

function insertImageOnSpreadsheet() {

  var ss = SpreadsheetApp.getActiveSpreadsheet();

  var sheet = ss.getSheetByName('Sheet1');

  var response = UrlFetchApp.fetch('Enter URL Here');
  var binaryData = response.getContent();

  // Insert the image in cell A1.
  var blob1 = Utilities.newBlob(binaryData, 'image/png', 'MyImageName');
  Logger.log(blob1)
  
      var apiHeaders = 
    {
      "Content-Type":"application/json",
      "Authorization":"Enter Token here"
    }
    var formData= '{"image": "'+blob1+'"}'

    var eventApiResponse = callApi('Enter API Here',"put",formData,apiHeaders,"insertImageOnSpreadsheet");
    Logger.log(eventApiResponse)
 
 
  sheet.insertImage(blob1, 1, 3);
}

function callApi(targetURL, method, formData, headers,functionName) {
  var options = {
    "method": method,
    "payload":formData,
    "headers":headers}
  var response = UrlFetchApp.fetch(targetURL, options);
  return response;
 }

API: livestream.com/developers/docs/api/#update-event-logo-poster

有人请帮忙

【问题讨论】:

  • 为了正确了解您目前的情况,能否提供您要使用的API的规范和当前的错误信息?
  • API 说文件类型不受支持。所以我假设我的代码正在发送 blob。 API 接受图片密钥中的 png 文件
  • 感谢您的回复。例如,当您将文件作为字节数组而不是 blob 发送时,您会得到什么结果?就像var formData = Utilities.newBlob(binaryData, 'image/png', 'MyImageName').getBytes()var formData = JSON.stringify({image: Utilities.newBlob(binaryData, 'image/png', 'MyImageName').getBytes()})。如果这些不是直接的解决方案,我深表歉意。
  • 虽然我还不能理解你要使用的API的规范,比如The API says unsupported file type,base64怎么样?
  • API 将只接受 png 和 jpeg 格式的图像,不接受其他文件格式或 base64 或 blob 等格式。错误 - {"code":415,"message":"HTTP 415 Unsupported Media Type"}

标签: javascript google-apps-script google-sheets


【解决方案1】:

我相信你的目标如下。

修改点:

  • 当我看到“更新事件标志(海报)”的示例 curl 命令时,如下所示。

      curl -X PUT \
        -u [API_SECRET_KEY] \
        -F logo='@<image file location>;type=<image type>' \
        --header 'Content-Type: multipart/form-data' \
        'https://livestreamapis.com/v3/accounts/18855759/events/5201483/logo'
    
    • 在这种情况下,使用基本授权。似乎需要使用multipart/form-data 将请求正文发送到{"logo": "data"} 到“文件”。
    • 为了发送带有multipart/form-data 的文件数据,需要创建请求体。
      • 在这种情况下,请求正文是使用字节数组创建的,因为包含二进制数据。
  • 在您的脚本中,

    • 我无法理解"Authorization":"Enter Token here"。但从示例 curl 命令中,我认为“API_SECRET_KEY”未使用 base64 编码。
    • 在示例 curl 命令中,未使用 "Content-Type":"application/json"

修改脚本:

当你的脚本被修改后,它变成如下。

const url = "###";  // Please set URL you want to use. It's like "https://livestreamapis.com/v3/accounts/18855759/events/5201483/logo".
const API_SECRET_KEY = "###";  // Please set your API_SECRET_KEY
// var binaryData = UrlFetchApp.fetch('Enter URL Here').getContent();
const binaryData = DriveApp.getFileById("### fileId ###").getBlob().getBytes();  // Modified

let data = "--xxxxxxxxxx\r\n";
data += "Content-Disposition: form-data; name=\"logo\"; filename=\"sample.png\"\r\n";
data += "Content-Type: image/png\r\n\r\n";
const payload = Utilities.newBlob(data).getBytes()
  .concat(binaryData)
  .concat(Utilities.newBlob("\r\n--xxxxxxxxxx--").getBytes());
const options = {
  method : "put",
  contentType : "multipart/form-data; boundary=xxxxxxxxxx",
  payload : payload,
  headers: {authorization : "Basic " + Utilities.base64Encode(API_SECRET_KEY)},
};
const res = UrlFetchApp.fetch(url, options);
console.log(res.getContentText())

var blob1 = Utilities.newBlob(binaryData, 'image/png', 'MyImageName');
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1');
sheet.insertImage(blob1, 1, 3);
  • 在我的环境中,我可以确认上述修改脚本的请求与curl命令的请求相同。
  • 在这种情况下,假设UrlFetchApp.fetch('Enter URL Here');返回PNG或JPEG图像的二进制数据。请注意这一点。

注意:

  • 请使用此脚本启用 V8 运行时。
  • 在这种情况下,data 中的换行符很重要。所以请注意这一点。
  • 当您的“API_SECRET_KEY”和 URL 不正确时,会发生错误。请注意这一点。
  • 从示例 curl 命令中,我建议将authorization : "Basic " + Utilities.base64Encode(API_SECRET_KEY) 作为授权标头。但如果API_SECRET_KEY"Basic " + Utilities.base64Encode(API_SECRET_KEY)相同,请尝试修改为authorization : "API_SECRET_KEY"

参考:

【讨论】:

  • 您好,谢谢您的回答,但有一个问题。当我尝试使用包含图像的谷歌驱动器链接时,它给出了这个异常:livestreamapis.com 的请求失败返回代码 400。截断服务器响应:{“code”:400,“message”:“命令失败:convert-im6 .q16: 未授权 `/tmp/uploadBeb5ea5532e2663e047ac3a813acb175' @error/constitute.c/ReadImage...(使用 muteHttpExceptions 选项检查完整响应)(第 30 行,文件“代码”)
  • @Ponnay 感谢您的回复。我带来的不便表示歉意。根据您的错误消息,认为错误的原因可能是由于授权和/或 URL。在我提出的答案中,请求与官方文档的示例 curl 命令相同。那么您能否再次确认您的授权参数。因为我无法测试这个。我为此道歉。顺便说一句,你能在你的问题中显示你当前的脚本吗?至此,它可能会想到问题。如果您能合作解决您的问题,我很高兴。
  • 嘿,我所做的只是在您分享的答案的第三行插入一个谷歌驱动器图像链接。我认为当我们执行 getContent() 时,数据来自谷歌驱动器的 text/html,这就是它给出上述错误的原因。
  • @Ponnay 感谢您的回复。我想确认一下您目前的情况。在您当前的错误中来自var binaryData = UrlFetchApp.fetch('Enter URL Here').getContent();?我的理解正确吗?从I am able to add images from url to the sheet,我认为UrlFetchApp.fetch('Enter URL Here') 可以正常工作。如果我的理解是正确的,你能提供示例网址吗?因为我无法理解Enter URL Here。对此我深表歉意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-25
相关资源
最近更新 更多