fix: unify inbound sender labels

This commit is contained in:
Peter Steinberger
2026-01-17 05:21:02 +00:00
parent 572e04d5fb
commit f7089cde54
20 changed files with 587 additions and 40 deletions

View File

@@ -41,4 +41,11 @@ describe("formatInboundBodyWithSenderMeta", () => {
"[X] hi\n[from: Alice (A1)]",
);
});
it("does not append when the body already includes a sender prefix", () => {
const ctx: MsgContext = { ChatType: "group", SenderName: "Alice", SenderId: "A1" };
expect(formatInboundBodyWithSenderMeta({ ctx, body: "Alice (A1): hi" })).toBe(
"Alice (A1): hi",
);
});
});

View File

@@ -1,28 +1,43 @@
import type { MsgContext } from "../templating.js";
import { normalizeChatType } from "../../channels/chat-type.js";
import { listSenderLabelCandidates, resolveSenderLabel } from "../../channels/sender-label.js";
export function formatInboundBodyWithSenderMeta(params: { body: string; ctx: MsgContext }): string {
const body = params.body;
if (!body.trim()) return body;
const chatType = normalizeChatType(params.ctx.ChatType);
if (!chatType || chatType === "direct") return body;
if (hasSenderMetaLine(body)) return body;
if (hasSenderMetaLine(body, params.ctx)) return body;
const senderLabel = formatSenderLabel(params.ctx);
const senderLabel = resolveSenderLabel({
name: params.ctx.SenderName,
username: params.ctx.SenderUsername,
tag: params.ctx.SenderTag,
e164: params.ctx.SenderE164,
id: params.ctx.SenderId,
});
if (!senderLabel) return body;
return `${body}\n[from: ${senderLabel}]`;
}
function hasSenderMetaLine(body: string): boolean {
return /(^|\n)\[from:/i.test(body);
function hasSenderMetaLine(body: string, ctx: MsgContext): boolean {
if (/(^|\n)\[from:/i.test(body)) return true;
const candidates = listSenderLabelCandidates({
name: ctx.SenderName,
username: ctx.SenderUsername,
tag: ctx.SenderTag,
e164: ctx.SenderE164,
id: ctx.SenderId,
});
if (candidates.length === 0) return false;
return candidates.some((candidate) => {
const escaped = escapeRegExp(candidate);
const pattern = new RegExp(`(^|\\n)${escaped}:\\s`, "i");
return pattern.test(body);
});
}
function formatSenderLabel(ctx: MsgContext): string | null {
const senderName = ctx.SenderName?.trim();
const senderId = (ctx.SenderE164?.trim() || ctx.SenderId?.trim()) ?? "";
if (senderName && senderId && senderName !== senderId) {
return `${senderName} (${senderId})`;
}
return senderName ?? (senderId || null);
function escapeRegExp(value: string): string {
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}