Televerseteleverse.

Sending & Receiving Files

Master file handling in your Telegram bot with Televerse.

Working with files is a fundamental part of building Telegram bots. Whether you're sending photos, videos, documents, or receiving files from users, Televerse makes this process straightforward with the InputFile class and context-aware methods.

Telegram File Upload Principles

According to the Telegram Bot API, there are three main ways to send files:

  1. File ID: If the file is already stored on Telegram's servers, use its file_id. No size limit when using this method.
  2. URL: Provide a publicly accessible URL. Telegram downloads and sends it for you. Size limit: 5 MB for photos, 20 MB for other types.
  3. Upload (multipart/form-data): Upload a local file directly. Size limit: 10 MB for photos, 50 MB for other types.

The InputFile Class

The InputFile class is your gateway to sending files with Televerse. It supports all three upload methods through dedicated constructors.

Constructors

  • InputFile.fromFileId - Use a file already on Telegram servers
  • InputFile.fromUrl - Send a file from a URL
  • InputFile.fromFile - Upload a local File object
  • InputFile.fromBytes - Upload raw bytes with a name
input_file_examples.dart
import 'package:televerse/televerse.dart';
import 'dart:io';

// From a file ID (already on Telegram servers)
final photo = InputFile.fromFileId('AgACAgUAAxkBAAIvAWbUio...QADNQQ');

// From a URL
final photo = InputFile.fromUrl('https://example.com/photo.jpg');

// From a local file
final file = File('assets/photo.jpg');
final photo = InputFile.fromFile(file);

// From bytes
final bytes = file.readAsBytesSync();
final photo = InputFile.fromBytes(bytes, name: 'photo.jpg');

Note: A file_id is unique to your bot. The same file can have different IDs across bots. While you can sometimes use file IDs from other bots, it's not guaranteed to work.

Sending Files

Once you have an InputFile, you can send it using Context methods. Televerse provides convenient reply methods for all file types.

Sending Photos

send_photo.dart
bot.command('photo', (ctx) async {
  // Using a file ID
  final photo = InputFile.fromFileId('AgACAgUAAxkBAAIvAWbUio...QADNQQ');
  await ctx.replyWithPhoto(photo);
  
  // Using a URL
  final urlPhoto = InputFile.fromUrl(
    'https://televerse.weaverlabs.ca/assets/lockup-with-bg.png',
  );
  await ctx.replyWithPhoto(urlPhoto, caption: 'From URL! 🌐');
  
  // Using a local file
  final localPhoto = InputFile.fromFile(File('assets/sunset.jpg'));
  await ctx.replyWithPhoto(
    localPhoto,
    caption: 'Beautiful sunset! 🌅',
    parseMode: ParseMode.markdown,
  );
});

Sending Documents

Documents are perfect for PDFs, spreadsheets, or any general file type.

send_document.dart
bot.command('document', (ctx) async {
  final document = InputFile.fromFile(File('reports/monthly.pdf'));
  
  await ctx.replyWithDocument(
    document,
    caption: 'Monthly Report - January 2024',
  );
});

Sending Videos

Send video files with optional thumbnails and streaming support.

send_video.dart
bot.command('video', (ctx) async {
  final video = InputFile.fromFile(File('videos/demo.mp4'));
  
  await ctx.replyWithVideo(
    video,
    caption: 'Check out this demo! 🎥',
    supportsStreaming: true,
    thumbnail: InputFile.fromFile(File('thumbnails/demo-thumb.jpg')),
  );
});

Sending Audio

Audio files support metadata like performer, title, and duration.

send_audio.dart
bot.command('audio', (ctx) async {
  final audio = InputFile.fromFile(File('music/song.mp3'));
  
  await ctx.replyWithAudio(
    audio,
    caption: 'Enjoy this track! 🎵',
    performer: 'Artist Name',
    title: 'Song Title',
    duration: 180, // 3 minutes
  );
});

Media Groups (Albums)

Send 2-10 photos or videos as an album using replyWithMediaGroup.

media_group.dart
bot.command('album', (ctx) async {
  final media = [
    InputMediaPhoto(media: InputFile.fromFile(File('photos/1.jpg'))),
    InputMediaPhoto(
      media: InputFile.fromFile(File('photos/2.jpg')),
      caption: 'Photo 2 with caption',
    ),
    InputMediaPhoto(media: InputFile.fromFile(File('photos/3.jpg'))),
  ];
  
  await ctx.replyWithMediaGroup(media);
});

Voice Messages & Video Notes

Telegram supports special file types for voice messages and rounded video notes.

voice_and_notes.dart
// Sending voice messages
bot.command('voice', (ctx) async {
  final voice = InputFile.fromFile(File('voice/greeting.ogg'));
  await ctx.replyWithVoice(voice, duration: 5);
});

// Sending video notes (rounded videos)
bot.command('videonote', (ctx) async {
  final videoNote = InputFile.fromFile(File('notes/message.mp4'));
  await ctx.replyWithVideoNote(
    videoNote,
    duration: 10,
  );
});

Receiving Files

When users send files to your bot, you can access file information and download files easily.

Getting File Information

Use the getMessageFile() context method to retrieve file metadata. This method automatically detects the file type (photo, document, video, etc.) and returns the File object.

receive_file.dart
bot.on(bot.filters.photo, (ctx) async {
  // Get the file information
  final file = await ctx.getMessageFile();
  
  if (file != null) {
    print('File ID: ${file.fileId}');
    print('File size: ${file.fileSize} bytes');
    print('File path: ${file.filePath}');
  }
});

The getMessageFile() method works with:

  • Photos (returns the largest size)
  • Documents
  • Audio files
  • Videos
  • Animations (GIFs)
  • Voice messages
  • Video notes
  • Stickers

Downloading Files

Once you have the File object, you can download it to your server for processing.

download_file.dart
bot.on(bot.filters.document, (ctx) async {
  await ctx.reply('Processing your document...');
  
  // Get the file information
  final file = await ctx.getMessageFile();
  
  if (file != null) {
    // Get the download URL
    final url = file.getDownloadUrl(bot.token);
    
    // Or download the file directly
    final io.File downloaded = await file.download(token: bot.token);
    
    // Process the file
    print('Downloaded to: ${downloaded.path}');
    
    // You can now read, analyze, or transform the file
    final bytes = await downloaded.readAsBytes();
    print('File size: ${bytes.length} bytes');
    
    await ctx.reply('Document processed successfully! ✅');
  }
});

Important: Download links expire after 1 hour. If you need a fresh link, call getMessageFile() or api.getFile() again.

Practical Example: Video Handler

Here's a complete example that receives a video and provides a download button:

video_handler.dart
bot.on(bot.filters.video, (ctx) async {
  await ctx.reply('Got it!');
  
  final video = ctx.msg!.video!;
  print('Video dimensions: ${video.width}x${video.height}');
  print('Duration: ${video.duration} seconds');
  
  // Get the file for downloading
  final file = await ctx.getMessageFile();
  
  if (file != null) {
    // Create a download button
    final url = file.getDownloadUrl(bot.token);
    await ctx.reply(
      'Tap the button to download the video.',
      replyMarkup: InlineKeyboard().addUrl('Download Now', url),
    );
  }
});

Using the Raw API

If you're not working within a context (e.g., scheduled tasks), you can use the Raw API directly:

raw_api_files.dart
// Send a photo
await bot.api.sendPhoto(
  ChatID(123456789),
  InputFile.fromFile(File('photo.jpg')),
  caption: 'Direct API call',
);

// Get file information by file ID
final file = await bot.api.getFile('AgACAgUAAxkBAAIvAWbUio...QADNQQ');
final downloaded = await file.download(token: bot.token);

See Also

  • Context- Learn about context-aware reply methods
  • Raw API- Direct API access for file operations