Skip to content

fix(telegram): allow URL strings in advanced mode media inputs#3572

Open
guoyangzhen wants to merge 1 commit intosimstudioai:mainfrom
guoyangzhen:fix/telegram-url-input-validation
Open

fix(telegram): allow URL strings in advanced mode media inputs#3572
guoyangzhen wants to merge 1 commit intosimstudioai:mainfrom
guoyangzhen:fix/telegram-url-input-validation

Conversation

@guoyangzhen
Copy link

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 to JSON.parse() it, fails, returns undefined, 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_photo
  • telegram_send_video
  • telegram_send_audio
  • telegram_send_animation

Testing

  1. Create workflow with Function block returning { photo: "https://example.com/image.jpg" }
  2. Add Telegram Send Photo in advanced mode: <function.result.photo>
  3. Run workflow → should send successfully

Closes #3220

normalizeFileInput only handles file objects, not plain URL strings.
Check for string input first before file normalization.

Fixes simstudioai#3220
@cursor
Copy link

cursor bot commented Mar 14, 2026

PR Summary

Low Risk
Low risk: small validation/param-shaping change confined to Telegram media send operations, mainly broadening accepted input types without altering auth or storage.

Overview
Fixes Telegram media blocks in advanced mode to accept plain string inputs (URL or file_id) for photo, video, audio, and animation before running normalizeFileInput(), preventing false " is required" validation errors and passing the string through to the Telegram API.

Written by Cursor Bugbot for commit affeebf. This will update automatically on new commits. Configure here.

@vercel
Copy link

vercel bot commented Mar 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Mar 14, 2026 8:49am

Request Review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 14, 2026

Greptile Summary

This PR fixes a bug where Telegram media blocks (send_photo, send_video, send_audio, send_animation) in advanced mode threw a "Media is required" validation error when passed a plain URL string or file_id (e.g. from a previous block's output). The root cause was that normalizeFileInput tries to JSON.parse any string input, fails for plain URLs, and returns undefined, causing the validation guard to fire before the Telegram API is even reached.

The fix adds a typeof param === 'string' short-circuit before the normalizeFileInput call in all four affected operations, passing the trimmed string directly to the tool when it is non-empty.

Key changes:

  • Four identical string-bypass guards added to telegram_send_photo, telegram_send_video, telegram_send_audio, and telegram_send_animation branches in telegram.ts.
  • telegram_send_document is intentionally left unchanged — documents are routed through a separate multipart-upload API route and do not support URL/file_id pass-through in the same way.

Minor concern:

  • The typeof === 'string' guard intercepts all non-empty strings, including JSON-serialized file-object references (e.g. '{"name":"photo.jpg","url":"blob:..."}') that template resolution may produce. These would be forwarded as-is to the Telegram API, which rejects them. Before this fix both paths ultimately failed for that scenario, so this is not a regression in practice, but a more defensive check (attempting JSON.parse first and only short-circuiting when the result is still a string) would make the intent clearer and guard against edge-cases.

Confidence Score: 4/5

  • Safe to merge — the fix is minimal, targeted, and correctly resolves the reported bug with no regressions for the primary usage patterns.
  • The change is a single-file, four-location fix using a well-understood type guard. The primary bug (URL strings failing validation) is definitively resolved. The one edge case worth noting — JSON-serialized file-object strings being intercepted by the new guard — was already broken before this PR and has no practical impact, since the Telegram API only accepts string URLs or file_ids regardless. No tests were added, but the logic is straightforward and manually verifiable against the PR's test steps.
  • No files require special attention beyond the inline comment on apps/sim/blocks/blocks/telegram.ts.

Important Files Changed

Filename Overview
apps/sim/blocks/blocks/telegram.ts Adds a string guard before each normalizeFileInput call in the four media-send operations so that plain URL / file_id strings are passed through directly. Logic is correct for the primary bug; one minor style concern around JSON-serialized object strings being intercepted prematurely (see inline comment).

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]
Loading

Last reviewed commit: affeebf

Comment on lines +274 to +280
if (typeof params.photo === 'string' && params.photo.trim()) {
return {
...commonParams,
photo: params.photo.trim(),
caption: params.caption,
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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):

Suggested change
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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] (Telegram) telegram_send_photo block rejects valid photo URL withPhoto is required. — error thrown internally before reaching Telegram API

1 participant