-
-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to create media attachment from Buffer #481
Comments
Hi, thanks again for the report.
This might be correct. I read the form-data doc again and realized that this is probably because we don't put c.f. https://github.com/form-data/form-data#buffer-getbuffer Also, sorry for the inconvenience of de-serializer / 400 error issues. I'd also like to fix the empty string problem and more understandable error message. |
I tried a raw Axios request with form-data as it is documented in the form data's README. However, I ended up with the same error as above, so this might be either a Mastodon's bug or form data's bug, I guess. const axios = require('axios');
const fs = require('fs');
const path = require('path');
const FormData = require('form-data')
const form = new FormData();
form.append(
'file',
fs.readFileSync(path.join(__dirname, './some_image.jpg')),
);
const media = await axios.post(
`https://mastodon.social/api/v2/media`,
form.getBuffer(),
{ headers: { ...form.getHeaders(), Authorization: `Bearer ${process.env.MASTODON_TOKEN}` } },
) I also thought converting the Buffer into a ReadableStream may help evade this issue but in this case, I got an error from the mastodon instance... I'll keep researching the solution Regarding the lacking of 400 information and unhandled |
Here's an update from #631 #626 . Even though I still could not figure out which component (including form-data, Axios, or Mastodon itself) was causing this bug, I tried out the Node.js-native implementation of Fetch API and everything worked OK. Node.js's fetch API has just been introduced at v18.X.X so I still have to maintain the Axios version for a while, but I'm going to drop the Axios version in the future. If you are still in trouble or want to try out the new version, you can install the Fetch API version with the following command:
And change your import to following - import { login } from 'masto';
+ import { login } from 'masto/fetch'; Additionally, since it's Fetch API, you need to convert the buffer to a blob. you can basically do that just by passing the buffer to the blob constructor. |
@neet thank you for the workaround! Is there a way to get typings when importing |
@eramdam You would need to change tsconfig.json as follows since the sub-package is served by a feature called package exports which was introduced in Node.js 16+. {
"compilerOptions": {
- "moduleResolution": "node",
+ "moduleResolution": "node16",
} Or if you want to stay in declare module 'masto/fetch' {
export * from 'masto';
} Update: @danielroe has added backward compatibility to the |
🎉 This issue has been resolved in version 5.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Hi. I was trying to investigate this. I am using this in NodeRed and have a picture in a binary buffer. Trying to send the picture gives an error ("Cannot process thumbnail creation). My conclusion is that current implementation does not send content type header. This is mandatory to upload a file to Mastodon server. This is the code that finally worked for me:
|
Hi @gmag11, thank you for sharing your tips. As of 5.0.0 (and 6.0.0 as well), we have dropped the support for Axios, replacing it with Node.js native Fetch API, so I believe now you can upload media regardless it is a file or a raw buffer input. The following code describes how to upload media created using npm canvas. import { Canvas } from "canvas";
function createCircle() {
const width = 100;
const height = 100;
const canvas = new Canvas(width, height);
const context = canvas.getContext("2d");
context.fillStyle = "red";
context.beginPath();
context.arc(width / 2, height / 2, width / 2, 0, 2 * Math.PI);
context.fill();
return canvas.toBuffer("image/png");
}
async function main() {
// 🚨 You need to wrap buffer by `Blob`
const file = new Blob([createCircle()]);
const media = await masto.v2.media.create({
file,
description: "Test upload",
});
await masto.v1.statuses.create({
status: "Hello, world!",
visibility: "private",
mediaIds: [media.id],
});
} Let me know if you still have a problem. |
Hi again, thanks for all your work on this library!
I seem to be getting odd errors when creating media attachments from a
Buffer
. This works:however, this:
fails with this output:
form-data
(and by extensionisomorphic-form-data
) should acceptBuffer
s, as noted in their readmes. The error seems like it might be in masto.js code?It's not a big deal for the above example (
createReadStream
is probably preferable to reading the whole file in from memory anyway) but for other cases (for example, creating image data in-memory usingnode-canvas
or similar) it's a bit inconvenient to have to write a file to a temporary location and then read it back rather than using aBuffer
directly.Edit: looked into this a bit -- it seems like the deserializer is trying to
JSON.parse
an empty string (length === 0
). If I make the deserializer return an empty object in this case, I get this output instead:If I add logging here, I can finally see that this is a status code 400. (It might be nice to add the status code to the
default
case and the request URL too, it's kinda confusing without it and makes it seem like an internal error...)I'm still not sure why using a
Buffer
isn't working here, but I'll keep investigating.The text was updated successfully, but these errors were encountered: