I got a problem, when I use telegram to upload an image file and want to pass to openrouter google/gemini-2.5-flash to analysis. Telegram Get file node works fine, I use edit field to trim out hidden ‘/n’, Edit node also works fine.
However, when I pass this input (from edit node) to Http node , which point to Openrouter and I prepared a send body in JSON form. It keeps throw me an error (Bad request).
Here is my JSON.
{
“model”: “google/gemini-2.5-flash”,
“messages”: [
{
“role”: “user”,
“content”: [
{
“type”: “text”,
“text”: “Please analyze this JPG image in detail, pointing out the construction progress and potential safety hazards.”
},
{
“type”: “image_url”,
“image_url”: {
“url”: “data:image/jpeg;base64,{{ $json.base64String }}”
}
}
]
}
]
}
Your Edit Fields node is pulling $json.result.file_id into base64String but that’s just the Telegram file identifier, not the actual image data. You need to convert the binary output from the Get File node to base64, something like {{ $binary.data.data }} or use a Code node with $input.first().binary.data.data to grab the real base64 content.
Your Edit Fields node is grabbing result.file_id which is just a Telegram identifier string, not the actual image data. You need to convert the binary file data to base64 instead, try using {{ $binary.data.data }} or a Convert to File node to get the real base64 content from the downloaded image.
Your Edit Fields node is pulling $json.result.file_id into the base64String field, that’s just the Telegram file ID not the actual image data. You need to convert the binary file content to base64 first, try using a Code node with $input.first().binary.data.data to get the actual base64 string and pass that to OpenRouter instead.
I try to base on your suggest, prepared a javascript to convert the image (from telegram ) to base64string, then connect the Code node to the Http node (open router) , but bad parameter error still throw out. . Do you have any ideas ?
// Get all input data using $input.all()
const items = $input.all();
// Iterate through all items and process binary data
for (let i = 0; i < items.length; i++) {
// Check if binary data exists in the item, default name is ‘data’
if (items[i].binary && items[i].binary.data) {
// Get the binary data content
const binaryData = items[i].binary.data;
// Convert binary content to a Base64 string
// Remove potential line breaks to ensure OpenRouter API can read it
const base64String = Buffer.from(binaryData.data, 'base64').toString('base64').replace(/\n/g, "");
// Store the generated Base64 string into the JSON field of the item
items[i].json.base64String = base64String;
Delete the Code node Connect your “Telegram (Get a file)” node directly to your “HTTP Request” node. The fewer nodes you have, the fewer places things can break!
then Update your HTTP Request JSON We are going to use n8n’s native expressions to pull the base64 data and the image type directly from the Telegram node. This ensures that whether someone uploads a JPG or a PNG, the API knows exactly what it is.
Copy and paste this exact JSON into your HTTP Request node’s “Send Body”:
{
"model": "google/gemini-2.5-flash",
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "Please analyze this JPG image in detail, pointing out the construction progress and potential safety hazards."
},
{
"type": "image_url",
"image_url": {
"url": "data:{{ $binary.data.mimeType }};base64,{{ $binary.data.data }}"
}
}
]
}
]
}
Notice the "url" line. Instead of hardcoding image/jpeg or relying on a Code node, we let n8n dynamically fill in the MIME type ({{ $binary.data.mimeType }}) and the clean base64 string ({{ $binary.data.data }}).
Delete that Code node, pop this JSON in, and give it a test run
if you look at the left panel in your screenshot, the telegram node only returned json metadata like file_path and file_id. it didn’t actually download the image itself. without a file, your $binary.data.data expression is completely empty, which sends a broken url string to openrouter and blocks the request.
just open that telegram node and change the operation from “Get” to “Download”.