Skip to content

Latest commit

 

History

History
111 lines (86 loc) · 3.42 KB

File metadata and controls

111 lines (86 loc) · 3.42 KB

tgbotkit-runtime

tgbotkit-runtime is a Go-based runtime environment designed for building Telegram bots. It provides a robust foundation for handling API interactions, event dispatching, and extensible logic via listeners and handlers, allowing developers to focus on bot logic.

Documentation

For detailed information, please refer to the official documentation:

Key Features

  • OpenAPI Client: Utilizes the most fresh, autogenerated client (github.com/tgbotkit/client) derived directly from the Telegram Bot API OpenAPI specification.
  • Event-Driven Architecture: Built around a pluggable EventEmitter system.
  • Middleware Support: Supports middleware for the event emitter (context injection, logging, recovery).
  • Modular Design: Core functionalities like update polling, command parsing, and message classification are implemented as distinct listeners.
  • Flexible Configuration: Uses the functional options pattern for type-safe configuration.
  • Pluggable Logging: Interfaces for logging allow for easy swapping of implementations (slog, zerolog, noop).

Example

Here is a simple webhook bot example:

package main

import (
	"context"
	"errors"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/tgbotkit/runtime"
	"github.com/tgbotkit/runtime/events"
	"github.com/tgbotkit/runtime/handlers"
	"github.com/tgbotkit/runtime/webhook"
)

func main() {
	token := os.Getenv("TELEGRAM_TOKEN")
	if token == "" {
		log.Fatal("TELEGRAM_TOKEN is required")
	}

	// Initialize webhook update source. Registration is disabled here because
	// this example assumes the public Telegram webhook is managed externally.
	wh, _ := webhook.New(webhook.NewOptions(
		webhook.WithWebhookRegistrationEnabled(false),
	))

	bot, err := runtime.New(runtime.NewOptions(
		token,
		runtime.WithUpdateSource(wh),
	))
	if err != nil {
		log.Fatalf("failed to create bot: %v", err)
	}

	// Register a handler for ping text messages only
	bot.Handlers().OnMessageMatch(handlers.MessageText("ping"), func(ctx context.Context, event *events.MessageEvent) error {
		_, err := bot.Responder().SendTextToMessage(ctx, event.Message, "pong")
		return err
	})

	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer stop()

	server := &http.Server{
		Addr:    ":8080",
		Handler: wh,
	}

	go func() {
		log.Printf("Webhook server listening on :8080")
		if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
			log.Fatalf("server error: %v", err)
		}
	}()

	runErr := bot.Run(ctx)

	shutdownCtx, cancelShutdown := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancelShutdown()
	if err := server.Shutdown(shutdownCtx); err != nil {
		log.Printf("server shutdown error: %v", err)
	}

	if runErr != nil {
		log.Fatalf("bot error: %v", runErr)
	}
}

Compatibility

Bot.Responder() and handler routing helpers are additive convenience APIs. Existing bots can keep using Bot.Client() with the generated github.com/tgbotkit/client request and response types, and that remains the full-coverage path for Telegram methods that are not wrapped by the responder helpers.

License

MIT