matrixfmt: cut off long messages

This commit is contained in:
Tulir Asokan
2026-05-05 17:55:24 +03:00
parent fa599cb358
commit 9d1fb4609b
3 changed files with 64 additions and 3 deletions

View File

@@ -431,6 +431,38 @@ func parseRandomID(txnID networkid.RawTransactionID) int64 {
return rand.Int64()
}
func (tc *TelegramClient) getMaxMessageLength(ctx context.Context, isMedia bool) (val int) {
if !isMedia {
return 4096
}
config, err := tc.getAppConfigCached(ctx)
if err != nil {
return 1024
}
myGhost, err := tc.main.Bridge.GetGhostByID(ctx, tc.userID)
if err != nil {
return 1024
}
isPremium := myGhost.Metadata.(*GhostMetadata).IsPremium
if isPremium {
val = 4096
} else {
val = 1024
}
tc.isPremiumCache.Store(isPremium)
var configLimit float64
var ok bool
if isPremium {
configLimit, ok = config["caption_length_limit_premium"].(float64)
} else {
configLimit, ok = config["caption_length_limit_default"].(float64)
}
if ok {
val = int(configLimit)
}
return
}
func (tc *TelegramClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.MatrixMessage) (resp *bridgev2.MatrixMessageResponse, err error) {
if msg.Portal.RoomType == database.RoomTypeSpace {
return nil, fmt.Errorf("can't send messages to space portals")
@@ -455,7 +487,7 @@ func (tc *TelegramClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2
noWebpage := msg.Content.BeeperLinkPreviews != nil && len(msg.Content.BeeperLinkPreviews) == 0
message, entities := matrixfmt.Parse(ctx, tc.matrixParser, msg.Content, msg.Portal)
message, entities := matrixfmt.Parse(ctx, tc.matrixParser, msg.Content, msg.Portal, tc.getMaxMessageLength(ctx, msg.Content.MsgType.IsMedia()))
var replyTo tg.InputReplyToClass
if msg.ReplyTo != nil {
@@ -657,7 +689,7 @@ func (tc *TelegramClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.Ma
return err
}
message, entities := matrixfmt.Parse(ctx, tc.matrixParser, msg.Content, msg.Portal)
message, entities := matrixfmt.Parse(ctx, tc.matrixParser, msg.Content, msg.Portal, tc.getMaxMessageLength(ctx, msg.Content.MsgType.IsMedia()))
var newContentURI id.ContentURIString
req := tg.MessagesEditMessageRequest{

View File

@@ -88,7 +88,9 @@ func toTelegramEntity(br telegramfmt.BodyRange) tg.MessageEntityClass {
}
}
func Parse(ctx context.Context, parser *HTMLParser, content *event.MessageEventContent, portal *bridgev2.Portal) (string, []tg.MessageEntityClass) {
const cutoffText = " [long message cut off]"
func Parse(ctx context.Context, parser *HTMLParser, content *event.MessageEventContent, portal *bridgev2.Portal, maxLength int) (string, []tg.MessageEntityClass) {
if content.MsgType.IsMedia() && (content.FileName == "" || content.FileName == content.Body) {
// The body is the filename.
return "", nil
@@ -103,6 +105,10 @@ func Parse(ctx context.Context, parser *HTMLParser, content *event.MessageEventC
if parsed == nil {
return "", nil
}
if len(parsed.String) > maxLength {
cutoffTextEntity := NewEntityString(cutoffText).Format(telegramfmt.Style{Type: telegramfmt.StyleItalic})
parsed = parsed.Substring(maxLength - len(cutoffText)).Append(cutoffTextEntity)
}
var entities []tg.MessageEntityClass
if len(parsed.Entities) > 0 {
entities = make([]tg.MessageEntityClass, len(parsed.Entities))

View File

@@ -211,6 +211,29 @@ func (es *EntityString) AppendString(other string) *EntityString {
return es
}
func (es *EntityString) Substring(end int) *EntityString {
if es == nil {
return nil
}
if end >= len(es.String) {
return es
}
DebugLog("SUBSTRING %d %q %+v\n", end, es.String, es.Entities)
newEntities := make(telegramfmt.BodyRangeList, 0, len(es.Entities))
for _, ent := range es.Entities {
ent = *ent.TruncateEnd(end)
if ent.Length > 0 {
newEntities = append(newEntities, ent)
}
}
newES := &EntityString{
String: es.String[:end],
Entities: newEntities,
}
DebugLog(" -> %q %+v\n", newES.String, newES.Entities)
return newES
}
type TagStack []string
func (ts TagStack) Index(tag string) int {