来自Graph的base64转换的照片显示为残缺图像

时间:2018-09-12 10:45:41

标签: node.js microsoft-graph node-request

我已经绞尽脑汁(和其他人)试图使它起作用。我正在通过MS Graph API拉照片-这部分工作正常。我能够接收数据(以字节为单位)。但是,我无法将图像正确转换为文件附件并发布。

我阅读了关于SO和GH的几篇文章,并尝试了约10种不同的npm软件包和口味(出于绝望的目的,使用了btoa,atob等),包括Graph docs中的JS示例。没有解决方案。 npm软件包彼此产生不同的输出,当我拍照并上传到在线base64转换器时,它们都不匹配输出。另外,如果我进行在线转换并将输出字符串直接放入代码中,它将起作用。

这是我代码的当前迭代。任何帮助将不胜感激。

var optionsPhoto = {
  url: "https://graph.microsoft.com/v1.0/me/photo/$value",
  method: "GET",
  headers: {
    Authorization: "Bearer " + token
  }
};

await request(optionsPhoto, function callback(error, response, body) {
  if (!error && response.statusCode == 200) {
    photoResponse.data = [
      {
        "@odata.type": "#microsoft.graph.fileAttachment",
        contentBytes: body.split(",").toString("base64"),
        contentLocation: "https://graph.microsoft.com/v1.0/me/photo/$value",
        isinline: true,
        Name: "mypic.jpg"
      }
    ];
    photoResponse.ContentType = response.headers["content-type"].toString();
    photoResponse.Base64string = (
      "data:" +
      photoResponse.ContentType +
      ";base64," +
      photoResponse.data[0].contentBytes
    ).toString();
  } else {
    console.log(error);
  }
});

.sendActivity命令仅接受附件,如下所示:

await dc.context.sendActivity({
  attachments: [
    { contentType: photoResponse.ContentType, contentUrl: photoResponse.Base64string }
  ]
});

1 个答案:

答案 0 :(得分:3)

当您请求照片的/$value时,响应将只是图像的原始二进制文件。但是,request客户端默认情况下会将主体视为基于utf8的字符串。

为了重新训练原始二进制值,您需要明确告诉request您不希望这种情况发生。这是通过设置encoding: null完成的。从文档中:

  

encoding-在响应数据的setEncoding上使用的编码。如果为null,则返回body作为Buffer。其他任何(包括默认值undefined将作为encoding参数传递给toString()(这意味着默认情况下实际上为utf8 )。 (注意:如果需要二进制数据,则应设置encoding: null。)

代码看起来像这样:

var optionsPhoto = {
  url: "https://graph.microsoft.com/v1.0/me/photo/$value",
  encoding: null, // Tells request this is a binary response
  method: "GET",
  headers: {
    Authorization: "Bearer " + token
  }
};

await request(optionsPhoto, function callback(error, response, body) {
  if (!error && response.statusCode == 200) {
    // Grab the content-type header for the data URI
    const contentType = response.headers["content-type"];

    // Encode the raw body as a base64 string
    const base64Body = body.toString("base64");

    // Construct a Data URI for the image
    const base64DataUri = "data:" + contentType + ";base64," + base64Body;

    // Assign your values to the photoResponse object
    photoResponse.data = [
      {
        "@odata.type": "#microsoft.graph.fileAttachment",
        contentBytes: base64Body,
        contentLocation: optionsPhoto.url,
        isinline: true,
        Name: "mypic.jpg"
      }
    ];
    photoResponse.ContentType = contentType;
    photoResponse.Base64string = base64DataUri;
  } else {
    console.log(error);
  }
});