feat(web): prime group sessions with member roster
This commit is contained in:
@@ -413,6 +413,25 @@ export async function getReplyFromConfig(
|
||||
isFirstTurnInSession && sessionCfg?.sessionIntro
|
||||
? applyTemplate(sessionCfg.sessionIntro, sessionCtx)
|
||||
: "";
|
||||
const groupIntro =
|
||||
isFirstTurnInSession && sessionCtx.ChatType === "group"
|
||||
? (() => {
|
||||
const subject = sessionCtx.GroupSubject?.trim();
|
||||
const members = sessionCtx.GroupMembers?.trim();
|
||||
const subjectLine = subject
|
||||
? `You are replying inside the WhatsApp group "${subject}".`
|
||||
: "You are replying inside a WhatsApp group chat.";
|
||||
const membersLine = members
|
||||
? `Group members: ${members}.`
|
||||
: undefined;
|
||||
return [subjectLine, membersLine]
|
||||
.filter(Boolean)
|
||||
.join(" ")
|
||||
.concat(
|
||||
" Address the specific sender noted in the message context.",
|
||||
);
|
||||
})()
|
||||
: "";
|
||||
const bodyPrefix = reply?.bodyPrefix
|
||||
? applyTemplate(reply.bodyPrefix, sessionCtx)
|
||||
: "";
|
||||
@@ -430,6 +449,9 @@ export async function getReplyFromConfig(
|
||||
if (sessionIntro) {
|
||||
prefixedBodyBase = `${sessionIntro}\n\n${prefixedBodyBase}`;
|
||||
}
|
||||
if (groupIntro) {
|
||||
prefixedBodyBase = `${groupIntro}\n\n${prefixedBodyBase}`;
|
||||
}
|
||||
if (abortedHint) {
|
||||
prefixedBodyBase = `${abortedHint}\n\n${prefixedBodyBase}`;
|
||||
if (sessionEntry && sessionStore && sessionKey) {
|
||||
|
||||
@@ -7,6 +7,11 @@ export type MsgContext = {
|
||||
MediaUrl?: string;
|
||||
MediaType?: string;
|
||||
Transcript?: string;
|
||||
ChatType?: string;
|
||||
GroupSubject?: string;
|
||||
GroupMembers?: string;
|
||||
SenderName?: string;
|
||||
SenderE164?: string;
|
||||
};
|
||||
|
||||
export type TemplateContext = MsgContext & {
|
||||
|
||||
@@ -766,6 +766,11 @@ export async function monitorWebProvider(
|
||||
MediaPath: latest.mediaPath,
|
||||
MediaUrl: latest.mediaUrl,
|
||||
MediaType: latest.mediaType,
|
||||
ChatType: latest.chatType,
|
||||
GroupSubject: latest.groupSubject,
|
||||
GroupMembers: latest.groupParticipants?.join(", "),
|
||||
SenderName: latest.senderName,
|
||||
SenderE164: latest.senderE164,
|
||||
},
|
||||
{
|
||||
onReplyStart: latest.sendComposing,
|
||||
|
||||
@@ -39,6 +39,8 @@ export type WebInboundMessage = {
|
||||
senderJid?: string;
|
||||
senderE164?: string;
|
||||
senderName?: string;
|
||||
groupSubject?: string;
|
||||
groupParticipants?: string[];
|
||||
mentionedJids?: string[];
|
||||
selfJid?: string | null;
|
||||
selfE164?: string | null;
|
||||
@@ -73,6 +75,33 @@ export async function monitorWebInbox(options: {
|
||||
const selfJid = sock.user?.id;
|
||||
const selfE164 = selfJid ? jidToE164(selfJid) : null;
|
||||
const seen = new Set<string>();
|
||||
const groupMetaCache = new Map<
|
||||
string,
|
||||
{ subject?: string; participants?: string[]; expires: number }
|
||||
>();
|
||||
const GROUP_META_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
||||
|
||||
const getGroupMeta = async (jid: string) => {
|
||||
const cached = groupMetaCache.get(jid);
|
||||
if (cached && cached.expires > Date.now()) return cached;
|
||||
try {
|
||||
const meta = await sock.groupMetadata(jid);
|
||||
const participants =
|
||||
meta.participants
|
||||
?.map((p) => jidToE164(p.id) ?? p.id)
|
||||
.filter(Boolean) ?? [];
|
||||
const entry = {
|
||||
subject: meta.subject,
|
||||
participants,
|
||||
expires: Date.now() + GROUP_META_TTL_MS,
|
||||
};
|
||||
groupMetaCache.set(jid, entry);
|
||||
return entry;
|
||||
} catch (err) {
|
||||
logVerbose(`Failed to fetch group metadata for ${jid}: ${String(err)}`);
|
||||
return { expires: Date.now() + GROUP_META_TTL_MS };
|
||||
}
|
||||
};
|
||||
|
||||
sock.ev.on("messages.upsert", async (upsert) => {
|
||||
if (upsert.type !== "notify") return;
|
||||
@@ -109,6 +138,13 @@ export async function monitorWebInbox(options: {
|
||||
const from = group ? remoteJid : jidToE164(remoteJid);
|
||||
// Skip if we still can't resolve an id to key conversation
|
||||
if (!from) continue;
|
||||
let groupSubject: string | undefined;
|
||||
let groupParticipants: string[] | undefined;
|
||||
if (group) {
|
||||
const meta = await getGroupMeta(remoteJid);
|
||||
groupSubject = meta.subject;
|
||||
groupParticipants = meta.participants;
|
||||
}
|
||||
|
||||
// Filter unauthorized senders early to prevent wasted processing
|
||||
// and potential session corruption from Bad MAC errors
|
||||
@@ -197,6 +233,8 @@ export async function monitorWebInbox(options: {
|
||||
senderJid: participantJid,
|
||||
senderE164: senderE164 ?? undefined,
|
||||
senderName,
|
||||
groupSubject,
|
||||
groupParticipants,
|
||||
mentionedJids: mentionedJids ?? undefined,
|
||||
selfJid,
|
||||
selfE164,
|
||||
|
||||
Reference in New Issue
Block a user