Conversation
[pull] origin from krau:main
[pull] origin from krau:main
Reviewer's GuideThis PR introduces full i18n support, adds a userbot fallback client for fetching files, extends configuration with language and userbot options, refactors handler registration, updates logging formatting, and upgrades project dependencies. Sequence Diagram for File Fetching with Userbot FallbacksequenceDiagram
actor User
participant MainBot
participant UserBotClient
participant Telegram
User->>MainBot: Send message with file link
MainBot->>MainBot: Parse link (chatID, messageID)
MainBot->>Telegram: Attempt to fetch file metadata (using MainBot client)
alt Fetch with MainBot Fails (e.g., peer not found) AND UserBot Enabled
Telegram-->>MainBot: Error (e.g., peer not found)
MainBot->>UserBotClient: Request file fetch (chatID, messageID)
UserBotClient->>Telegram: Fetch file metadata (using UserBot client)
Telegram-->>UserBotClient: File metadata
UserBotClient-->>MainBot: File metadata (file, useUserClient=true)
else Fetch with MainBot Succeeds or UserBot not applicable
Telegram-->>MainBot: File metadata
MainBot->>MainBot: Process file (useUserClient=false)
end
MainBot->>MainBot: Create Task (with useUserClient flag)
MainBot-->>User: Reply (e.g., "Processing file...")
Note right of MainBot: Later, during download:
alt Task.UseUserClient is true
MainBot->>UserBotClient: Download file via UserBotClient API
UserBotClient->>Telegram: Download file bytes
Telegram-->>UserBotClient: File bytes
UserBotClient-->>MainBot: File bytes
else Task.UseUserClient is false
MainBot->>Telegram: Download file bytes via MainBot API
Telegram-->>MainBot: File bytes
end
ER Diagram for ReceivedFile Entity UpdateerDiagram
ReceivedFile {
int ID PK
string ChatID
string MessageID
string FileName
bool IsTelegraph
string TelegraphURL
bool UseUserClient "New: Whether to use userbot client to fetch the file"
}
Class Diagram for Configuration StructuresclassDiagram
class Config {
+String Lang
+Int Workers
+Int Retry
+Bool NoCleanCache
+Int Threads
+Bool Stream
+Bool AsPublicCopyMediaBot
+telegramConfig Telegram
+logConfig Log
+tempConfig Temp
+dbConfig DB
+List~StorageInterface~ Storages
}
class telegramConfig {
+String Token
+Int AppID
+String AppHash
+Int Timeout
+proxyConfig Proxy
+Int FloodRetry
+Int RpcRetry
+userbotConfig Userbot
}
class userbotConfig {
+Bool Enable
+String Session
}
class proxyConfig {
+Bool Enable
+String Url
}
Config *-- telegramConfig
telegramConfig *-- userbotConfig
telegramConfig *-- proxyConfig
Class Diagram for Updated Data ModelsclassDiagram
class ReceivedFile {
+int ID
+string ChatID
+string MessageID
+string FileName
+bool IsTelegraph
+string TelegraphURL
+bool UseUserClient
}
class Task {
+Context Ctx
+CancelFunc Cancel
+Error Error
+bool UseUserClient
+TaskStatus Status
+String StorageName
+String StoragePath
+Time StartTime
+uint FileDBID
+File File
+int FileMessageID
+int64 FileChatID
+int ReplyMessageID
+int64 ReplyChatID
+String UserID
}
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Hello @Silentely, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
Summary of Changes
As gemini-code-assist, I've reviewed this pull request titled "Origin". This PR introduces significant new functionality by integrating a Telegram user client alongside the existing bot client. The primary goal appears to be enabling the bot to access and process files and messages from sources that might be restricted for a standard bot, such as private channels or groups where the user client is a member. The changes involve adding a user client login and session management system, implementing logic to fall back to the user client for file fetching when the bot client encounters specific errors, and laying the groundwork for internationalization (i18n) by adding a new i18n package and updating various messages to be localizable.
Highlights
- User Client Integration: Adds support for logging in and using a Telegram user client (
gotd/td) to fetch files and messages, providing a fallback mechanism when the standard bot client fails, particularly for 'peer not found' or 'unexpected message type' errors. - Internationalization (i18n): Introduces a new i18n package (
go-i18n) with support for loading locale files (TOML) and provides functions for translating messages. Includes a command-line tool to generate Go constants for message keys. - Dependency Updates: Updates several dependencies, including
gotd/td, and adds new dependencies for i18n (go-i18n,pelletier/go-toml/v2), user client session storage (glebarez/sqlite), user client middlewares (cenkalti/backoff/v4), and terminal interaction for user client auth (charmbracelet/huh,charmbracelet/log,fatih/color). - Improved API Call Handling: Adds custom retry and recovery middlewares for the user client API calls to enhance robustness against transient errors.
Changelog
Click here to see the changelog
- bot/handle_add_task.go
- Imported
userclientpackage. - Added
UseUserClientboolean field totypes.Taskstruct. - Modified
AddToQueueto conditionally use the user client (userclient.UC) for fetching files ifrecord.UseUserClientis true and the user client is initialized.
- Imported
- bot/handle_link.go
- Imported
userclientpackage. - Added
tryFetchFileFromMessagefunction to attempt fetching a file with the bot client and fall back to the user client on specific errors. - Added
tryFetchMessagefunction as a wrapper forGetTGMessage. - Updated
handleLinkMessageto use the newtryFetchFileFromMessageandtryFetchMessagefunctions. - Stored the
useUserClientflag in thedao.ReceivedFilerecord and the created task.
- Imported
- bot/handle_start.go
- Changed the help message to display the full Git commit hash instead of a truncated one.
- bot/handlers.go
- Imported
extpackage. - Added handlers to ignore messages received in channels and chats (groups).
- Renamed the dispatcher variable from
dispatchertodisp.
- Imported
- cmd/geni18n/main.go
- Added a new command-line tool to generate Go constants for i18n message keys by parsing TOML locale files.
- cmd/run.go
- Imported
context,i18n,i18n/i18nk, anduserclientpackages. - Initialized the i18n system using
i18n.Init. - Added logic to log in the user client (
userclient.Login) if enabled in the configuration. - Updated various log and error messages to use the i18n translation function
i18n.T.
- Imported
- common/logger.go
- Removed the default channel name setting for the logger.
- Set a custom template format for console and file log handlers.
- common/os.go
- Updated log messages related to file removal to use i18n translation.
- config/viper.go
- Imported
errors,i18n, andi18n/i18nkpackages. - Added
Langfield to the mainConfigstruct. - Added
Userbotstruct withEnableandSessionfields totelegramConfig. - Set default values for
lang,telegram.userbot.enable, andtelegram.userbot.session. - Updated config validation error messages to use
i18n.TWithoutInit.
- Imported
- core/download.go
- Imported
userclientpackage. - Modified
processPendingTaskto use the user client's API (userclient.UC.API()) for downloading files if the task'sUseUserClientflag is true and the user client is available, otherwise uses the bot client's API.
- Imported
- dao/model.go
- Added a
UseUserClientboolean field to theReceivedFilestruct to track which client was used to fetch the file.
- Added a
- go.mod
- Updated dependencies, including
gotd/tdandduke-git/lancet/v2. - Added new dependencies:
cenkalti/backoff/v4,charmbracelet/huh,charmbracelet/log,fatih/color,nicksnyder/go-i18n/v2,pelletier/go-toml/v2,glebarez/sqlite.
- Updated dependencies, including
- go.sum
- Updated checksums for added and updated dependencies.
- i18n/i18n.go
- Added a new package for internationalization.
- Implements i18n using
go-i18n, loading messages from embedded TOML files. - Provides
Init,T,TWithLang, andTWithoutInitfunctions for translation.
- i18n/i18nk/keys.go
- Added a new file containing generated Go constants for i18n message IDs.
- i18n/locale/zh-Hans.toml
- Added a new locale file containing Chinese translations for various messages.
- types/task.go
- Added a
UseUserClientboolean field to theTaskstruct to indicate if the task should use the user client for operations.
- Added a
- userclient/auth.go
- Added a new file implementing a
gotgproto.AuthConversatorusingcharmbracelet/huhfor terminal-based user client authentication (phone number, code, 2FA password).
- Added a new file implementing a
- userclient/middlewares/middlewares.go
- Added a new file defining default middlewares for the user client, including recovery and retry.
- userclient/middlewares/recovery/recovery.go
- Added a new file implementing a recovery middleware using
cenkalti/backoffto handle non-Telegram business errors.
- Added a new file implementing a recovery middleware using
- userclient/middlewares/retry/retry.go
- Added a new file implementing a retry middleware for specific Telegram API errors.
- userclient/userclient.go
- Added a new package for managing the user client.
- Implements user client login using
gotgprotoand SQLite for session storage. - Uses the custom terminal auth conversator and default middlewares.
- Exports the user client instance (
UC) and a function to get its context (GetCtx).
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Code Review
This pull request introduces significant and valuable features: userbot client fallback and comprehensive internationalization. The implementation is largely robust, with good attention to configuration, logging, and error handling for the new userbot client. The i18n integration is well-done and will greatly improve the bot's usability.
I have one primary concern regarding the new message handlers in bot/handlers.go which might unintentionally prevent the bot from processing commands or links in group/channel chats. There are also a couple of minor points for consideration. Please see the detailed comments.
Summary of Findings
- Handler Order and Scope: New handlers in
bot/handlers.gofor channel and chat messages might prematurely terminate message processing, potentially preventing commands and other interactions in those chat types. This needs clarification on intended behavior. - Error String Matching for Userbot Fallback: In
bot/handle_link.go, the logic to trigger userbot fallback relies on specific error message strings, which could be brittle. A more robust error detection mechanism might be preferable. - Inconsistent Internationalization: A config loading error message in
cmd/run.goremains hardcoded in English, while other similar messages are internationalized. - Efficiency of
TWithoutInit: Thei18n.TWithoutInitfunction re-initializes a bundle on each call. This is acceptable for its current use in early startup/config phases but should be noted if its usage expands.
Merge Readiness
This pull request introduces excellent new features and shows a lot of good work. However, before merging, I strongly recommend addressing the high severity issue identified in bot/handlers.go concerning the new message handlers, as it could significantly impact the bot's functionality in group and channel chats. The medium severity items should also be considered for improvement. I am not authorized to approve pull requests, so please ensure these points are reviewed and resolved by the appropriate maintainers before merging.
| disp.AddHandler(handlers.NewMessage(filters.Message.ChatType(filters.ChatTypeChannel), func(ctx *ext.Context, u *ext.Update) error { | ||
| return dispatcher.EndGroups | ||
| })) |
There was a problem hiding this comment.
These new handlers for ChatTypeChannel and ChatTypeChat are placed at the beginning of the handler chain and return dispatcher.EndGroups. This means any message from a channel or a group chat will be caught by these handlers, and no subsequent handlers (like command handlers, link handlers, or even checkPermission) will be processed for those messages.
If the bot is intended to operate at all in channels or group chats (e.g., respond to commands from authorized users, process links posted there), this change will prevent that. The PR description mentions "Improve handler registration to ignore channel and chat messages early," which is good, but this implementation might be too broad if it's not intended to completely disable the bot in these chat types.
Could you clarify the intended behavior?
- Is the bot now meant to function only in private chats?
- If it should still work in groups/channels for certain actions (e.g., commands), how should these early-exit handlers be adjusted to allow that while still ignoring other irrelevant messages?
| if (strings.Contains(err.Error(), "peer not found") || strings.Contains(err.Error(), "unexpected message type")) && userclient.UC != nil { | ||
| common.Log.Warnf("无法获取文件 %d:%d, 尝试使用 userbot: %s", chatID, messageID, err) | ||
| uctx := userclient.GetCtx() | ||
| // TODO: 群组支持 | ||
| file, err = FileFromMessage(uctx, chatID, messageID, fileName) | ||
| if err == nil { | ||
| return file, true, nil | ||
| } | ||
| return nil, true, err | ||
| } |
There was a problem hiding this comment.
The condition strings.Contains(err.Error(), "peer not found") || strings.Contains(err.Error(), "unexpected message type") for deciding to use the userbot is quite specific. While these errors might currently cover the main scenarios where a userbot is beneficial, relying on specific error strings can be brittle if Telegram API error messages change or if other error types also signify a situation where the bot client lacks access but a user client might succeed.
Could we consider a more robust way to determine if a userbot attempt is warranted? Perhaps checking for specific error codes if available, or a broader category of permission-related errors?
| func InitAll() { | ||
| if err := config.Init(); err != nil { | ||
| fmt.Println("加载配置文件失败: ", err) | ||
| fmt.Println("Failed to load config:", err) |
There was a problem hiding this comment.
The error message "Failed to load config:" is hardcoded in English here, while other messages in this file and config/viper.go are being internationalized. Since i18n.Init() is called after config loading, if this message needs to be localized, i18n.TWithoutInit(config.Cfg.Lang, i18nk.YourKeyForConfigLoadFailure, map[string]any{"Error": err}) would be appropriate. Was this hardcoding intentional?
fmt.Println(i18n.TWithoutInit(config.Cfg.Lang, i18nk.ConfigLoadFailed, map[string]any{
"Error": err,
}))
Summary by Sourcery
Implement a userbot client fallback mechanism and embed internationalization throughout the application, upgrade dependencies, and refactor configuration, logging, and task handling to support localization and userbot features
New Features:
Enhancements:
Chores: