diff --git a/pkg/channels/telegram.go b/pkg/channels/telegram.go index bfb78a7f6..b0607d143 100644 --- a/pkg/channels/telegram.go +++ b/pkg/channels/telegram.go @@ -169,12 +169,14 @@ func (c *TelegramChannel) Send(ctx context.Context, msg bus.OutboundMessage) err limit = 4000 // Default Telegram limit (~4096) } - // Telegram HTML tags (like
) can expand content significantly.
- // We use a safe headroom for the markdown-based split, but never exceed
- // the configured limit.
- effectiveMarkdownLimit := limit - 500
+ // Use a percentage-based headroom for the markdown-based split, but never
+ // exceed the configured limit. This scales better for large messages with
+ // extensive formatting or code blocks.
+ effectiveMarkdownLimit := int(float64(limit) * 0.8) // ~80% of limit
if effectiveMarkdownLimit < 1 {
effectiveMarkdownLimit = 1
+ } else if effectiveMarkdownLimit >= limit {
+ effectiveMarkdownLimit = limit - 1
}
chunks := utils.SplitMessage(msg.Content, effectiveMarkdownLimit)
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 02766341e..00c95365c 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -195,10 +195,9 @@ type ChannelsConfig struct {
}
type WhatsAppConfig struct {
- Enabled bool `json:"enabled" env:"PICOCLAW_CHANNELS_WHATSAPP_ENABLED"`
- BridgeURL string `json:"bridge_url" env:"PICOCLAW_CHANNELS_WHATSAPP_BRIDGE_URL"`
- AllowFrom FlexibleStringSlice `json:"allow_from" env:"PICOCLAW_CHANNELS_WHATSAPP_ALLOW_FROM"`
- MaxMessageLength int `json:"max_message_length,omitempty" env:"PICOCLAW_CHANNELS_WHATSAPP_MAX_MESSAGE_LENGTH"`
+ Enabled bool `json:"enabled" env:"PICOCLAW_CHANNELS_WHATSAPP_ENABLED"`
+ BridgeURL string `json:"bridge_url" env:"PICOCLAW_CHANNELS_WHATSAPP_BRIDGE_URL"`
+ AllowFrom FlexibleStringSlice `json:"allow_from" env:"PICOCLAW_CHANNELS_WHATSAPP_ALLOW_FROM"`
}
type TelegramConfig struct {
@@ -216,7 +215,6 @@ type FeishuConfig struct {
EncryptKey string `json:"encrypt_key" env:"PICOCLAW_CHANNELS_FEISHU_ENCRYPT_KEY"`
VerificationToken string `json:"verification_token" env:"PICOCLAW_CHANNELS_FEISHU_VERIFICATION_TOKEN"`
AllowFrom FlexibleStringSlice `json:"allow_from" env:"PICOCLAW_CHANNELS_FEISHU_ALLOW_FROM"`
- MaxMessageLength int `json:"max_message_length,omitempty" env:"PICOCLAW_CHANNELS_FEISHU_MAX_MESSAGE_LENGTH"`
}
type DiscordConfig struct {
@@ -235,19 +233,17 @@ type MaixCamConfig struct {
}
type QQConfig struct {
- Enabled bool `json:"enabled" env:"PICOCLAW_CHANNELS_QQ_ENABLED"`
- AppID string `json:"app_id" env:"PICOCLAW_CHANNELS_QQ_APP_ID"`
- AppSecret string `json:"app_secret" env:"PICOCLAW_CHANNELS_QQ_APP_SECRET"`
- AllowFrom FlexibleStringSlice `json:"allow_from" env:"PICOCLAW_CHANNELS_QQ_ALLOW_FROM"`
- MaxMessageLength int `json:"max_message_length,omitempty" env:"PICOCLAW_CHANNELS_QQ_MAX_MESSAGE_LENGTH"`
+ Enabled bool `json:"enabled" env:"PICOCLAW_CHANNELS_QQ_ENABLED"`
+ AppID string `json:"app_id" env:"PICOCLAW_CHANNELS_QQ_APP_ID"`
+ AppSecret string `json:"app_secret" env:"PICOCLAW_CHANNELS_QQ_APP_SECRET"`
+ AllowFrom FlexibleStringSlice `json:"allow_from" env:"PICOCLAW_CHANNELS_QQ_ALLOW_FROM"`
}
type DingTalkConfig struct {
- Enabled bool `json:"enabled" env:"PICOCLAW_CHANNELS_DINGTALK_ENABLED"`
- ClientID string `json:"client_id" env:"PICOCLAW_CHANNELS_DINGTALK_CLIENT_ID"`
- ClientSecret string `json:"client_secret" env:"PICOCLAW_CHANNELS_DINGTALK_CLIENT_SECRET"`
- AllowFrom FlexibleStringSlice `json:"allow_from" env:"PICOCLAW_CHANNELS_DINGTALK_ALLOW_FROM"`
- MaxMessageLength int `json:"max_message_length,omitempty" env:"PICOCLAW_CHANNELS_DINGTALK_MAX_MESSAGE_LENGTH"`
+ Enabled bool `json:"enabled" env:"PICOCLAW_CHANNELS_DINGTALK_ENABLED"`
+ ClientID string `json:"client_id" env:"PICOCLAW_CHANNELS_DINGTALK_CLIENT_ID"`
+ ClientSecret string `json:"client_secret" env:"PICOCLAW_CHANNELS_DINGTALK_CLIENT_SECRET"`
+ AllowFrom FlexibleStringSlice `json:"allow_from" env:"PICOCLAW_CHANNELS_DINGTALK_ALLOW_FROM"`
}
type SlackConfig struct {
@@ -276,7 +272,6 @@ type OneBotConfig struct {
ReconnectInterval int `json:"reconnect_interval" env:"PICOCLAW_CHANNELS_ONEBOT_RECONNECT_INTERVAL"`
GroupTriggerPrefix []string `json:"group_trigger_prefix" env:"PICOCLAW_CHANNELS_ONEBOT_GROUP_TRIGGER_PREFIX"`
AllowFrom FlexibleStringSlice `json:"allow_from" env:"PICOCLAW_CHANNELS_ONEBOT_ALLOW_FROM"`
- MaxMessageLength int `json:"max_message_length,omitempty" env:"PICOCLAW_CHANNELS_ONEBOT_MAX_MESSAGE_LENGTH"`
}
type WeComConfig struct {
diff --git a/pkg/utils/message.go b/pkg/utils/message.go
index 0c91d99f9..4bb51074e 100644
--- a/pkg/utils/message.go
+++ b/pkg/utils/message.go
@@ -106,6 +106,10 @@ func SplitMessage(content string, maxLen int) []string {
msgEndOffset = startIndex + innerLimit
}
+ if msgEndOffset > len(runes) {
+ msgEndOffset = len(runes)
+ }
+
chunkStr := string(runes[startIndex:msgEndOffset])
messages = append(messages, strings.TrimRight(chunkStr, " \t\n\r")+"\n```")
@@ -138,6 +142,9 @@ func SplitMessage(content string, maxLen int) []string {
} else {
// Hard split inside (last resort)
msgEndOffset = startIndex + maxLen - 5
+ if msgEndOffset > len(runes) {
+ msgEndOffset = len(runes)
+ }
chunkStr := string(runes[startIndex:msgEndOffset])
messages = append(messages, strings.TrimRight(chunkStr, " \t\n\r")+"\n```")