mirror of
https://github.com/HugeFrog24/go-telegram-bot.git
synced 2026-03-02 00:14:34 +00:00
Added tests, revised logging Removed dependency on env file Try reformatting unit file Comments clarification Added readme Added readme
189 lines
5.7 KiB
Go
Executable File
189 lines
5.7 KiB
Go
Executable File
package main
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"github.com/go-telegram/bot"
|
|
"github.com/go-telegram/bot/models"
|
|
"github.com/liushuangls/go-anthropic/v2"
|
|
)
|
|
|
|
func (b *Bot) handleUpdate(ctx context.Context, tgBot *bot.Bot, update *models.Update) {
|
|
var message *models.Message
|
|
|
|
if update.Message != nil {
|
|
message = update.Message
|
|
} else if update.BusinessMessage != nil {
|
|
message = update.BusinessMessage
|
|
} else {
|
|
// No message to process
|
|
return
|
|
}
|
|
|
|
// Extract businessConnectionID if available
|
|
var businessConnectionID string
|
|
if update.BusinessConnection != nil {
|
|
businessConnectionID = update.BusinessConnection.ID
|
|
} else if message.BusinessConnectionID != "" {
|
|
businessConnectionID = message.BusinessConnectionID
|
|
}
|
|
|
|
chatID := message.Chat.ID
|
|
userID := message.From.ID
|
|
username := message.From.Username
|
|
text := message.Text
|
|
|
|
// Pass the incoming message through the centralized screen for storage
|
|
_, err := b.screenIncomingMessage(message)
|
|
if err != nil {
|
|
ErrorLogger.Printf("Error storing user message: %v", err)
|
|
return
|
|
}
|
|
|
|
// Check if the message is a command
|
|
if message.Entities != nil {
|
|
for _, entity := range message.Entities {
|
|
if entity.Type == "bot_command" {
|
|
command := strings.TrimSpace(message.Text[entity.Offset : entity.Offset+entity.Length])
|
|
switch command {
|
|
case "/stats":
|
|
b.sendStats(ctx, chatID, userID, username, businessConnectionID)
|
|
return
|
|
case "/whoami":
|
|
b.sendWhoAmI(ctx, chatID, userID, username, businessConnectionID)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check if the message contains a sticker
|
|
if message.Sticker != nil {
|
|
b.handleStickerMessage(ctx, chatID, userID, message, businessConnectionID)
|
|
return
|
|
}
|
|
|
|
// Rate limit check
|
|
if !b.checkRateLimits(userID) {
|
|
b.sendRateLimitExceededMessage(ctx, chatID, businessConnectionID)
|
|
return
|
|
}
|
|
|
|
// Proceed only if the message contains text
|
|
if text == "" {
|
|
InfoLogger.Printf("Received a non-text message from user %d in chat %d", userID, chatID)
|
|
return
|
|
}
|
|
|
|
// Determine if the user is the owner
|
|
var isOwner bool
|
|
err = b.db.Where("telegram_id = ? AND bot_id = ? AND is_owner = ?", userID, b.botID, true).First(&User{}).Error
|
|
if err == nil {
|
|
isOwner = true
|
|
}
|
|
|
|
user, err := b.getOrCreateUser(userID, username, isOwner)
|
|
if err != nil {
|
|
ErrorLogger.Printf("Error getting or creating user: %v", err)
|
|
return
|
|
}
|
|
|
|
// Update the username if it's empty or has changed
|
|
if user.Username != username {
|
|
user.Username = username
|
|
if err := b.db.Save(&user).Error; err != nil {
|
|
ErrorLogger.Printf("Error updating user username: %v", err)
|
|
}
|
|
}
|
|
|
|
// Determine if the text contains only emojis
|
|
isEmojiOnly := isOnlyEmojis(text)
|
|
|
|
// Prepare context messages for Anthropic
|
|
chatMemory := b.getOrCreateChatMemory(chatID)
|
|
b.addMessageToChatMemory(chatMemory, b.createMessage(chatID, userID, username, user.Role.Name, text, true))
|
|
contextMessages := b.prepareContextMessages(chatMemory)
|
|
|
|
// Get response from Anthropic
|
|
response, err := b.getAnthropicResponse(ctx, contextMessages, b.isNewChat(chatID), isOwner, isEmojiOnly)
|
|
if err != nil {
|
|
ErrorLogger.Printf("Error getting Anthropic response: %v", err)
|
|
response = "I'm sorry, I'm having trouble processing your request right now."
|
|
}
|
|
|
|
// Send the response through the centralized screen
|
|
if err := b.sendResponse(ctx, chatID, response, businessConnectionID); err != nil {
|
|
ErrorLogger.Printf("Error sending response: %v", err)
|
|
return
|
|
}
|
|
}
|
|
|
|
func (b *Bot) sendRateLimitExceededMessage(ctx context.Context, chatID int64, businessConnectionID string) {
|
|
if err := b.sendResponse(ctx, chatID, "Rate limit exceeded. Please try again later.", businessConnectionID); err != nil {
|
|
ErrorLogger.Printf("Error sending rate limit exceeded message: %v", err)
|
|
}
|
|
}
|
|
|
|
func (b *Bot) handleStickerMessage(ctx context.Context, chatID, userID int64, message *models.Message, businessConnectionID string) {
|
|
username := message.From.Username
|
|
|
|
// Create the user message (without storing it manually)
|
|
userMessage := b.createMessage(chatID, userID, username, "user", "Sent a sticker.", true)
|
|
userMessage.StickerFileID = message.Sticker.FileID
|
|
|
|
// Safely store the Thumbnail's FileID if available
|
|
if message.Sticker.Thumbnail != nil {
|
|
userMessage.StickerPNGFile = message.Sticker.Thumbnail.FileID
|
|
}
|
|
|
|
// Update chat memory with the user message
|
|
chatMemory := b.getOrCreateChatMemory(chatID)
|
|
b.addMessageToChatMemory(chatMemory, userMessage)
|
|
|
|
// Generate AI response about the sticker
|
|
response, err := b.generateStickerResponse(ctx, userMessage)
|
|
if err != nil {
|
|
ErrorLogger.Printf("Error generating sticker response: %v", err)
|
|
// Provide a fallback dynamic response based on sticker type
|
|
if message.Sticker.IsAnimated {
|
|
response = "Wow, that's a cool animated sticker!"
|
|
} else if message.Sticker.IsVideo {
|
|
response = "Interesting video sticker!"
|
|
} else {
|
|
response = "That's a cool sticker!"
|
|
}
|
|
}
|
|
|
|
// Send the response through the centralized screen
|
|
if err := b.sendResponse(ctx, chatID, response, businessConnectionID); err != nil {
|
|
ErrorLogger.Printf("Error sending response: %v", err)
|
|
return
|
|
}
|
|
}
|
|
|
|
func (b *Bot) generateStickerResponse(ctx context.Context, message Message) (string, error) {
|
|
// Example: Use the sticker type to generate a response
|
|
if message.StickerFileID != "" {
|
|
// Prepare context with information about the sticker
|
|
contextMessages := []anthropic.Message{
|
|
{
|
|
Role: anthropic.RoleUser,
|
|
Content: []anthropic.MessageContent{
|
|
anthropic.NewTextMessageContent("User sent a sticker."),
|
|
},
|
|
},
|
|
}
|
|
|
|
// Since this is a sticker message, isEmojiOnly is false
|
|
response, err := b.getAnthropicResponse(ctx, contextMessages, false, false, false)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return response, nil
|
|
}
|
|
|
|
return "Hmm, that's interesting!", nil
|
|
}
|