feat: add i18n support for backend API and Telegram bot (#797)

* feat: add i18n support for backend API and Telegram bot

- Add comprehensive i18n support for all backend API error messages (zh/en)
- Add /lang command for Telegram bot to set language preference
- Add bilingual command descriptions for Telegram bot
- Support per-user language preference stored in KV
- Global push uses DEFAULT_LANG, user push uses saved preference

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: improve Telegram bot language preference feature

- Add internationalized message for disabled language feature
- Fix hardcoded English message in /lang command
- Optimize getTgMessages calls (reduce from 3 to 1 call)
- Remove verbose comments for better code clarity
- Add TgLangFeatureDisabledMsg to i18n (zh/en)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Dream Hunter
2025-12-31 01:42:41 +08:00
committed by GitHub
co-authored by Claude Sonnet 4.5
parent 5e227d2b2d
commit 3ebe22115a
25 changed files with 762 additions and 276 deletions
+123
View File
@@ -46,6 +46,129 @@ const messages: LocaleMessages = {
PasswordLoginDisabledMsg: "Password login is disabled",
EmailPasswordRequiredMsg: "Email and password are required",
AddressNotFoundMsg: "Address not found",
// Common messages (merged similar ones)
OperationFailedMsg: "Operation failed",
RequiredFieldMsg: "Required field is missing",
InvalidInputMsg: "Invalid input",
// Address related
NameTooShortMsg: "Name is too short",
NameTooLongMsg: "Name is too long",
InvalidDomainMsg: "Invalid domain",
AddressAlreadyExistsMsg: "Address already exists",
MaxAddressCountReachedMsg: "Max address count reached",
AddressNotBindedMsg: "Address is not binded",
AddressAlreadyBindedMsg: "Address is already binded, please unbind first",
TargetUserNotFoundMsg: "Target user not found",
// Send mail related
NoBalanceMsg: "No balance",
AddressBlockedMsg: "Address is blocked",
SubjectEmptyMsg: "Subject is empty",
ContentEmptyMsg: "Content is empty",
AlreadyRequestedMsg: "Already requested",
EnableResendOrSmtpMsg: "Please enable resend or smtp for this domain",
EnableResendOrSmtpWithVerifiedMsg: "Please enable resend or smtp for this domain, or add recipient to verified address list",
InvalidToMailMsg: "Invalid recipient address",
// Admin related
InvalidAddressIdMsg: "Invalid address_id",
EnableKVMsg: "Please enable KV first",
EnableSendMailMsg: "Please enable SEND_MAIL first",
InvalidCleanupConfigMsg: "Invalid cleanType or cleanDays",
InvalidCleanTypeMsg: "Invalid cleanType",
EnableKVForMailVerifyMsg: "Please enable KV first if you want to enable mail verify",
VerifyMailDomainInvalidMsg: "VerifyMailSender domain must be in",
InvalidMaxAddressCountMsg: "Invalid maxAddressCount",
FailedDeleteUserMsg: "Failed to delete user",
InvalidUserIdMsg: "Invalid user_id",
InvalidRoleTextMsg: "Invalid role_text",
// SQL validation
SqlEmptyMsg: "SQL statement is empty",
SqlTooLongMsg: "SQL statement is too long (max 1000 characters)",
SqlOnlyDeleteMsg: "Only DELETE statements are allowed",
SqlSingleStatementMsg: "Only single SQL statement is allowed",
SqlNoCommentsMsg: "SQL comments are not allowed",
// Passkey related
InvalidPasskeyNameMsg: "Invalid passkey name",
PasskeyNotFoundMsg: "Passkey not found",
AuthenticationFailedMsg: "Authentication failed",
RegistrationFailedMsg: "Registration failed",
// Auto reply related
AutoReplyDisabledMsg: "Auto reply is disabled",
InvalidAutoReplyMsg: "Invalid subject or message",
SubjectOrMessageTooLongMsg: "Subject or message is too long",
// Bind address related
NoAddressOrUserTokenMsg: "No address or user token",
InvalidAddressOrUserTokenMsg: "Invalid address or user token",
// Pagination related
InvalidLimitMsg: "Invalid limit",
InvalidOffsetMsg: "Invalid offset",
// Clear inbox/sent items related
FailedClearInboxMsg: "Failed to clear inbox",
FailedClearSentItemsMsg: "Failed to clear sent items",
// Webhook related
WebhookNotAllowedForUserMsg: "Webhook settings is not allowed for this user",
// IP blacklist related
InvalidIpBlacklistSettingMsg: "Invalid IP blacklist setting",
BlacklistExceedsMaxSizeMsg: "Blacklist exceeds maximum size",
// Telegram bot messages
TgUnableGetUserInfoMsg: "Unable to get user info",
TgNoPermissionMsg: "You don't have permission to use this bot",
TgWelcomeMsg: "Welcome! You can open the mini app",
TgCurrentPrefixMsg: "Current prefix enabled:",
TgCurrentDomainsMsg: "Available domains:",
TgAvailableCommandsMsg: "Available commands:",
TgCreateSuccessMsg: "Address created successfully:",
TgCreateFailedMsg: "Failed to create address:",
TgBindSuccessMsg: "Binding successful:",
TgBindFailedMsg: "Binding failed:",
TgUnbindSuccessMsg: "Unbinding successful:",
TgUnbindFailedMsg: "Unbinding failed:",
TgDeleteSuccessMsg: "Deleted successfully:",
TgDeleteFailedMsg: "Delete failed:",
TgAddressListMsg: "Address list:",
TgGetAddressFailedMsg: "Failed to get address list:",
TgCleanSuccessMsg: "Invalid addresses cleaned:",
TgCurrentAddressListMsg: "Current address list:",
TgCleanFailedMsg: "Failed to clean invalid addresses:",
TgNotBoundAddressMsg: "This address is not bound:",
TgInvalidAddressMsg: "Invalid address",
TgNoMoreMailsMsg: "No more mails",
TgNoMailMsg: "No mail",
TgGetMailFailedMsg: "Failed to get mail:",
TgParseMailFailedMsg: "Failed to parse mail:",
TgViewMailBtnMsg: "View Mail",
TgPrevBtnMsg: "Prev",
TgNextBtnMsg: "Next",
TgPleaseInputCredentialMsg: "Please enter credential",
TgPleaseInputAddressMsg: "Please enter address",
TgAddressMsg: "Address:",
TgPasswordMsg: "Password:",
TgCredentialMsg: "Credential:",
TgNoSenderMsg: "No sender",
TgMsgTooLongMsg: "Message too long, please view in mini app",
TgParseFailedViewInAppMsg: "Parse failed, please view in mini app",
TgMaxAddressReachedMsg: "Maximum address limit reached",
TgMaxAddressReachedCleanMsg: "Maximum address limit reached, please /cleaninvalidaddress first",
TgInvalidCredentialMsg: "Invalid credential",
TgAddressNotYoursMsg: "This address does not belong to you",
TgLangSetSuccessMsg: "Language set successfully:",
TgCurrentLangMsg: "Current language:",
TgSelectLangMsg: "Please select language:",
TgNoPermissionViewMailMsg: "No permission to view this mail",
TgBotTokenRequiredMsg: "TELEGRAM_BOT_TOKEN is required",
TgLangFeatureDisabledMsg: "Language setting feature is disabled. System default language is used.",
}
export default messages;
+123
View File
@@ -44,4 +44,127 @@ export type LocaleMessages = {
PasswordLoginDisabledMsg: string
EmailPasswordRequiredMsg: string
AddressNotFoundMsg: string
// Common messages (merged similar ones)
OperationFailedMsg: string
RequiredFieldMsg: string
InvalidInputMsg: string
// Address related
NameTooShortMsg: string
NameTooLongMsg: string
InvalidDomainMsg: string
AddressAlreadyExistsMsg: string
MaxAddressCountReachedMsg: string
AddressNotBindedMsg: string
AddressAlreadyBindedMsg: string
TargetUserNotFoundMsg: string
// Send mail related
NoBalanceMsg: string
AddressBlockedMsg: string
SubjectEmptyMsg: string
ContentEmptyMsg: string
AlreadyRequestedMsg: string
EnableResendOrSmtpMsg: string
EnableResendOrSmtpWithVerifiedMsg: string
InvalidToMailMsg: string
// Admin related
InvalidAddressIdMsg: string
EnableKVMsg: string
EnableSendMailMsg: string
InvalidCleanupConfigMsg: string
InvalidCleanTypeMsg: string
EnableKVForMailVerifyMsg: string
VerifyMailDomainInvalidMsg: string
InvalidMaxAddressCountMsg: string
FailedDeleteUserMsg: string
InvalidUserIdMsg: string
InvalidRoleTextMsg: string
// SQL validation
SqlEmptyMsg: string
SqlTooLongMsg: string
SqlOnlyDeleteMsg: string
SqlSingleStatementMsg: string
SqlNoCommentsMsg: string
// Passkey related
InvalidPasskeyNameMsg: string
PasskeyNotFoundMsg: string
AuthenticationFailedMsg: string
RegistrationFailedMsg: string
// Auto reply related
AutoReplyDisabledMsg: string
InvalidAutoReplyMsg: string
SubjectOrMessageTooLongMsg: string
// Bind address related
NoAddressOrUserTokenMsg: string
InvalidAddressOrUserTokenMsg: string
// Pagination related
InvalidLimitMsg: string
InvalidOffsetMsg: string
// Clear inbox/sent items related
FailedClearInboxMsg: string
FailedClearSentItemsMsg: string
// Webhook related
WebhookNotAllowedForUserMsg: string
// IP blacklist related
InvalidIpBlacklistSettingMsg: string
BlacklistExceedsMaxSizeMsg: string
// Telegram bot messages
TgUnableGetUserInfoMsg: string
TgNoPermissionMsg: string
TgWelcomeMsg: string
TgCurrentPrefixMsg: string
TgCurrentDomainsMsg: string
TgAvailableCommandsMsg: string
TgCreateSuccessMsg: string
TgCreateFailedMsg: string
TgBindSuccessMsg: string
TgBindFailedMsg: string
TgUnbindSuccessMsg: string
TgUnbindFailedMsg: string
TgDeleteSuccessMsg: string
TgDeleteFailedMsg: string
TgAddressListMsg: string
TgGetAddressFailedMsg: string
TgCleanSuccessMsg: string
TgCurrentAddressListMsg: string
TgCleanFailedMsg: string
TgNotBoundAddressMsg: string
TgInvalidAddressMsg: string
TgNoMoreMailsMsg: string
TgNoMailMsg: string
TgGetMailFailedMsg: string
TgParseMailFailedMsg: string
TgViewMailBtnMsg: string
TgPrevBtnMsg: string
TgNextBtnMsg: string
TgPleaseInputCredentialMsg: string
TgPleaseInputAddressMsg: string
TgAddressMsg: string
TgPasswordMsg: string
TgCredentialMsg: string
TgNoSenderMsg: string
TgMsgTooLongMsg: string
TgParseFailedViewInAppMsg: string
TgMaxAddressReachedMsg: string
TgMaxAddressReachedCleanMsg: string
TgInvalidCredentialMsg: string
TgAddressNotYoursMsg: string
TgLangSetSuccessMsg: string
TgCurrentLangMsg: string
TgSelectLangMsg: string
TgNoPermissionViewMailMsg: string
TgBotTokenRequiredMsg: string
TgLangFeatureDisabledMsg: string
}
+123
View File
@@ -46,6 +46,129 @@ const messages: LocaleMessages = {
PasswordLoginDisabledMsg: "密码登录已禁用",
EmailPasswordRequiredMsg: "邮箱和密码不能为空",
AddressNotFoundMsg: "邮箱地址不存在",
// Common messages (merged similar ones)
OperationFailedMsg: "操作失败",
RequiredFieldMsg: "缺少必填字段",
InvalidInputMsg: "输入无效",
// Address related
NameTooShortMsg: "名称太短",
NameTooLongMsg: "名称太长",
InvalidDomainMsg: "无效的域名",
AddressAlreadyExistsMsg: "邮箱地址已存在",
MaxAddressCountReachedMsg: "已达到最大地址数量限制",
AddressNotBindedMsg: "邮箱地址未绑定",
AddressAlreadyBindedMsg: "邮箱地址已绑定, 请先解绑",
TargetUserNotFoundMsg: "目标用户不存在",
// Send mail related
NoBalanceMsg: "余额不足",
AddressBlockedMsg: "地址已被屏蔽",
SubjectEmptyMsg: "主题不能为空",
ContentEmptyMsg: "内容不能为空",
AlreadyRequestedMsg: "已经申请过了",
EnableResendOrSmtpMsg: "请先为此域名启用 resend 或 smtp",
EnableResendOrSmtpWithVerifiedMsg: "请先为此域名启用 resend 或 smtp,或将收件人添加到已验证地址列表",
InvalidToMailMsg: "收件人地址无效",
// Admin related
InvalidAddressIdMsg: "无效的 address_id",
EnableKVMsg: "请先启用 KV",
EnableSendMailMsg: "请先启用 SEND_MAIL",
InvalidCleanupConfigMsg: "无效的 cleanType 或 cleanDays",
InvalidCleanTypeMsg: "无效的 cleanType",
EnableKVForMailVerifyMsg: "如果要启用邮件验证,请先启用 KV",
VerifyMailDomainInvalidMsg: "验证邮件发送者域名必须在",
InvalidMaxAddressCountMsg: "无效的 maxAddressCount",
FailedDeleteUserMsg: "删除用户失败",
InvalidUserIdMsg: "无效的 user_id",
InvalidRoleTextMsg: "无效的 role_text",
// SQL validation
SqlEmptyMsg: "SQL 语句为空",
SqlTooLongMsg: "SQL 语句过长 (最大 1000 字符)",
SqlOnlyDeleteMsg: "只允许 DELETE 语句",
SqlSingleStatementMsg: "只允许单条 SQL 语句",
SqlNoCommentsMsg: "不允许 SQL 注释",
// Passkey related
InvalidPasskeyNameMsg: "无效的 passkey 名称",
PasskeyNotFoundMsg: "Passkey 不存在",
AuthenticationFailedMsg: "认证失败",
RegistrationFailedMsg: "注册失败",
// Auto reply related
AutoReplyDisabledMsg: "自动回复已禁用",
InvalidAutoReplyMsg: "无效的主题或消息",
SubjectOrMessageTooLongMsg: "主题或消息太长",
// Bind address related
NoAddressOrUserTokenMsg: "缺少地址或用户令牌",
InvalidAddressOrUserTokenMsg: "无效的地址或用户令牌",
// Pagination related
InvalidLimitMsg: "无效的 limit 参数",
InvalidOffsetMsg: "无效的 offset 参数",
// Clear inbox/sent items related
FailedClearInboxMsg: "清空收件箱失败",
FailedClearSentItemsMsg: "清空已发送邮件失败",
// Webhook related
WebhookNotAllowedForUserMsg: "此用户不允许使用 Webhook 设置",
// IP blacklist related
InvalidIpBlacklistSettingMsg: "无效的 IP 黑名单设置",
BlacklistExceedsMaxSizeMsg: "黑名单超出最大条目限制",
// Telegram bot messages
TgUnableGetUserInfoMsg: "无法获取用户信息",
TgNoPermissionMsg: "您没有权限使用此机器人",
TgWelcomeMsg: "欢迎使用本机器人, 您可以打开 mini app",
TgCurrentPrefixMsg: "当前已启用前缀:",
TgCurrentDomainsMsg: "当前可用域名:",
TgAvailableCommandsMsg: "请使用以下命令:",
TgCreateSuccessMsg: "创建地址成功:",
TgCreateFailedMsg: "创建地址失败:",
TgBindSuccessMsg: "绑定成功:",
TgBindFailedMsg: "绑定失败:",
TgUnbindSuccessMsg: "解绑成功:",
TgUnbindFailedMsg: "解绑失败:",
TgDeleteSuccessMsg: "删除成功:",
TgDeleteFailedMsg: "删除失败:",
TgAddressListMsg: "地址列表:",
TgGetAddressFailedMsg: "获取地址列表失败:",
TgCleanSuccessMsg: "清理无效地址成功:",
TgCurrentAddressListMsg: "当前地址列表:",
TgCleanFailedMsg: "清理无效地址失败:",
TgNotBoundAddressMsg: "未绑定此地址:",
TgInvalidAddressMsg: "无效地址",
TgNoMoreMailsMsg: "已经没有邮件了",
TgNoMailMsg: "无邮件",
TgGetMailFailedMsg: "获取邮件失败:",
TgParseMailFailedMsg: "解析邮件失败:",
TgViewMailBtnMsg: "查看邮件",
TgPrevBtnMsg: "上一条",
TgNextBtnMsg: "下一条",
TgPleaseInputCredentialMsg: "请输入凭证",
TgPleaseInputAddressMsg: "请输入地址",
TgAddressMsg: "地址:",
TgPasswordMsg: "密码:",
TgCredentialMsg: "凭证:",
TgNoSenderMsg: "无发件人",
TgMsgTooLongMsg: "消息过长请到 mini app 查看",
TgParseFailedViewInAppMsg: "解析失败,请打开 mini app 查看",
TgMaxAddressReachedMsg: "绑定地址数量已达上限",
TgMaxAddressReachedCleanMsg: "绑定地址数量已达上限, 请先 /cleaninvalidaddress",
TgInvalidCredentialMsg: "无效凭证",
TgAddressNotYoursMsg: "此地址不属于您",
TgLangSetSuccessMsg: "语言设置成功:",
TgCurrentLangMsg: "当前语言:",
TgSelectLangMsg: "请选择语言:",
TgNoPermissionViewMailMsg: "无权查看此邮件",
TgBotTokenRequiredMsg: "需要设置 TELEGRAM_BOT_TOKEN",
TgLangFeatureDisabledMsg: "语言设置功能已禁用,使用系统默认语言",
}
export default messages;