fix(messages): sync recognize configured app link entities
This commit is contained in:
parent
35d3908660
commit
c9371c6048
12 changed files with 327 additions and 72 deletions
|
|
@ -6,6 +6,8 @@ import (
|
|||
"unicode/utf8"
|
||||
|
||||
"github.com/iamxvbaba/td/tg"
|
||||
|
||||
"telesrv/internal/links"
|
||||
)
|
||||
|
||||
// 服务端自动实体检测:@mention / #hashtag / $cashtag / bot command。
|
||||
|
|
@ -24,16 +26,15 @@ import (
|
|||
// augmentAutoEntities 在客户端已发实体基础上补充服务端检测的自动实体。补充项与任何
|
||||
// 已有实体(客户端富文本意图实体或先补入的自动实体)区间相交时丢弃,避免把 mention/
|
||||
// hashtag 打进 code/pre/textUrl/已有 mentionName 内部或彼此重叠(对齐官方不重复打实体)。
|
||||
// 客户端已带 url/textUrl 实体(自行检测过,如 DrKLO)时跳过 url 检测,沿用既有口径。
|
||||
// 客户端实体保持在前(超过上限裁剪时优先保留),结果裁剪到实体上限。
|
||||
func augmentAutoEntities(message string, entities []tg.MessageEntityClass) []tg.MessageEntityClass {
|
||||
// URL 按跨度逐条补缺,不能因客户端带了某一条 HTTP URL 就跳过同消息中客户端不认识的
|
||||
// app-link。客户端实体保持在前(超过上限裁剪时优先保留),结果裁剪到实体上限。
|
||||
func augmentAutoEntities(message string, entities []tg.MessageEntityClass, appLinks links.AppLinkBuilder) []tg.MessageEntityClass {
|
||||
// 快路径:绝大多数消息不含任何可自动识别的触发字符。单次 ContainsAny 扫描即短路返回,
|
||||
// 跳过下面各检测器对全文的扫描与区间分配(纯文本发送零额外开销)。所有 http(s) 链接
|
||||
// 都含 '/',故 "@#$/" 一并覆盖 url 检测;email/phone 未实现故不在触发集内。
|
||||
if message == "" || !strings.ContainsAny(message, "@#$/") {
|
||||
return entities
|
||||
}
|
||||
hasClientURL := false
|
||||
type interval struct{ start, end int }
|
||||
occupied := make([]interval, 0, len(entities)+8)
|
||||
for _, e := range entities {
|
||||
|
|
@ -41,10 +42,6 @@ func augmentAutoEntities(message string, entities []tg.MessageEntityClass) []tg.
|
|||
off := e.GetOffset()
|
||||
occupied = append(occupied, interval{off, off + ln})
|
||||
}
|
||||
switch e.(type) {
|
||||
case *tg.MessageEntityURL, *tg.MessageEntityTextURL:
|
||||
hasClientURL = true
|
||||
}
|
||||
}
|
||||
overlaps := func(s, e int) bool {
|
||||
for _, iv := range occupied {
|
||||
|
|
@ -75,9 +72,9 @@ func augmentAutoEntities(message string, entities []tg.MessageEntityClass) []tg.
|
|||
}
|
||||
|
||||
// URL 跨度始终计算并加入排除区(occupied),使 @mention/#hashtag 等不会落进 URL 路径内部
|
||||
// (如 https://t.me/@scam 的 @scam,既不符官方语义也是钓鱼风险);但仅在客户端未带任何
|
||||
// url/textUrl 实体时才作为实体下发,沿用 all-or-nothing(DrKLO 一带即全带;TDesktop 不带、依赖服务端)。
|
||||
for _, u := range detectURLEntities(message) {
|
||||
// (如 https://t.me/@scam 的 @scam,既不符官方语义也是钓鱼风险)。逐跨度补缺可覆盖
|
||||
// “客户端带 HTTP entity、但不认识 telesrv://”的混合消息,同时仍避免重复实体。
|
||||
for _, u := range detectURLEntities(message, appLinks) {
|
||||
ln := u.GetLength()
|
||||
if ln <= 0 {
|
||||
continue
|
||||
|
|
@ -87,7 +84,7 @@ func augmentAutoEntities(message string, entities []tg.MessageEntityClass) []tg.
|
|||
continue
|
||||
}
|
||||
occupied = append(occupied, interval{off, off + ln})
|
||||
if !hasClientURL && len(entities)+len(extra) < maxMessageEntityCount {
|
||||
if len(entities)+len(extra) < maxMessageEntityCount {
|
||||
extra = append(extra, u)
|
||||
}
|
||||
}
|
||||
|
|
@ -114,6 +111,10 @@ func augmentAutoEntities(message string, entities []tg.MessageEntityClass) []tg.
|
|||
return append(out, extra...)
|
||||
}
|
||||
|
||||
func (r *Router) augmentAutoEntities(message string, entities []tg.MessageEntityClass) []tg.MessageEntityClass {
|
||||
return augmentAutoEntities(message, entities, r.appLinks)
|
||||
}
|
||||
|
||||
// isWordRune 判定「单词字符」(用于实体前导边界:前一个字符是单词字符时不是新实体起点,
|
||||
// 借此排除 email 的 local@domain、路径里的 and/or 等)。
|
||||
func isWordRune(r rune) bool {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue