Skip to content

Commit c118f15

Browse files
authored
fix(contrib): handle matrix media placeholder captions (#572)
Recognize bridge-generated media captions like "Alice sent an image" so bridge messages keep the real sender and drop the duplicated placeholder caption. Also make the shared sender helper return the sender id for forwarded messages and stop guessing captionless media senders from recent cache. Reference: https://t.me/ArchlinuxCN_Appearance/294784
1 parent a4aeba5 commit c118f15

1 file changed

Lines changed: 68 additions & 46 deletions

File tree

contrib/telega-bridge-bot.el

Lines changed: 68 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,15 @@ If FORCE-UPDATE is non-nil, force update the file."
314314

315315
(defun telega-bridge-bot--matrix-file-spliter (text)
316316
"Split TEXT into username and message."
317-
;; Split with file type prefix
318-
(split-string text " sent \\(a file\\|an image\\|a video\\): "))
317+
(when (string-match
318+
"\\`\\(.+?\\) sent \\(a file\\|an image\\|a video\\)\\(?:: \\(.*\\)\\)?\\'"
319+
text)
320+
(list
321+
(match-string 1 text)
322+
;; Keep empty string for bridge-generated placeholder captions like
323+
;; \"Alice sent an image\" so caller can still replace sender and
324+
;; clear the duplicated caption.
325+
(or (match-string 3 text) ""))))
319326

320327

321328
;;; bridge
@@ -378,6 +385,23 @@ Return a string if STRING is non-nil."
378385
"Return cached bridge username for CHAT-ID and BOT-ID."
379386
(gethash (list chat-id bot-id) telega-bridge-bot--recent-counterparty-name))
380387

