fix(telegram): allow URL strings in advanced mode media inputs#3572
fix(telegram): allow URL strings in advanced mode media inputs#3572guoyangzhen wants to merge 1 commit intosimstudioai:mainfrom
Conversation
normalizeFileInput only handles file objects, not plain URL strings. Check for string input first before file normalization. Fixes simstudioai#3220
PR SummaryLow Risk Overview Written by Cursor Bugbot for commit affeebf. This will update automatically on new commits. Configure here. |
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Greptile SummaryThis PR fixes a bug where Telegram media blocks ( The fix adds a Key changes:
Minor concern:
Confidence Score: 4/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Block params resolved] --> B{operation?}
B -->|send_photo / video / audio / animation| C{param is non-empty string?}
C -->|Yes - NEW path| D[Pass string directly as URL or file_id]
C -->|No| E[normalizeFileInput]
E --> F{result defined?}
F -->|No| G[throw Media is required]
F -->|Yes - file object| H[Pass file object]
D --> I[Return commonParams + media + caption]
H --> I
B -->|send_document| J[normalizeFileInput params.files]
J --> K[Return commonParams + files + caption]
I --> L[Telegram Bot API JSON call]
K --> M[Internal multipart upload route]
Last reviewed commit: affeebf |
| if (typeof params.photo === 'string' && params.photo.trim()) { | ||
| return { | ||
| ...commonParams, | ||
| photo: params.photo.trim(), | ||
| caption: params.caption, | ||
| } | ||
| } |
There was a problem hiding this comment.
JSON-serialized file object strings bypassed prematurely
The check typeof params.photo === 'string' && params.photo.trim() intercepts any non-empty string — including a JSON-serialized file object that template resolution might produce when a user references a file-typed block output (e.g. <uploadBlock.result.file> resolves to '{"name":"photo.jpg","url":"blob:..."}').
In that case the raw JSON string gets forwarded to the Telegram API as the photo value, which Telegram will reject as an invalid URL or file_id.
A slightly more defensive guard tries to parse the string first and only short-circuits when the result is still a string (or parsing fails):
| if (typeof params.photo === 'string' && params.photo.trim()) { | |
| return { | |
| ...commonParams, | |
| photo: params.photo.trim(), | |
| caption: params.caption, | |
| } | |
| } | |
| // In advanced mode, photo can be a plain URL string or file_id. | |
| // Only bypass normalizeFileInput when the value is *not* a JSON-encoded object/array. | |
| if (typeof params.photo === 'string' && params.photo.trim()) { | |
| let directValue: string | null = null | |
| try { | |
| const parsed = JSON.parse(params.photo) | |
| // A JSON-encoded string is still a valid passthrough (e.g. `"https://..."`) | |
| if (typeof parsed === 'string') directValue = parsed | |
| } catch { | |
| // Not valid JSON → plain URL or file_id | |
| directValue = params.photo.trim() | |
| } | |
| if (directValue) { | |
| return { | |
| ...commonParams, | |
| photo: directValue, | |
| caption: params.caption, | |
| } | |
| } | |
| } |
The same pattern applies to the video, audio, and animation cases below. Note that even without this change both paths would ultimately fail for a file-object reference (since the Telegram API only accepts string identifiers), but the refined guard makes the intent explicit and avoids silently forwarding malformed values.
Problem
When using Telegram Send Photo/Video/Audio/Animation blocks in advanced mode with a URL string (e.g., from
<Block.result.photo>), the block throws "Photo is required." even though a valid URL is passed.The internal validation layer never reaches the Telegram API.
Root Cause
normalizeFileInput()is designed for file objects from the upload UI. When given a plain URL string, it tries toJSON.parse()it, fails, returnsundefined, and the validation throws.Fix
Check if the parameter is a plain string (URL or file_id) before attempting file normalization. If it is, pass it through directly.
Applies to all 4 media operations:
telegram_send_phototelegram_send_videotelegram_send_audiotelegram_send_animationTesting
{ photo: "https://example.com/image.jpg" }<function.result.photo>Closes #3220