如何在使用Axios从附件获取ArrayBuffer后将图像作为文件发布

3
作为一个 POC,我希望能够拍摄我的收据图片(如加油、购物等),并使用聊天机器人将它们发送到我的会计软件。我的问题在于使用其 API 将收集的收据(图像)发送到会计软件。
第一步(获取附件)会生成一个包含图像的 Arraybuffer。我使用了 NodeJS 的示例之一(编号 15)来完成此操作。
    const attachment = turnContext.activity.attachments[0];
    const url = attachment.contentUrl;
    let image;
    axios.get(url, { responseType: 'arraybuffer' })
        .then((response) => {
            if (response.headers['content-type'] === 'application/json') {
                response.data = JSON.parse(response.data, (key, value) => {
                    return value && value.type === 'Buffer' ? Buffer.from(value.data) : value;
                });
            }
            image = response.data;
        }
        ).catch((error) => {
            console.log(error);
        });

我在第二部分遇到了困难。即将图像发布到会计软件中。

const requestConfig = {
        headers: {
            'Authorization': 'Bearer ' + accessToken,
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    };
    axios.post(postUrl, image, requestConfig)
        .then((response) => { console.log(response); }
        ).catch((error) => {
            console.log(error);
        });
};

这会导致400个错误请求。可能API需要一个文件,而我不能只发送缓冲区。我使用Postman进行测试,并且在本地存储图像文件的情况下,请求被接受,使用application/x-www-form-urlencoded 。如何最好地发布在缓冲区数组中检索到的图像?

当你说“将图像发布到会计软件”时,你指的是将图片发送到非BotFramework API吗?公共API可用吗?这应该可以给你一些关于所接受格式的线索。 - mdrichardson
@mdrichardson-MSFT 他们要求带有 content-type:multipart/mixed 的头文件。正文应包含一个文件。在 cURL 示例中,它指出:-F file=@/tmp/upload.pdf。我猜我需要找到一种将 arraybuffer 转换为文件并发送的方法。还没有想出来如何做。在 Facebook 渠道的情况下,将其暂时存储在文件系统上作为中间步骤可能很困难。 - Hessel
1个回答

2
我认为你的评论非常中肯,需要先将它转换成文件。频道并不是问题,因为文件将存储在机器人托管的位置。Attachments Sample实际上有这段代码,可以让你接近目标:
fs.writeFile(localFileName, response.data, (fsError) => {
    if (fsError) {
        throw fsError;
    }
    // Send the file
    const url = '<yourApiUrl>';
    const formData = new FormData();
    formData.append('file',fs.createReadStream('<pathToFile>'), { knownLength: fs.statSync('<pathToFile>').size });
    const config = {
        headers: {
            ...formData.getHeaders(),
            'Content-Length': formData.getLengthSync()
        }
    };
    axios.post(url, forData, { headers });
});

我对“// 发送文件”部分并不是非常有信心,因为我无法针对您的API进行测试。 我从这里获得了大部分代码。

早上好。您的解决方案在本地运行得很好。但是一旦在Azure上托管,就会出现问题。我为此创建了一个新的问题:https://stackoverflow.com/questions/58306146/internal-server-error-om-azure-when-writing-file-from-buffer-to-filesystem。如果您愿意,我真的很感谢您提供帮助。 - Hessel
@Hessel 今天早上我们将您的新问题分配给了另一位支持工程师,他有更多的时间来提供帮助。我不确定问题可能是什么,除非它不喜欢文件保存的位置——部署的机器人使用非常不同的目录结构。 - mdrichardson
谢谢。我添加了一些日志记录。应该不难重现。 - Hessel
1
仅对此代码片段进行评论,最后一行似乎有错误:
axios.post(url, forData, { headers });使用的变量似乎不正确,看起来应该是:
axios.post(url, formData, config)
- Allister Moon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接