### Minimal Bot Setup Source: https://github.com/kslamph/teleflow/blob/master/README.md Sets up a basic TeleFlow bot with a simple command handler for the '/start' command. It initializes the bot using a Telegram bot token and starts the bot to listen for incoming messages. ```go import teleflow "github.com/kslamph/teleflow/core" // Basic initialization bot, err := teleflow.NewBot(os.Getenv("TELEGRAM_BOT_TOKEN")) if err != nil { log.Fatal(err) } // Simple message handler bot.HandleCommand("start", func(ctx *teleflow.Context, command string, args string) error { return ctx.SendPromptText("Welcome to TeleFlow!") }) bot.Start() ``` -------------------------------- ### Teleflow Context: Start Flow Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Demonstrates initiating a conversational flow for a user within the Teleflow framework using the Context. ```go ctx.StartFlow(flowName string) ``` -------------------------------- ### Start a Teleflow Flow from a Command Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Illustrates how to initiate a Teleflow flow in response to a bot command. The flow is started using its unique registered name. ```go bot.HandleCommand("register", func(ctx *teleflow.Context, command string, args string) error { return ctx.StartFlow("user_registration") // Use the flow's unique name }) ``` -------------------------------- ### Start Teleflow Bot Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Shows how to start the Teleflow bot's long polling loop to begin receiving updates from Telegram. ```go bot.Start() // This starts the long polling loop to receive updates. ``` -------------------------------- ### Teleflow Handler: Handle Command Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Provides an example of registering a handler for a specific Telegram command (e.g., /start) using the Teleflow Bot object. ```go // Example: /start command bot.HandleCommand("start", func(ctx *teleflow.Context, command string, args string) error { return ctx.SendPromptText("Welcome!") }) ``` -------------------------------- ### Run TeleFlow Showcase Source: https://github.com/kslamph/teleflow/blob/master/example/template/README.md Instructions for running the TeleFlow MarkdownV2 showcase example, including setting the bot token and executing the Go program. ```bash export TELEGRAM_BOT_TOKEN="your_bot_token_here" go run example/template/markdownv2-showcase.go ``` -------------------------------- ### Run Teleflow Bot Example Source: https://github.com/kslamph/teleflow/blob/master/example/business_flow/README.md Instructions to set the Telegram bot token and run the Teleflow business bot example using Go. ```bash export TELEGRAM_BOT_TOKEN="your_bot_token_here" go run . ``` -------------------------------- ### Register a Teleflow Flow with a Bot Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Shows how to register a previously defined Teleflow flow with a bot instance. This makes the flow available to be started by users. ```go bot.RegisterFlow(registrationFlow) ``` -------------------------------- ### Build an Inline Keyboard with Teleflow Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Provides an example of constructing an inline keyboard using `teleflow.NewPromptKeyboardBuilder`. It shows how to add callback buttons (with serializable data) and URL buttons, and how to arrange them in rows. ```go keyboard := teleflow.NewPromptKeyboard(). ButtonCallback("✅ Approve", approveCallbackData). // approveCallbackData can be a struct or map ButtonCallback("❌ Reject", "reject_action"). Row(). // Start a new row of buttons ButtonURL("More Info", "https://example.com/info"). Build() // Returns *tgbotapi.InlineKeyboardMarkup // Use in PromptConfig: // Keyboard: keyboard, ``` -------------------------------- ### Teleflow Flow Definition Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Shows the fluent syntax for defining conversational flows using chained methods like `.Step()`, `.Prompt()`, and `.Process()`. Flows are registered with the bot and can be started via `ctx.StartFlow()`. ```go teleflow.NewFlow("flow_name").Step(...).Process(...).Build() bot.RegisterFlow(myFlow) ctx.StartFlow("flow_name") ``` -------------------------------- ### TeleFlow Unit and Integration Testing Source: https://github.com/kslamph/teleflow/blob/master/README.md Provides examples for testing TeleFlow bots, including unit tests for flow behavior using mocks and integration tests that interact with the actual Telegram API. ```go // Test flow behavior func TestUserRegistrationFlow(t *testing.T) { // Mock external dependencies mockService := &MockBusinessService{} // Create test bot bot := createTestBot(mockService) // Simulate user interaction ctx := createTestContext(userID) // Test flow execution err := ctx.StartFlow("user_registration") assert.NoError(t, err) // Simulate user input result := simulateInput(ctx, "John Doe") assert.Equal(t, "NextStep", result.Action) // Verify state name, exists := ctx.GetFlowData("user_name") assert.True(t, exists) assert.Equal(t, "John Doe", name) } // Integration test with real Telegram API func TestBotIntegration(t *testing.T) { if testing.Short() { t.Skip("Skipping integration test") } // Use test bot token bot, err := teleflow.NewBot(os.Getenv("TEST_BOT_TOKEN")) require.NoError(t, err) // Test actual Telegram interaction // ... integration test logic } ``` -------------------------------- ### Account Creation Interaction Example Source: https://github.com/kslamph/teleflow/blob/master/example/business_flow/README.md Simulates a user interaction for creating a new account within the Teleflow business bot. ```go User: 💼 Account Info Bot: Account Management - What would you like to do? User: [Clicks "Add New Account"] Bot: Enter a name for your new account: User: Investment Account Bot: Enter initial balance for 'Investment Account' account: User: 2500.00 Bot: ✅ Account created successfully! Name: Investment Account Account ID: `abc123-def456-ghi789` Initial Balance: `$2500.00` ``` -------------------------------- ### Initialize Teleflow Bot Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Demonstrates the basic initialization of a Teleflow bot using a Telegram bot token. It includes error handling for the initialization process. ```go import teleflow "github.com/kslamph/teleflow/core" import "os" import "log" // Basic initialization bot, err := teleflow.NewBot(os.Getenv("TELEGRAM_BOT_TOKEN")) if err != nil { log.Fatal(err) } ``` -------------------------------- ### Teleflow Command Handling Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Demonstrates how to create new command handlers using `bot.HandleCommand()`. Handlers can then use context methods like `ctx.SendPromptText()` or `ctx.StartFlow()`. ```go bot.HandleCommand("mycommand", func(ctx *teleflow.Context) error { return ctx.SendPromptText("Hello from mycommand!") }) ``` -------------------------------- ### Teleflow Template Registration and Usage Source: https://github.com/kslamph/teleflow/blob/master/README.md Shows how to register templates with specified parse modes (e.g., MarkdownV2) and use them within Teleflow flows for dynamic message generation. It includes examples of registering welcome and transaction summary templates, and sending prompts using these templates with contextual data. ```go // Register templates with parse modes func initTemplates() { templates := map[string]struct { content string parseMode teleflow.ParseMode }{ "user_welcome": { content: `
🎉 *Welcome {{.UserName}}!*
Your account details:
• *ID:* ` + "`{{.UserID}}`" + `
• *Join Date:* {{.JoinDate}}
• *Status:* {{if .IsActive}}✅ _Active_{{else}}❌ _Inactive_{{end}}
{{if .HasPremium}}
🌟 *Premium Member*
{{end}}`, parseMode: teleflow.ParseModeMarkdownV2, }, "transaction_summary": { content: `
💰 *Transaction Summary*
*Amount:* ${{printf "%.2f" .Amount}}
*From:* {{.FromAccount}}
*To:* {{.ToAccount}}
*Date:* {{.Date}}
*Status:* {{.Status}}
{{if .Notes}}
*Notes:* {{.Notes}}
{{end}}`, parseMode: teleflow.ParseModeMarkdownV2, }, } for name, template := range templates { if err := teleflow.AddTemplate(name, template.content, template.parseMode); err != nil { log.Printf("Failed to register template %s: %v", name, err) } } } // Using templates in flows func sendWelcome(ctx *teleflow.Context, user User) error { return ctx.SendPromptWithTemplate("user_welcome", map[string]interface{}{ "UserName": user.Name, "UserID": user.ID, "JoinDate": user.CreatedAt.Format("2006-01-02"), "IsActive": user.Status == "active", "HasPremium": user.Plan == "premium", }) } // Template in flow steps step.Prompt("template:transaction_summary"). WithTemplateData(map[string]interface{}{ "Amount": transaction.Amount, "FromAccount": transaction.Source, "ToAccount": transaction.Destination, "Date": transaction.CreatedAt.Format("2006-01-02 15:04"), "Status": transaction.Status, "Notes": transaction.Notes, }) ``` -------------------------------- ### Test Teleflow Bot with Race Detector Source: https://github.com/kslamph/teleflow/blob/master/example/business_flow/README.md Command to run the Teleflow business bot example with Go's race detector enabled for testing concurrency issues. ```bash go run -race . ``` -------------------------------- ### Enterprise Bot Setup with Security Source: https://github.com/kslamph/teleflow/blob/master/README.md Configures an enterprise-grade TeleFlow bot with custom access management and flow configurations. This includes defining permission logic, providing a main menu, and enabling a middleware stack for security features like rate limiting and authentication. ```go // Access manager for enterprise features type EnterpriseAccessManager struct { mainMenu *teleflow.ReplyKeyboard } func (m *EnterpriseAccessManager) CheckPermission(ctx *teleflow.PermissionContext) error { // Your permission logic here return nil } func (m *EnterpriseAccessManager) GetReplyKeyboard(ctx *teleflow.PermissionContext) *teleflow.ReplyKeyboard { return m.mainMenu } // Enterprise bot with automatic middleware stack bot, err := teleflow.NewBot(token, teleflow.WithFlowConfig(teleflow.FlowConfig{ ExitCommands: []string{"/cancel", "/exit"}, ExitMessage: "🚫 Operation cancelled", AllowGlobalCommands: false, }), teleflow.WithAccessManager(accessManager), // Auto-applies auth and main menu button pushing ) ``` -------------------------------- ### Teleflow Enterprise Middleware Stack Configuration Source: https://github.com/kslamph/teleflow/blob/master/README.md Details how to implement and apply custom middleware for enterprise features in Teleflow. It provides an example of an `AuditMiddleware` that logs user actions and their duration, and demonstrates applying this custom middleware along with a rate-limiting middleware to the bot. ```go // Custom middleware for enterprise features func AuditMiddleware() teleflow.MiddlewareFunc { return func(ctx *teleflow.Context, next teleflow.HandlerFunc) error { start := time.Now() // Log request log.Printf("User %d started action: %s", ctx.UserID(), ctx.Update().Message.Text) err := next(ctx) // Log completion duration := time.Since(start) log.Printf("User %d completed action in %v", ctx.UserID(), duration) return err } } // Apply enterprise middleware stack // Note: No need to manually call bot.UseMiddleware(teleflow.AuthMiddleware(accessManager)) bot.UseMiddleware(AuditMiddleware()) bot.UseMiddleware(teleflow.RateLimitMiddleware(60)) // 60 req/min ``` -------------------------------- ### Usage with User Profile Data Source: https://github.com/kslamph/teleflow/blob/master/example/template/README.md Provides an example of how to use the `user_profile` template by passing dynamic data, including user details and a list of activities. ```go ctx.ReplyTemplate("user_profile", map[string]interface{}{ "Name": "John Doe", "Role": "Developer", "IsActive": true, "Activities": []map[string]interface{}{ {"Index": "1", "Activity": "Implemented templates"}, {"Index": "2", "Activity": "Fixed bugs"}, }, }) ``` -------------------------------- ### Teleflow Handler: Handle Text Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Demonstrates how to register a handler that responds to exact text matches from users, using the Teleflow Bot object. ```go bot.HandleText("hello", func(ctx *teleflow.Context, text string) error { return ctx.SendPromptText("Hi there!") }) ``` -------------------------------- ### Teleflow Context: Get Flow Data Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Illustrates retrieving data that was previously stored in a user's flow session using the Teleflow Context. ```go ctx.GetFlowData(key string) (interface{}, bool) ``` -------------------------------- ### Teleflow Context: Send Prompt Text Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Illustrates how to send a simple text message to a user using the Teleflow Context object. ```go ctx.SendPromptText("Welcome!") ``` -------------------------------- ### TeleFlow Quick Reference: Data Management Source: https://github.com/kslamph/teleflow/blob/master/README.md Explains TeleFlow functions for managing data within a flow, covering setting and getting flow-scoped data and request-scoped data. ```APIDOC Data Management: - ctx.SetFlowData(key, value): Store flow-scoped data - ctx.GetFlowData(key): Retrieve flow data - ctx.Set(key, value): Store request-scoped data - ctx.Get(key): Retrieve request data ``` -------------------------------- ### Order Placement Conversation Flow Source: https://github.com/kslamph/teleflow/blob/master/example/business_flow/README.md Illustrates a comprehensive user journey for placing an order through the Teleflow bot. This includes product selection, quantity input, address confirmation, shipping method choice, and payment. ```Go User: 🛒 Place Order Bot: [Shows promotional image] Welcome to our store! Select a product category: User: [Clicks "📱 Electronics"] Bot: Select an item from 📱 Electronics: User: [Clicks "Smartphone Pro - $999.99"] Bot: Enter the quantity you want to order: User: 1 Bot: Please type your full delivery address: User: 123 Main St, New York, NY 10001 Bot: [Shows map image] Confirm delivery address: 123 Main St, New York, NY 10001 User: [Clicks "✅ Yes, Confirm"] Bot: Select shipping method: User: [Clicks "Express (2-3 days) - $12.99"] Bot: Select payment account: User: [Clicks "Main Account - $750.00"] Bot: 🎉 Order Confirmed! Order ID: `ord_789abc123def` Total Paid: `$1012.98` ``` -------------------------------- ### Teleflow Prompting in Flows Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Explains how to ask questions within a flow step and receive user input. The `.Prompt()` method displays the question, and the `.Process()` function receives the user's text reply. ```go // Define a Step() // Use .Prompt("Your question?") // In .Process(func(ctx *teleflow.Context, input string, ...)), the input variable will contain the user's text reply. ``` -------------------------------- ### Teleflow Flow Lifecycle: Starting a Flow Source: https://github.com/kslamph/teleflow/blob/master/docs/teleflow_architecture.md Illustrates the process of initiating a user's journey through a defined flow. This is typically done via a command or another flow step, which calls `ctx.StartFlow`, leading to the creation of user state and rendering the initial prompt. ```go // Starting a flow from a context ctx.StartFlow("flow_name") // Internal FlowManager action // FlowManager.startFlow(userID, "flow_name", ctx) // - Creates userFlowState // - Sets CurrentStep // - Stores initial data // - Calls renderStepPrompt ``` -------------------------------- ### Define and Build a Teleflow Flow Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Demonstrates how to define a multi-step conversational flow using the Teleflow library. It includes defining steps, prompts, processing user input, managing flow data, and handling flow completion. Dependencies include the teleflow library and standard Go libraries. ```go registrationFlow, err := teleflow.NewFlow("user_registration"). // Unique name for the flow Step("ask_name"). // Define a step Prompt("What's your name?"). // Message to send when this step starts Process(func(ctx *teleflow.Context, input string, buttonClick *teleflow.ButtonClick) teleflow.ProcessResult { // 'input' is the user's text response. // 'buttonClick' is non-nil if the user clicked an inline keyboard button. if input == "" { return teleflow.Retry().WithPrompt("Please provide a name.") // Ask the same step again } ctx.SetFlowData("userName", input) // Store data for this flow instance return teleflow.NextStep() // Proceed to the next defined step }). Step("ask_email"). Prompt(func(ctx *teleflow.Context) string { // Prompt can be a dynamic function name, _ := ctx.GetFlowData("userName") return fmt.Sprintf("Nice to meet you, %s! What's your email?", name) }). Process(func(ctx *teleflow.Context, input string, buttonClick *teleflow.ButtonClick) teleflow.ProcessResult { if !isValidEmail(input) { // Assume isValidEmail is defined elsewhere return teleflow.Retry().WithPrompt("Invalid email. Please try again.") } ctx.SetFlowData("userEmail", input) return teleflow.CompleteFlow() // End the flow successfully }). OnComplete(func(ctx *teleflow.Context) error { // Executed after CompleteFlow() name, _ := ctx.GetFlowData("userName") email, _ := ctx.GetFlowData("userEmail") // Send a summary or save data return ctx.SendPromptText(fmt.Sprintf("Registered: %s, %s", name, email)) }). Build() if err != nil { log.Fatal(err) } ``` -------------------------------- ### Keyboard Callbacks: String vs. Structured Data in Go Source: https://github.com/kslamph/teleflow/blob/master/README.md Illustrates the difference between using simple string callbacks and structured data for keyboard interactions. Structured data provides type safety and easier data parsing for callback payloads. ```go // DON'T: Limited callback data keyboard.ButtonCallback("Approve Transaction", "approve_tx_123") // Then manually parse in handler if buttonClick.Data == "approve_tx_123" { // Parse ID from string... } ``` ```go // DO: Use structured callback data approvalData := struct { Action string `json:"action"` TransactionID string `json:"transaction_id"` Amount float64 `json:"amount"` RequiresAuth bool `json:"requires_auth"` }{ Action: "approve", TransactionID: "tx_123", Amount: 1500.50, RequiresAuth: true, } keyboard.ButtonCallback("Approve $1,500.50", approvalData) // Easy type-safe access if data, ok := buttonClick.Data.(struct{...}); ok { if data.RequiresAuth { // Handle authentication } } ``` -------------------------------- ### Async Patterns with Timeouts in TeleFlow Source: https://github.com/kslamph/teleflow/blob/master/README.md Illustrates the correct approach for performance by using asynchronous patterns with timeouts. This prevents blocking operations within handlers and improves responsiveness. ```go .Process(func(ctx *teleflow.Context, input string, buttonClick *teleflow.ButtonClick) teleflow.ProcessResult { go func() { // Background processing result, err := processWithTimeout(input, 30*time.Second) if err != nil { ctx.SendPromptText("❌ Processing failed: " + err.Error()) return } ctx.SendPromptText("✅ Processing complete: " + result) }() return teleflow.CompleteFlow().WithPrompt("⏳ Processing your request in background...") }) ``` -------------------------------- ### TeleFlow Quick Reference: Message Actions Source: https://github.com/kslamph/teleflow/blob/master/README.md Details TeleFlow functions for sending messages to users, including simple text messages, rich messages with configurations, and messages using templates. ```APIDOC Message Actions: - ctx.SendPromptText(msg): Simple text message - ctx.SendPrompt(config): Rich message with templates/images - ctx.SendPromptWithTemplate(name, data): Template shorthand ``` -------------------------------- ### Teleflow Templates Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Defines reusable message formats with placeholders using Go's text/template syntax. Templates can be registered and then used within prompt configurations or directly in message sending functions. ```go teleflow.AddTemplate("welcome_message", "Hello {{.UserName}}! Welcome to our bot.", teleflow.ParseModeMarkdownV2) ``` -------------------------------- ### TeleFlow Quick Reference: Error Strategies Source: https://github.com/kslamph/teleflow/blob/master/README.md Outlines TeleFlow's built-in error handling strategies, such as canceling or retrying a step on error, and the option for custom error handlers. ```APIDOC Error Strategies: - teleflow.OnErrorCancel(msg): Cancel flow on error - teleflow.OnErrorRetry(msg): Retry step on error - Custom error handler for complex scenarios ``` -------------------------------- ### Flow Design: Monolithic vs. Single Responsibility Steps in Go Source: https://github.com/kslamph/teleflow/blob/master/README.md Compares monolithic process functions with a design that breaks down flows into smaller, single-responsibility steps. The latter approach enhances testability and maintainability. ```go // DON'T: Everything in one function .Process(func(ctx *teleflow.Context, input string, buttonClick *teleflow.ButtonClick) teleflow.ProcessResult { // 100+ lines of validation, business logic, API calls, etc. // Hard to test and maintain }) ``` ```go // DO: Break down into focused steps .Step("validate_input"). .Process(validateUserInput). .Step("check_permissions"). .Process(checkUserPermissions). .Step("process_business_logic"). .Process(processBusinessRequest). // Each function has single responsibility func validateUserInput(ctx *teleflow.Context, input string, buttonClick *teleflow.ButtonClick) teleflow.ProcessResult { if err := validation.ValidateInput(input); err != nil { return teleflow.Retry().WithPrompt("Invalid input: " + err.Error()) } return teleflow.NextStep() } ``` -------------------------------- ### External Service Integration with Caching in Go Source: https://github.com/kslamph/teleflow/blob/master/README.md Demonstrates integrating external services using a BusinessService struct that utilizes a database, API client, and cache. The GetUserAccounts method prioritizes cache lookups before falling back to the database and then caching the result. ```go type BusinessService struct { database Database apiClient *APIClient cache Cache } func (bs *BusinessService) GetUserAccounts(userID int64) []Account { // Try cache first if accounts, found := bs.cache.Get(fmt.Sprintf("accounts:%d", userID)); found { return accounts.([]Account) } // Fallback to database accounts := bs.database.GetAccountsByUserID(userID) // Cache result bs.cache.Set(fmt.Sprintf("accounts:%d", userID), accounts, 5*time.Minute) return accounts } // Use in flows flow := teleflow.NewFlow("account_management"). Step("load_accounts"). Process(func(ctx *teleflow.Context, input string, buttonClick *teleflow.ButtonClick) teleflow.ProcessResult { accounts := businessService.GetUserAccounts(ctx.UserID()) ctx.SetFlowData("accounts", accounts) return teleflow.NextStep() }). Build() ``` -------------------------------- ### Correct Error Handling in TeleFlow Source: https://github.com/kslamph/teleflow/blob/master/README.md Demonstrates the correct way to handle errors in TeleFlow by implementing a comprehensive error strategy with a custom handler. This includes logging errors and providing user-friendly messages. ```go flow := teleflow.NewFlow("payment"). OnError(&teleflow.ErrorConfig{ Handler: func(ctx *teleflow.Context, err error) error { // Log for monitoring monitoring.LogError(ctx.UserID(), err) // User-friendly error message return ctx.SendPrompt(&teleflow.PromptConfig{ Message: "❌ Payment failed. Your account was not charged. Please try again or contact support.", }) }, }). Process(func(ctx *teleflow.Context, input string, buttonClick *teleflow.ButtonClick) teleflow.ProcessResult { if err := businessService.ProcessPayment(amount); err != nil { // Specific error handling if errors.Is(err, ErrInsufficientFunds) { return teleflow.Retry().WithPrompt("❌ Insufficient funds. Please check your balance.") } // Let OnError handler catch other errors return teleflow.ProcessResult{} // This will trigger OnError } return teleflow.CompleteFlow() }). Build() ``` -------------------------------- ### Send a Rich Prompt with Teleflow Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Demonstrates sending a complex message to the user using `teleflow.PromptConfig`. This includes text, an optional image, template data for dynamic content, and an inline keyboard. It also shows setting the message parse mode. ```go // Assume imageBytes is []byte content of an image return ctx.SendPrompt(&teleflow.PromptConfig{ Message: "template:welcome_message", // Can be literal text or "template:template_name" Image: imageBytes, // Optional image TemplateData: map[string]interface{}{ // Data for the template "UserName": "John Doe", }, Keyboard: teleflow.NewPromptKeyboard(). // Optional inline keyboard ButtonCallback("Option 1", "callback_data_1"). ButtonURL("Visit Site", "https://example.com"). Build(), ParseMode: teleflow.ParseModeMarkdownV2, // Optional, defaults based on template or global config }) ``` -------------------------------- ### Teleflow Middleware Function Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Demonstrates the structure and application of middleware functions in Teleflow. Middleware intercepts updates before they reach handlers, allowing for actions like logging or authentication. It takes a `HandlerFunc` and returns a new `HandlerFunc`. ```go func MyMiddleware(next teleflow.HandlerFunc) teleflow.HandlerFunc { return func(ctx *teleflow.Context) error { // Code before handler log.Printf("User %d accessing: %s", ctx.UserID(), ctx.Update().Message.Text) err := next(ctx) // Call the next middleware or the actual handler // Code after handler return err } } bot.UseMiddleware(MyMiddleware) bot.UseMiddleware(teleflow.RateLimitMiddleware(10, time.Minute*1)) ``` -------------------------------- ### Advanced Messaging with Prompt Builder Source: https://github.com/kslamph/teleflow/blob/master/README.md Illustrates sending a rich message that includes an image and uses a template for the message content. This method allows for dynamic content personalization by passing data to the template. ```go // Rich message with image and template imageBytes, _ := generateWelcomeImage(user.Name) return ctx.SendPrompt(&teleflow.PromptConfig{ Message: "template:welcome_user", Image: imageBytes, TemplateData: map[string]interface{}{ "UserName": user.Name, "UserID": ctx.UserID(), "JoinDate": time.Now().Format("2006-01-02"), }, }) ``` -------------------------------- ### Teleflow Advanced Template Features Source: https://github.com/kslamph/teleflow/blob/master/README.md Explores advanced capabilities of the Teleflow template system, including data precedence where `TemplateData` overrides context data, conditional rendering of templates based on user attributes, and dynamically generating template content using Go's `fmt.Sprintf`. ```go // Data precedence: TemplateData overrides Context data step.Prompt("template:user_profile"). WithTemplateData(map[string]interface{}{ "UserName": "Custom Name", // This takes precedence "UserID": ctx.UserID(), // Context data as fallback }) // Conditional templates if user.IsVIP { ctx.SendPromptWithTemplate("vip_welcome", userData) } else { ctx.SendPromptWithTemplate("standard_welcome", userData) } // Template with dynamic content dynamicTemplate := fmt.Sprintf(` *` + "`%s`" + ` Dashboard* {{range .Items}} • {{.Name}}: {{.Value}} {{end}} `, user.GetDashboardTitle()) teleflow.AddTemplate("user_dashboard", dynamicTemplate, teleflow.ParseModeMarkdownV2) ``` -------------------------------- ### Create and Register User Registration Flow in Go Source: https://github.com/kslamph/teleflow/blob/master/README.md Defines a Teleflow flow for user registration, collecting name and email, with an OnComplete handler to send a confirmation message. The flow is then registered with a bot and can be initiated via a command. ```go registrationFlow, err := teleflow.NewFlow("user_registration"). Step("welcome"). Prompt("👋 Welcome! What's your name?"). Process(func(ctx *teleflow.Context, input string, buttonClick *teleflow.ButtonClick) teleflow.ProcessResult { if input == "" { return teleflow.Retry().WithPrompt("Please enter your name:") } ctx.SetFlowData("user_name", input) return teleflow.NextStep() }). Step("email"). Prompt(func(ctx *teleflow.Context) string { name, _ := ctx.GetFlowData("user_name") return fmt.Sprintf("Nice to meet you, %s! What's your email?", name) }). Process(func(ctx *teleflow.Context, input string, buttonClick *teleflow.ButtonClick) teleflow.ProcessResult { if !isValidEmail(input) { return teleflow.Retry().WithPrompt("Please enter a valid email address:") } ctx.SetFlowData("user_email", input) return teleflow.CompleteFlow() }). OnComplete(func(ctx *teleflow.Context) error { name, _ := ctx.GetFlowData("user_name") email, _ := ctx.GetFlowData("user_email") return ctx.SendPrompt(&teleflow.PromptConfig{ Message: fmt.Sprintf("✅ Registration complete!\n\n*Name:* %s\n*Email:* %s", name, email), }) }). Build() // Register and use bot.RegisterFlow(registrationFlow) bot.HandleCommand("register", func(ctx *teleflow.Context, command string, args string) error { return ctx.StartFlow("user_registration") }) ``` -------------------------------- ### State Management: Manual vs. TeleFlow in Go Source: https://github.com/kslamph/teleflow/blob/master/README.md Contrasts manual state management with TeleFlow's built-in flow-based state management. The correct approach leverages TeleFlow to automatically handle user sessions and data persistence within flows. ```go // DON'T: Manual session management var userSessions = make(map[int64]*UserSession) func handleMessage(ctx *teleflow.Context) error { session, exists := userSessions[ctx.UserID()] if !exists { session = &UserSession{} userSessions[ctx.UserID()] = session } // Manual state logic... } ``` ```go // DO: Use flow-based state management flow := teleflow.NewFlow("user_session"). Step("start"). Process(func(ctx *teleflow.Context, input string, buttonClick *teleflow.ButtonClick) teleflow.ProcessResult { // TeleFlow automatically manages user state ctx.SetFlowData("user_preference", input) return teleflow.NextStep() }). Build() ``` -------------------------------- ### Implement Teleflow Error Handling Strategies Source: https://github.com/kslamph/teleflow/blob/master/README.md Showcases different strategies for handling errors within Teleflow flows: cancelling the flow, retrying the operation, and implementing custom error handling logic with detailed logging and user feedback. ```go // Strategy 1: Cancel on error flow1 := teleflow.NewFlow("strict_flow"). OnError(teleflow.OnErrorCancel("❌ Error occurred. Operation cancelled.")). Build() // Strategy 2: Retry on error flow2 := teleflow.NewFlow("retry_flow"). OnError(teleflow.OnErrorRetry("⚠️ Error occurred. Please try again.")). Build() // Strategy 3: Custom error handling flow3 := teleflow.NewFlow("custom_error_flow"). OnError(&teleflow.ErrorConfig{ Handler: func(ctx *teleflow.Context, err error) error { // Log error for monitoring log.Printf("Flow error for user %d: %v", ctx.UserID(), err) // Send custom error message based on error type if businessError, ok := err.(*BusinessError); ok { return ctx.SendPrompt(&teleflow.PromptConfig{ Message: fmt.Sprintf("❌ %s\n\nError Code: %s", businessError.Message, businessError.Code), }) } // Default error message return ctx.SendPromptText("❌ An unexpected error occurred. Please contact support.") }, }). Build() ``` -------------------------------- ### Teleflow Bot Management API Source: https://github.com/kslamph/teleflow/blob/master/docs/godoc_summary.md Documentation for creating, configuring, and managing Teleflow bots, including handlers, middleware, and commands. ```APIDOC Bot Management: Types: HandlerFunc: Generic handler for processing updates. CommandHandlerFunc: Handler for Telegram commands. TextHandlerFunc: Handler for specific text messages. DefaultHandlerFunc: Fallback handler for unmatched messages. BotOption: Configuration option for bot customization. PermissionContext: Context for access control decisions. AccessManager: Interface for controlling user access. Bot: Main bot instance with full documentation. Functions: NewBot(): Bot creation with examples. - Initializes a new Bot instance. - Accepts optional BotOption configurations. WithFlowConfig(config FlowConfig): BotOption - Configures the flow system for the bot. WithAccessManager(am AccessManager): BotOption - Sets a custom AccessManager for permission checks. UseMiddleware(middleware ...Middleware): - Registers middleware functions to be executed for each update. HandleCommand(command string, handler CommandHandlerFunc): - Registers a handler for a specific Telegram command. HandleText(handler TextHandlerFunc): - Registers a handler for general text messages. DefaultHandler(handler DefaultHandlerFunc): - Registers a fallback handler for messages not matched by other handlers. RegisterFlow(flow Flow): - Registers a custom flow with the bot. SetBotCommands(commands []telegram.BotCommand): - Configures the Telegram command menu for the bot. DeleteMessage(chatID int64, messageID int): - Deletes a specific message from a chat. EditMessageReplyMarkup(chatID int64, messageID int, markup telegram.InlineKeyboardMarkup): - Edits the reply markup of an existing message. Start(): - Starts the bot's event loop, listening for updates. ``` -------------------------------- ### Convenience Template Methods Source: https://github.com/kslamph/teleflow/blob/master/example/template/README.md Provides direct methods for replying with templates and sending template-based prompts, simplifying message composition. ```go // Direct template reply ctx.ReplyTemplate("template_name", templateData) // Template-based prompts ctx.SendPromptWithTemplate("template_name", templateData) ``` -------------------------------- ### Teleflow Context: Set Flow Data Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Shows how to store data within a user's current flow session using the Teleflow Context. ```go ctx.SetFlowData(key string, value interface{}) ``` -------------------------------- ### Simple Text Messaging Source: https://github.com/kslamph/teleflow/blob/master/README.md Demonstrates sending a simple text message to a user using the TeleFlow bot context. This is a fundamental method for basic user interaction. ```go // Simple text only ctx.SendPromptText("Hello World") ``` -------------------------------- ### TeleFlow Quick Reference: Flow Control Source: https://github.com/kslamph/teleflow/blob/master/README.md Lists common TeleFlow functions for controlling the flow of a conversation, including moving to the next step, retrying, completing, or canceling the flow. ```APIDOC Flow Control: - teleflow.NextStep(): Continue to next step - teleflow.GoToStep("name"): Jump to specific step - teleflow.Retry(): Re-prompt current step - teleflow.CompleteFlow(): Finish flow, trigger OnComplete - teleflow.CancelFlow(): Abort flow, trigger cleanup ``` -------------------------------- ### Teleflow Bot Initialization Source: https://github.com/kslamph/teleflow/blob/master/docs/teleflow_architecture.md Initializes a new Teleflow bot instance, setting up essential components like the Telegram client, flow manager, prompt composer, template manager, and keyboard handler. It also registers middleware and command handlers. ```go // Initialize bot with token and other configurations bot := teleflow.NewBot(token, config) // Register middleware bot.UseMiddleware(middleware1, middleware2) // Register command handlers bot.HandleCommand("start", handleStart) bot.HandleCommand("help", handleHelp) // Start the bot bot.Start() ``` -------------------------------- ### Basic Formatting Template Source: https://github.com/kslamph/teleflow/blob/master/example/template/README.md Demonstrates basic MarkdownV2 formatting within a TeleFlow template, including bold, italic, underline, strikethrough, and combined styles. ```go bot.AddTemplate("basic_formatting", "*Bold text* and _italic text_ and __underline__ and ~strikethrough~\n\n"+ "You can also combine *_bold italic_* and *__bold underline__*", teleflow.ParseModeMarkdownV2) ``` -------------------------------- ### Teleflow Type-Safe Callbacks Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Illustrates using Go structs or maps for button callback data, enabling type-safe deserialization. This avoids manual JSON parsing of callback strings. ```go type UserAction struct { Action string `json:"action"` ItemID int `json:"item_id"` } // ... in keyboard setup ButtonCallback("Delete Item 5", UserAction{Action: "delete", ItemID: 5}) // ... in Process function if buttonClick != nil { if actionData, ok := buttonClick.Data.(UserAction); ok { // actionData is now a UserAction struct if actionData.Action == "delete" { /* ... */ } } } ``` -------------------------------- ### Teleflow Keyboard System API Source: https://github.com/kslamph/teleflow/blob/master/docs/godoc_summary.md API for creating and configuring various types of reply keyboards for user interaction in Teleflow bots. ```APIDOC Keyboard System: Types: ReplyKeyboardButton: Individual keyboard button. ReplyKeyboard: Complete keyboard structure. ReplyKeyboardBuilder: Fluent keyboard construction. Functions: BuildReplyKeyboard(buttons [][]ReplyKeyboardButton): ReplyKeyboard - Creates a ReplyKeyboard from a 2D slice of buttons. NewReplyKeyboard(): ReplyKeyboardBuilder - Initializes a new ReplyKeyboardBuilder. AddButton(text string, requestContact bool, requestLocation bool): ReplyKeyboardBuilder - Adds a standard button to the current row. AddContactButton(): ReplyKeyboardBuilder - Adds a button that requests the user's contact information. AddLocationButton(): ReplyKeyboardBuilder - Adds a button that requests the user's location. Row(): ReplyKeyboardBuilder - Starts a new row for keyboard buttons. Resize(): ReplyKeyboardBuilder - Enables keyboard resizing. OneTime(): ReplyKeyboardBuilder - Configures the keyboard to be one-time use. Placeholder(placeholder string): ReplyKeyboardBuilder - Sets a placeholder text for the input field when the keyboard is active. Selective(): ReplyKeyboardBuilder - Configures the keyboard to be displayed selectively. Build(): ReplyKeyboard - Finalizes the keyboard construction. ``` -------------------------------- ### Fund Transfer Conversation Flow Source: https://github.com/kslamph/teleflow/blob/master/example/business_flow/README.md Demonstrates a typical user interaction for transferring funds between accounts within the Teleflow bot. It covers account selection, amount entry, and confirmation of a successful transfer. ```Go User: 💸 Transfer Funds Bot: Select the account to transfer FROM: User: [Clicks "Main Account - $1000.00"] Bot: Select the account to transfer TO: User: [Clicks "Savings Account - $5000.00"] Bot: Enter transfer amount (Available balance: $1000.00): User: 250.00 Bot: ✅ Transfer Successful! Transfer of `$250.00` from account `main123` to account `save456` completed successfully. ``` -------------------------------- ### Fluent Inline Keyboard Builder Source: https://github.com/kslamph/teleflow/blob/master/example/template/README.md Constructs an inline keyboard with various button types (callback, URL) and custom callback data. Supports complex data structures for callback queries. ```go func(ctx *teleflow.Context) *teleflow.InlineKeyboardBuilder { userData := map[string]interface{}{ "user_id": ctx.UserID(), "action": "profile", "timestamp": time.Now(), } return teleflow.NewInlineKeyboard(). ButtonCallback("📝 Basic", "basic"). ButtonCallback("💻 Code", "code"). Row(). ButtonCallback("🔗 Links", "links"). ButtonCallback("📋 Lists", "lists"). Row(). ButtonCallback("👤 Profile", userData). ButtonUrl("🌐 Website", "https://example.com") } ``` -------------------------------- ### Teleflow State Management Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Explains how to manage state within a user's flow session using `ctx.SetFlowData()` and `ctx.GetFlowData()`. This provides a simple key-value store scoped to the current flow. ```go ctx.SetFlowData("myKey", myValue) value, ok := ctx.GetFlowData("myKey") ``` -------------------------------- ### PromptComposer Keyboard Handling Source: https://github.com/kslamph/teleflow/blob/master/docs/teleflow_architecture.md Describes the process of building and attaching inline keyboards to messages using KeyboardFunc and PromptKeyboardHandler. ```go // If promptConfig.Keyboard (a KeyboardFunc) is present: // PromptKeyboardHandler.BuildKeyboard(ctx, promptConfig.Keyboard) is called. // This executes the KeyboardFunc, which uses PromptKeyboardBuilder to define buttons. // PromptKeyboardHandler registers UUIDs for callback data and returns the tgbotapi.InlineKeyboardMarkup. ``` -------------------------------- ### Teleflow Flow Control Diagram Source: https://github.com/kslamph/teleflow/blob/master/README.md Visualizes the control flow within Teleflow, illustrating transitions between steps, handling of user input, and different process results like NextStep, Retry, and CompleteFlow. ```mermaid graph TD A[User Input/Button Click] --> B{Process Function} B --> C[NextStep] B --> D[GoToStep] B --> E[Retry] B --> F[CompleteFlow] B --> G[CancelFlow] C --> H[Auto State Transition] D --> I[Manual Step Selection] E --> J[Re-prompt Same Step] F --> K[OnComplete Handler] G --> L[Flow Cleanup] H --> M[Keyboard Management] I --> M J --> M K --> N[Flow End] L --> N O[Error Occurs] --> P{Error Strategy} P --> Q[OnErrorCancel] P --> R[OnErrorRetry] P --> S[Custom Handler] Q --> L R --> E S --> T[Custom Logic] ``` -------------------------------- ### FlowManager Methods Source: https://github.com/kslamph/teleflow/blob/master/docs/teleflow_architecture.md Manages the lifecycle of active conversation flows, tracking user states and handling flow execution. Key methods include starting, handling updates, canceling flows, and managing user-specific flow data. ```go newFlowManager(...) registerFlow(flow *Flow) startFlow(userID int64, flowName string, ctx *Context) HandleUpdate(ctx *Context) cancelFlow(userID int64) isUserInFlow(userID int64) setUserFlowData(userID int64, key string, value interface{}) getUserFlowData(userID int64, key string) ``` -------------------------------- ### Extensibility Options Source: https://github.com/kslamph/teleflow/blob/master/docs/teleflow_architecture.md Outlines various ways to extend Teleflow's functionality, including middleware, custom managers, template functions, and handlers. ```go // Middleware: Add custom MiddlewareFunc to intercept and process updates. // Custom AccessManager: Implement AccessManager interface for fine-grained permission control. // Custom Template Functions: Extend TemplateManager with custom Go template functions. // Custom Handlers: Define CommandHandlerFunc, TextHandlerFunc, and DefaultHandlerFunc. // Flow Logic: Use ProcessFunc within flow steps for arbitrary Go code. ``` -------------------------------- ### Teleflow Keyboard Buttons in Flows Source: https://github.com/kslamph/teleflow/blob/master/docs/llm_teleflow_guide.md Details how to add buttons to messages within a flow using `.WithPromptKeyboard()`. Keyboards are built with `teleflow.NewPromptKeyboard().ButtonCallback(...).Build()`, and button data is accessed in the `.Process()` function. ```go // In a Step(), use .WithPromptKeyboard(func(ctx *teleflow.Context) *teleflow.PromptKeyboardBuilder { ... }) // Build the keyboard using teleflow.NewPromptKeyboard().ButtonCallback(...).Build() // In .Process(func(ctx *teleflow.Context, ..., buttonClick *teleflow.ButtonClick)), check if buttonClick != nil and access buttonClick.Data. ```