telegram

package
v0.15.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 16, 2026 License: MIT Imports: 16 Imported by: 0

README

FTPServer Telegram connector

Stand With Ukraine

Register bot

Read about telegram bots at https://core.telegram.org/bots/tutorial.

Bots are not allowed to contact users. You need to make the first contact from the user for which you want to set up the bot.

Quick start

  • Create a bot with @BotFather, let's say with username my_ftp_bot
  • Get bot token from BotFather's response, use it as Token in config
  • Get bot id by run curl https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getMe
  • Find @my_ftp_bot in telegram and start chat with it
  • Send /start to bot
  • Run curl https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates and find your chat id in response, use it as ChatID in config

Config example

Please note about shared flag. If it's true then bot instance will be shared between all connections. If it's false then each user (or even each ftp connection) will have own bot instance and it can lead to telegram bot flood protection.

MaxPartSize (optional) sets the maximum size in bytes for each part when uploading large files. Files exceeding this size are automatically split into multiple parts. Default is 51380224 (49 MB). Telegram's upload limit is 50 MB.

TempDir (optional) sets the directory used to store temporary multipart chunks before upload. If omitted, the system temp directory is used.

RetryAttempts (optional) sets the number of retry attempts for transient Telegram errors (e.g. rate-limit, timeout). Default is 10.

RetryDelay (optional) sets the delay in milliseconds between retry attempts. Default is 2000 (2 seconds).

PartUploadDelay (optional) sets the delay in milliseconds between uploading consecutive parts, to help avoid Telegram rate-limit errors. Default is 500.

{
  "version": 1,
  "accesses": [
    {
      "fs": "telegram",
      "shared": true,
      "user": "my_ftp_bot",
      "pass": "my_secure_password",
      "params": {
        "Token": "<YOUR_BOT_TOKEN>",
        "ChatID": "<YOUR_CHAT_ID>",
        "MaxPartSize": "51380224",
        "TempDir": "/tmp",
        "RetryAttempts": "10",
        "RetryDelay": "2000",
        "PartUploadDelay": "500"
      }

    }
  ],
  "passive_transfer_port_range": {
    "start": 2122,
    "end": 2130
  }
}

Reassembling multipart files

When a file exceeds MaxPartSize, it is uploaded as numbered parts (filename.part1ofN, filename.part2ofN, …). Download all parts into the same directory, then reassemble them with one of the commands below.

Linux / macOS

# Reassemble every *.tar.gz split in the current directory
for base in $(ls *.part1of* | sed 's/\.part1of.*//'); do
  ls "${base}.part"*of* | sort -t'f' -k2 -n | xargs cat > "${base}"
  echo "Reassembled: ${base}"
done

Windows (PowerShell)

# Reassemble every *.tar.gz split in the current directory
Get-ChildItem '*.part1of*' | ForEach-Object {
  $base = $_.Name -replace '\.part1of.*', ''
  $out  = $base
  Get-ChildItem "${base}.part*of*" |
    Sort-Object { [int]($_.Name -replace '.*\.part(\d+)of.*','$1') } |
    ForEach-Object { Get-Content $_.FullName -AsByteStream } |
    Set-Content -AsByteStream $out
  Write-Host "Reassembled: $out"
}

Documentation

Overview

Package telegram provides a telegram access layer

Index

Constants

This section is empty.

Variables

View Source
var ErrInvalidParameter = errors.New("invalid parameter")

ErrInvalidParameter is returned when a parameter is invalid

View Source
var ErrNotFound = errors.New("not found")

ErrNotFound is returned when something is not found

View Source
var ErrNotImplemented = errors.New("not implemented")

ErrNotImplemented is returned when something is not implemented

Functions

func LoadFs

func LoadFs(access *confpar.Access, logger *slog.Logger) (afero.Fs, error)

LoadFs loads a file system from an access description

Types

type File

type File struct {
	// Path is the file path
	Path string
	// Content is the file content
	Content []byte
	// PartNumber is the uploaded part counter for multipart uploads
	PartNumber int
	// PartTempFiles stores temporary part file paths before final upload
	PartTempFiles []string
	// PartTempDir stores the temporary directory used for multipart spool
	PartTempDir string
	// TotalWritten stores total bytes written across the transfer
	TotalWritten int64
	// Fs is the parent Fs
	Fs *Fs
	// At is the current position in the file
	At int64
}

File is the afero.File implementation

func (*File) Close

func (f *File) Close() error

Close closes the file transfer and does the actual transfer to telegram. If the file is larger than maxPartSize, it will be split into multiple parts.

func (*File) Name

func (f *File) Name() string

Name of the file

func (*File) Read

func (f *File) Read(b []byte) (int, error)

Read stores the received file content into the local buffer

func (*File) ReadAt

func (f *File) ReadAt(_ []byte, _ int64) (int, error)

ReadAt is not implemented

func (*File) Readdir

func (f *File) Readdir(_ int) ([]os.FileInfo, error)

Readdir is not implemented

func (*File) Readdirnames

func (f *File) Readdirnames(_ int) ([]string, error)

Readdirnames is not implemented

func (*File) Seek

func (f *File) Seek(_ int64, _ int) (int64, error)

Seek is not implemented

func (*File) Stat

func (f *File) Stat() (os.FileInfo, error)

Stat for the file relies on the fake filesystem

func (*File) Sync

func (f *File) Sync() error

Sync is not implemented

func (*File) Truncate

func (f *File) Truncate(_ int64) error

Truncate is not implemented

func (*File) Write

func (f *File) Write(b []byte) (int, error)

func (*File) WriteAt

func (f *File) WriteAt(b []byte, off int64) (int, error)

WriteAt is not implemented

func (*File) WriteString

func (f *File) WriteString(s string) (int, error)

WriteString is not implemented

type FileData

type FileData struct {
	// contains filtered or unexported fields
}

FileData is a simple structure to store file information and implement os.FileInfo interface

type FileInfo

type FileInfo struct {
	*FileData
}

func (*FileInfo) IsDir

func (s *FileInfo) IsDir() bool

func (*FileInfo) ModTime

func (s *FileInfo) ModTime() time.Time

func (*FileInfo) Mode

func (s *FileInfo) Mode() os.FileMode

func (*FileInfo) Name

func (s *FileInfo) Name() string

Implements os.FileInfo

func (*FileInfo) Size

func (s *FileInfo) Size() int64

func (*FileInfo) Sys

func (s *FileInfo) Sys() interface{}

type Fs

type Fs struct {
	// Bot is the telegram bot instance
	Bot *tele.Bot
	// ChatID is the telegram chat ID to send files to
	ChatID int64
	// Logger is the logger, obviously
	Logger *slog.Logger
	// MaxPartSize is the maximum size of each part when splitting large files (bytes)
	MaxPartSize int64
	// TempDir is the optional directory used to store multipart temporary files
	TempDir string
	// RetryAttempts is the number of retry attempts for transient errors
	RetryAttempts int
	// RetryDelay is the delay between retry attempts
	RetryDelay time.Duration
	// PartUploadDelay is the delay between uploading each part to avoid rate limiting
	PartUploadDelay time.Duration
	// contains filtered or unexported fields
}

Fs is a write-only afero.Fs implementation using telegram as backend

func (*Fs) Chmod

func (m *Fs) Chmod(name string, mode os.FileMode) error

Chmod is not implemented

func (*Fs) Chown

func (m *Fs) Chown(string, int, int) error

Chown is not implemented

func (*Fs) Chtimes

func (m *Fs) Chtimes(name string, atime, mtime time.Time) error

Chtimes is not implemented

func (*Fs) Create

func (m *Fs) Create(name string) (afero.File, error)

Create creates a file buffer

func (*Fs) LstatIfPossible

func (m *Fs) LstatIfPossible(name string) (os.FileInfo, bool, error)

LstatIfPossible is not implemented

func (*Fs) Mkdir

func (m *Fs) Mkdir(name string, mode os.FileMode) error

Mkdir

func (*Fs) MkdirAll

func (m *Fs) MkdirAll(name string, mode os.FileMode) error

MkdirAll creates full path of directories like mkdir -p

func (*Fs) Name

func (m *Fs) Name() string

Name of the filesystem

func (*Fs) Open

func (m *Fs) Open(name string) (afero.File, error)

Open opens a file buffer

func (*Fs) OpenFile

func (m *Fs) OpenFile(name string, flag int, mode os.FileMode) (afero.File, error)

OpenFile opens a file buffer

func (*Fs) Remove

func (m *Fs) Remove(name string) error

Remove is not implemented

func (*Fs) RemoveAll

func (m *Fs) RemoveAll(name string) error

RemoveAll is not implemented

func (*Fs) Rename

func (m *Fs) Rename(name string, newname string) error

Rename is not implemented

func (*Fs) Stat

func (m *Fs) Stat(name string) (os.FileInfo, error)

Stat() fake implementation

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL