mtproto-core
mtproto-core copied to clipboard
API messages.sendMultiMedia Always Fails (400 MEDIA_INVALID) for valid media
I have been trying to get this particular api method to work (https://core.telegram.org/method/messages.sendMultiMedia).
I have provided sample code below that I am using to test this behavior. It shouldn't be an issue of the actual file being invalid as if you attempt to send the media using https://core.telegram.org/method/messages.sendMedia it works just fine.
It appears to be a bug, but I don't know enough about the protocol implementation to be able to fix it myself.
const { MTProto } = require("@mtproto/core");
const readline = require("readline");
const fs = require("fs");
const api_id = "<app id>";
const api_hash = "<app hash>";
const phone_number = "<phone>";
const file = fs.readFileSync("test.jpg"); // assumes under 512kb
// 1. Create an instance
const mtproto = new MTProto({
api_id,
api_hash,
});
async function auth() {
const send = await mtproto.call("auth.sendCode", {
phone_number,
settings: {
_: "codeSettings",
},
});
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const code = await new Promise((resolve) => {
rl.question("Code: ", (answer) => {
rl.close();
resolve(answer);
});
});
const authed = await mtproto.call("auth.signIn", {
phone_code: code,
phone_number,
phone_code_hash: send.phone_code_hash,
});
console.log(authed);
}
async function getChats() {
return await mtproto
.call("messages.getAllChats", {
except_ids: [],
})
.then(({ chats }) => chats);
}
function wait() {
return new Promise((resolve) => {
setTimeout(resolve, 2000);
});
}
async function upload(file) {
const id = Date.now();
await mtproto.call("upload.saveFilePart", {
file_id: id,
file_part: 0,
bytes: file,
});
return id;
}
// This does all the stuff
async function run() {
mtproto.setDefaultDc(
await mtproto.call("help.getNearestDc").then((result) => {
return result.nearest_dc;
})
);
let chats;
try {
chats = await getChats();
} catch {
await auth();
chats = await getChats();
}
const chat = chats[0];
await wait();
const upl = await upload(file);
await wait();
// I AM BROKEN
const res = await mtproto
.call("messages.sendMultiMedia", {
peer: {
_: "inputPeerChannel",
channel_id: chat.id,
access_hash: chat.access_hash,
},
multi_media: [
{
_: "inputSingleMedia",
random_id: Date.now(),
// message: "Hello, World!",
media: {
_: "inputMediaUploadedPhoto",
file: {
_: "inputFile",
id: upl,
name: "test.jpg",
parts: 1,
},
},
},
],
})
.catch((err) => err);
// UNCOMMENT ME TO SEE THAT messages.sendMedia works correctly.
// const res = await mtproto
// .call("messages.sendMedia", {
// random_id: Date.now(),
// peer: {
// _: "inputPeerChannel",
// channel_id: chat.id,
// access_hash: chat.access_hash,
// },
// message: "Hello, World",
// media: {
// _: "inputMediaUploadedPhoto",
// file: {
// _: "inputFile",
// id: upl,
// name: "test.jpg",
// parts: 1,
// },
// },
// })
// .catch((err) => err);
console.log(res);
}
run()
.catch(console.error)
.finally(() => process.exit(0));
process.on("unhandledRejection", console.error);
https://stackoverflow.com/questions/65628877/in-nodejs-telegram-api-messages-sendmultimedia-method-is-not-working
I have the same question. Have you solved your problem
@alik0211
@mvdicarlo Have you solved your problem? I need help
No. I just accepted the less preferable way of sending individually for now. Wasn't able to tell if this was a limitation of the library or some limitation of the Telegram API.
I don't know enough about the protocol to debug it myself
I tried everything,This is very frustrating,The author doesn't have any explanation
2021年5月18日 下午8:34,Lemonynade @.***> 写道:
No. I just accepted the less preferable way of sending individually for now. Wasn't able to tell if this was a limitation of the library or some limitation of the Telegram API.
I don't know enough about the protocol to debug it myself
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/alik0211/mtproto-core/issues/148#issuecomment-843132377, or unsubscribe https://github.com/notifications/unsubscribe-auth/ARDPXOTYCPI5TUMXMWXJMELTOJNDXANCNFSM4WPAAHKA.
Any update on this issue? I try all kinds of ways but still the response is "400 MEDIA_INVALID"
This is just fuck this is so stupid, why python has everything while js developers has to deal with dead library with "call" method that pretty much don't do anything, what the actual fuck why just why
I'm going to try to patch this error. It seems that problem is at src/tl/builder/index.js:7159
'messages.sendMultiMedia': function(params) {
this.int32(-134016113);
const flags = (this.has(params.silent) << 5) | (this.has(params.background) << 6) | (this.has(params.clear_draft) << 7) | (this.has(params.noforwards) << 14) | (this.has(params.reply_to_msg_id) << 0) | (this.has(params.schedule_date) << 10) | (this.has(params.send_as) << 13);
this.int32(flags);
this.predicate(params.peer);
this.flag(this.int, params.reply_to_msg_id);
this.vector(this.predicate, params.multi_media);
this.flag(this.int, params.schedule_date);
this.flag(this.predicate, params.send_as);
},
you may use uploadMedia to upload each photo
...
...
// step 1 ,upload the file
const chat = chats[0];
await wait();
const upl_id = await upload(file);
await wait();
// step2, uploadMedia
const upl_media = await mtproto('messages.uploadMedia', {
peer: target_peer,
media: {
"_": "inputMediaUploadedPhoto",
"file": {
"_": "inputFile",
"id": upl_id,
"parts": 1,
"name": 'upload.png',
"md5_checksum": ""
},
"mime_type": "image/png",
"attributes": [{
"_": "documentAttributeFilename",
"file_name": 'upload.png'
}]
}
})
// step 3 send multi media
const res = await mtproto
.call("messages.sendMultiMedia", {
peer: {
_: "inputPeerChannel",
channel_id: chat.id,
access_hash: chat.access_hash,
},
multi_media: [{
"_": "inputSingleMedia",
"random_id": this.createSendMessageId(),
"message": text,
"entities": entities,
"media": {
"_": "inputMediaPhoto",
"id": {
"_": 'inputPhoto',
"id": upl_media.photo.id,
"access_hash": upl_media.photo.access_hash,
"file_reference": upl_media.photo.file_reference
}
}
}, {
"_": "inputSingleMedia",
"random_id": this.createSendMessageId(),
"media": {
"_": "inputMediaPhoto",
"id": {
"_": 'inputPhoto',
"id": upl_media.photo.id,
"access_hash": upl_media.photo.access_hash,
"file_reference": upl_media.photo.file_reference
}
}
}],
})
.catch((err) => err);
=========================================================================================== the code is work for me.