388+
(defun telega-bridge-bot--set-msg-sender (msg sender-id)
389+
"Set MSG sender to SENDER-ID."
390+
(plist-put msg :sender_id (list :@type "messageSenderUser" :user_id sender-id)))
391+
392+
(defun telega-bridge-bot--cached-msg-sender-name (msg chat-id bot-id)
393+
"Return bridge sender name for MSG using signature or recent cache."
394+
(or (telega-tl-str msg :author_signature)
395+
(telega-bridge-bot--cached-counterparty-name chat-id bot-id)))
396+
397+
(defun telega-bridge-bot--apply-bridge-sender (msg chat-id bot-id username)
398+
"Apply bridge sender USERNAME to MSG in CHAT-ID from BOT-ID."
399+
(let ((sender-id
400+
(telega-bridge-bot--update-user-info
401+
(telega--tl-get msg :id) chat-id bot-id username)))
402+
(telega-bridge-bot--set-msg-sender msg sender-id)
403+
sender-id))
404+
381405
(defun telega-bridge-bot--file-id (path)
382406
"Return file id based on PATH and modification time seconds."
383407
(let* ((mtime (file-attribute-modification-time (file-attributes path)))
@@ -463,16 +487,13 @@ If FORCE-UPDATE is non-nil, force update the user info."
463487

464488
(defun telega-bridge-bot--update-sticker (msg)
465489
"Update sender id in sticker MSG using recently resolved bridge username."
466-
(when-let* ((msg-id (telega--tl-get msg :id))
467-
(chat-id (telega--tl-get msg :chat_id))
490+
(when-let* ((chat-id (telega--tl-get msg :chat_id))
468491
(bot-id (telega--tl-get (telega-msg-sender msg) :id))
469492
(counterparty-info (telega-bridge-bot--counterparty-info chat-id bot-id))
470493
(content (telega--tl-get msg :content))
471494
(sticker-p (eq (telega--tl-type content) 'messageSticker))
472-
(name (or (telega-tl-str msg :author_signature)
473-
(telega-bridge-bot--cached-counterparty-name chat-id bot-id))))
474-
(let ((sender-id (telega-bridge-bot--update-user-info msg-id chat-id bot-id name)))
475-
(plist-put msg :sender_id (list :@type "messageSenderUser" :user_id sender-id)))))
495+
(name (telega-bridge-bot--cached-msg-sender-name msg chat-id bot-id)))
496+
(telega-bridge-bot--apply-bridge-sender msg chat-id bot-id name)))
476497

477498
(defun telega-bridge-bot--download-async-callback (chat-id msg-id)
478499
"Callback for `telega-bridge-bot--download-async'.
@@ -487,8 +508,7 @@ Will update CHAT-ID MSG-ID when download completed."
487508

488509
(defun telega-bridge-bot--update-fmt-text (msg)
489510
"Update sender id and remove duplicated username in MSG."
490-
(when-let* ((msg-id (telega--tl-get msg :id))
491-
(chat-id (telega--tl-get msg :chat_id))
511+
(when-let* ((chat-id (telega--tl-get msg :chat_id))
492512
(bot-id (telega--tl-get (telega-msg-sender msg) :id))
493513
(counterparty-info (telega-bridge-bot--counterparty-info chat-id bot-id)) ; check if it is a bridge bot
494514
(counterparty-type (plist-get counterparty-info :type))
@@ -503,44 +523,43 @@ Will update CHAT-ID MSG-ID when download completed."
503523
(name-and-body (funcall spliter content-text-text))
504524
(name (car name-and-body))
505525
(body (cadr name-and-body))) ; skip if no body
506-
(let ((sender-id (telega-bridge-bot--update-user-info msg-id chat-id bot-id name)))
507-
;; replace sender
508-
(plist-put msg :sender_id (list :@type "messageSenderUser" :user_id sender-id))
509-
;; remove duplicated username in body
510-
;; we don't use body directly here
511-
;; because then we only need to make sure the name is correct
512-
;; makes it easier to write the split function
513-
(plist-put
514-
content :text
515-
(telega-bridge-bot--remove-username content-text body)))))
526+
(let ((sender-id
527+
(telega-bridge-bot--apply-bridge-sender msg chat-id bot-id name)))
528+
(prog1 sender-id
529+
;; remove duplicated username in body
530+
;; we don't use body directly here
531+
;; because then we only need to make sure the name is correct
532+
;; makes it easier to write the split function
533+
(plist-put
534+
content :text
535+
(telega-bridge-bot--remove-username content-text body))))))
516536

517537
(defun telega-bridge-bot--update-file (msg)
518538
"Update sender id and remove file caption in MSG."
519-
(when-let* ((msg-id (telega--tl-get msg :id))
520-
(chat-id (telega--tl-get msg :chat_id))
539+
(when-let* ((chat-id (telega--tl-get msg :chat_id))
521540
(bot-id (telega--tl-get (telega-msg-sender msg) :id))
522541
(counterparty-info (telega-bridge-bot--counterparty-info chat-id bot-id)) ; check if it is a bridge bot
523542
(counterparty-type (plist-get counterparty-info :type))
524-
(content (telega--tl-get msg :content))
525-
(content-caption (telega--tl-get content :caption))
526-
(fmt-text-p (eq (telega--tl-type content-caption) 'formattedText))
527-
(content-caption-text (telega--tl-get content-caption :text)) ; get the msg text
528-
(spliter (telega--tl-get
529-
telega-bridge-bot--counterparty-handler-plist
530-
counterparty-type :file-spliter))
531-
(name-and-body (funcall spliter content-caption-text))
532-
(name (car name-and-body))
533-
(body (cadr name-and-body))) ; skip if no body
534-
(let ((sender-id (telega-bridge-bot--update-user-info msg-id chat-id bot-id name)))
535-
;; replace sender
536-
(plist-put msg :sender_id (list :@type "messageSenderUser" :user_id sender-id))
537-
;; remove caption
538-
(plist-put content :caption nil))))
543+
(content (telega--tl-get msg :content)))
544+
(let* ((content-caption (telega--tl-get content :caption))
545+
(content-caption-text (telega--tl-get content-caption :text))
546+
(spliter (telega--tl-get
547+
telega-bridge-bot--counterparty-handler-plist
548+
counterparty-type :file-spliter))
549+
(name-and-body (and content-caption-text
550+
(funcall spliter content-caption-text)))
551+
(name (car-safe name-and-body)))
552+
(when name
553+
(let ((sender-id
554+
(telega-bridge-bot--apply-bridge-sender
555+
msg chat-id bot-id name)))
556+
(prog1 sender-id
557+
;; remove bridge-generated caption when sender came from caption
558+
(plist-put content :caption nil)))))))
539559

540560
(defun telega-bridge-bot--update-forwarded (msg)
541561
"Update forwarded sender id and remove duplicated username in MSG."
542-
(when-let* ((msg-id (telega--tl-get msg :id))
543-
(forward-info (telega--tl-get msg :forward_info))
562+
(when-let* ((forward-info (telega--tl-get msg :forward_info))
544563
(fwd-info-p (eq (telega--tl-type forward-info) 'messageForwardInfo))
545564
(bot-id (telega--tl-get forward-info :origin :sender_user_id))
546565
(chat-id (telega--tl-get forward-info :from_chat_id))
@@ -556,13 +575,16 @@ Will update CHAT-ID MSG-ID when download completed."
556575
(name-and-body (funcall spliter content-text-text))
557576
(name (car name-and-body))
558577
(body (cadr name-and-body))) ; skip if no body
559-
(let ((sender-id (telega-bridge-bot--update-user-info msg-id chat-id bot-id name)))
560-
;; replace sender
561-
(plist-put forward-info :origin (list :@type "messageOriginUser" :sender_user_id sender-id))
562-
;; remove duplicated username in body
563-
(plist-put
564-
content :text
565-
(telega-bridge-bot--remove-username content-text body)))))
578+
(let ((sender-id
579+
(telega-bridge-bot--apply-bridge-sender msg chat-id bot-id name)))
580+
(prog1 sender-id
581+
;; replace sender
582+
(plist-put forward-info :origin
583+
(list :@type "messageOriginUser" :sender_user_id sender-id))
584+
;; remove duplicated username in body
585+
(plist-put
586+
content :text
587+
(telega-bridge-bot--remove-username content-text body))))))
566588

567589
(defun telega-bridge-bot--update-msg (msg &rest _)
568590
"Replace the sender in MSG with the other party's sender."

0 commit comments

Comments
 (0)