Telego API Callers: FastHTTPCaller, HTTPCaller, and RetryCaller Explained
Telego provides three pluggable HTTP client implementations—FastHTTPCaller, HTTPCaller, and RetryCaller—that allow developers to customize how requests are sent to the Telegram Bot API.
The mymmrac/telego library abstracts all network communication through a Caller interface, making it possible to swap between high-performance clients, standard library implementations, or retry-wrapped transports without modifying your bot logic. This article examines the three built-in callers and how to configure them for your specific latency, reliability, and testing requirements.
Understanding the Caller Interface in Telego
At the heart of Telego’s networking layer is the Caller interface defined in telegoapi/api.go at line 73. This minimal contract ensures that any HTTP client can be plugged into the Bot struct.
type Caller interface {
Call(ctx context.Context, url string, data *RequestData) (*Response, error)
}
The Call method accepts a context.Context for cancellation, the target Telegram API URL, and a RequestData payload containing the method parameters. It returns a Response struct containing the Ok boolean, raw Result JSON, and error details. This abstraction allows FastHTTPCaller, HTTPCaller, and RetryCaller to be used interchangeably.
Built-in Telego API Callers
Telego ships with three concrete implementations of the Caller interface, each optimized for different operational requirements.
FastHTTPCaller for High-Performance Bots
FastHTTPCaller is the default transport in Telego, implemented in telegoapi/caller.go at line 20. It leverages the valyala/fasthttp library, which provides significantly lower memory allocation and faster request processing compared to the standard library.
This caller is ideal for high-throughput bots handling hundreds of concurrent updates. It constructs fasthttp.Request objects, respects context cancellation via timeout settings, handles both raw and streamed request bodies, and unmarshals JSON responses using Telego’s internal JSON helper.
HTTPCaller for Standard Library Compatibility
HTTPCaller provides a thin wrapper around Go’s standard net/http client, located in telegoapi/caller.go at line 82. Use this implementation when your project already relies on the standard library’s HTTP transport, requires specific http.Client configurations (such as custom TLS settings or proxies), or when minimizing external dependencies is a priority.
The implementation creates standard http.Request objects, executes them via http.Client.Do, checks for server-level errors, and decodes the JSON response into the Response struct.
RetryCaller for Automatic Retry Logic
RetryCaller is a decorator that adds configurable retry behavior to any underlying Caller, defined in telegoapi/caller.go starting at line 34. The Call method implementation begins at line 74.
This caller supports exponential backoff with configurable ExponentBase, StartDelay, and MaxDelay. It handles three distinct rate-limiting strategies via the RateLimit field: RetryRateLimitSkip (continue without waiting), RetryRateLimitAbort (fail immediately), and RetryRateLimitWait (pause until the retry-after window expires).
When BufferRequestData is set to true, the caller buffers request bodies to allow safe retries of streaming data. This is essential when retrying multipart file uploads or large payloads.
How to Configure Telego API Callers
You can inject these callers into your Bot instance using functional options defined in bot_options.go.
Using the Default FastHTTPCaller
By default, Telego uses FastHTTPCaller automatically. No explicit configuration is required:
bot, err := telego.NewBot(os.Getenv("TELEGRAM_TOKEN"))
if err != nil {
log.Fatal(err)
}
// Uses DefaultFastHTTPCaller internally
_, err = bot.SendMessage(&telego.SendMessageParams{
ChatID: telego.ChatID{ID: 123456789},
Text: "Hello from FastHTTPCaller!",
})
Switching to the Standard HTTPCaller
To use the standard library client instead, pass the WithHTTPCaller option:
bot, err := telego.NewBot(
os.Getenv("TELEGRAM_TOKEN"),
telego.WithHTTPCaller(),
)
Adding Retry Logic with RetryCaller
Wrap any caller with RetryCaller to handle transient failures and rate limits:
retryCaller := &telegoapi.RetryCaller{
Caller: telegoapi.DefaultFastHTTPCaller,
MaxAttempts: 5,
ExponentBase: 2.0,
StartDelay: 200 * time.Millisecond,
MaxDelay: 5 * time.Second,
RateLimit: telegoapi.RetryRateLimitWait,
BufferRequestData: true,
}
bot, err := telego.NewBot(
os.Getenv("TELEGRAM_TOKEN"),
telego.WithCaller(retryCaller),
)
Implementing a Custom Caller
For testing or alternative transports, implement the Caller interface. The telegoapi/mock/caller.go file demonstrates this pattern:
type mockCaller struct{}
func (c *mockCaller) Call(ctx context.Context, url string, data *telegoapi.RequestData) (*telegoapi.Response, error) {
return &telegoapi.Response{
Ok: true,
Result: json.RawMessage(`{"message_id":42}`),
}, nil
}
bot, err := telego.NewBot(
os.Getenv("TELEGRAM_TOKEN"),
telego.WithCaller(&mockCaller{}),
)
Summary
- FastHTTPCaller (
telegoapi/caller.go#L20) provides high-performance HTTP requests using thefasthttplibrary, making it the default choice for production bots with high request volumes. - HTTPCaller (
telegoapi/caller.go#L82) wraps the standardnet/httpclient for compatibility with existing HTTP configurations and minimal external dependencies. - RetryCaller (
telegoapi/caller.go#L34) decorates any underlying caller with exponential backoff, configurable rate-limit strategies (RetryRateLimitWait,RetryRateLimitAbort,RetryRateLimitSkip), and request body buffering for resilient API communication. - All callers implement the
Callerinterface defined intelegoapi/api.go#L73, allowing seamless substitution viaBotOptionsinbot_options.goandbot.go.
Frequently Asked Questions
What is the default caller in Telego?
Telego uses FastHTTPCaller by default when you create a new bot instance without specifying caller options. This implementation leverages the valyala/fasthttp library for optimized memory usage and reduced latency. You can verify this in bot.go where the default BotOptions initialize the FastHTTPCaller internally.
When should I use FastHTTPCaller over HTTPCaller?
Choose FastHTTPCaller when your bot handles high concurrency or requires minimal memory allocation per request, as it outperforms the standard library in throughput benchmarks. Use HTTPCaller when you need specific http.Client configurations that are difficult to replicate with fasthttp, such as custom Transport layers, corporate proxy settings, or when you want to minimize external dependencies for security-audited environments.
How does RetryCaller handle Telegram rate limits?
RetryCaller supports three rate-limit handling strategies via the RateLimit field: RetryRateLimitWait pauses execution until the retry-after window expires, RetryRateLimitAbort immediately returns the rate limit error without retrying, and RetryRateLimitSkip continues to the next retry attempt without waiting. For streaming requests like file uploads, you must set BufferRequestData: true to allow the body to be re-read during retries.
Can I implement a custom caller for testing?
Yes, you can implement the Caller interface defined in telegoapi/api.go to create mock clients for unit testing. The telegoapi/mock/caller.go file provides a reference implementation showing how to return fabricated Response objects. Pass your custom caller using telego.WithCaller() when constructing the bot to isolate your tests from network dependencies and simulate specific API responses or error conditions.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →