Skip to content

Commit 13510d7

Browse files
MaxwellCalkinclaude
andcommitted
fix: pass URL strings and file_ids through to Telegram media API
The telegram_send_photo, telegram_send_video, telegram_send_audio, and telegram_send_animation blocks always routed media params through normalizeFileInput(), which JSON.parse's string inputs and returns undefined when parsing fails. This caused plain URL strings and Telegram file_id strings (both valid per the Telegram Bot API) to be silently dropped, resulting in "Photo is required." even when a valid URL was provided. Extract a resolveTelegramMedia() helper that passes plain strings through directly and only delegates to normalizeFileInput when the value is a serialized JSON object/array or a non-string value. Fixes #3220 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8c0a2e0 commit 13510d7

File tree

1 file changed

+25
-16
lines changed

1 file changed

+25
-16
lines changed

apps/sim/blocks/blocks/telegram.ts

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,27 @@ import { normalizeFileInput } from '@/blocks/utils'
55
import type { TelegramResponse } from '@/tools/telegram/types'
66
import { getTrigger } from '@/triggers'
77

8+
/**
9+
* Resolves a Telegram media parameter to a value suitable for the Telegram API.
10+
* Telegram accepts plain URL strings and file_id strings directly, but
11+
* normalizeFileInput drops plain strings that aren't valid JSON. This helper
12+
* passes plain strings through and delegates to normalizeFileInput only when
13+
* the value looks like a serialized file object (JSON) or is already an object.
14+
*/
15+
function resolveTelegramMedia(param: unknown): string | object | undefined {
16+
if (typeof param === 'string') {
17+
const trimmed = param.trim()
18+
if (!trimmed) return undefined
19+
// If the string looks like serialized JSON (object or array), let normalizeFileInput parse it
20+
if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
21+
return normalizeFileInput(param, { single: true })
22+
}
23+
// Plain URL or file_id — pass through directly
24+
return trimmed
25+
}
26+
return normalizeFileInput(param, { single: true })
27+
}
28+
829
export const TelegramBlock: BlockConfig<TelegramResponse> = {
930
type: 'telegram',
1031
name: 'Telegram',
@@ -269,10 +290,7 @@ export const TelegramBlock: BlockConfig<TelegramResponse> = {
269290
messageId: params.messageId,
270291
}
271292
case 'telegram_send_photo': {
272-
// photo is the canonical param for both basic (photoFile) and advanced modes
273-
const photoSource = normalizeFileInput(params.photo, {
274-
single: true,
275-
})
293+
const photoSource = resolveTelegramMedia(params.photo)
276294
if (!photoSource) {
277295
throw new Error('Photo is required.')
278296
}
@@ -283,10 +301,7 @@ export const TelegramBlock: BlockConfig<TelegramResponse> = {
283301
}
284302
}
285303
case 'telegram_send_video': {
286-
// video is the canonical param for both basic (videoFile) and advanced modes
287-
const videoSource = normalizeFileInput(params.video, {
288-
single: true,
289-
})
304+
const videoSource = resolveTelegramMedia(params.video)
290305
if (!videoSource) {
291306
throw new Error('Video is required.')
292307
}
@@ -297,10 +312,7 @@ export const TelegramBlock: BlockConfig<TelegramResponse> = {
297312
}
298313
}
299314
case 'telegram_send_audio': {
300-
// audio is the canonical param for both basic (audioFile) and advanced modes
301-
const audioSource = normalizeFileInput(params.audio, {
302-
single: true,
303-
})
315+
const audioSource = resolveTelegramMedia(params.audio)
304316
if (!audioSource) {
305317
throw new Error('Audio is required.')
306318
}
@@ -311,10 +323,7 @@ export const TelegramBlock: BlockConfig<TelegramResponse> = {
311323
}
312324
}
313325
case 'telegram_send_animation': {
314-
// animation is the canonical param for both basic (animationFile) and advanced modes
315-
const animationSource = normalizeFileInput(params.animation, {
316-
single: true,
317-
})
326+
const animationSource = resolveTelegramMedia(params.animation)
318327
if (!animationSource) {
319328
throw new Error('Animation is required.')
320329
}

0 commit comments

Comments
 (0)