mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-10 09:03:17 +08:00
Expose conversation/target session lookup for cron result mirroring.
Schedulers can resolve the live Harness session for a bot+target or conversationKey without changing proactive send() semantics. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
356538ac18
commit
01924e5f7e
8 changed files with 307 additions and 0 deletions
|
|
@ -100,6 +100,19 @@ export class ConversationStateStore {
|
|||
return this.#state.sessions[key] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Live conversationKey → sessionId bindings (excludes unbound provenance).
|
||||
* @returns {Array<{ conversationKey: string, sessionId: string }>}
|
||||
*/
|
||||
listLiveSessions() {
|
||||
return Object.entries(this.#state.sessions)
|
||||
.filter(([conversationKey, sessionId]) => (
|
||||
typeof conversationKey === 'string' && conversationKey
|
||||
&& typeof sessionId === 'string' && sessionId
|
||||
))
|
||||
.map(([conversationKey, sessionId]) => ({ conversationKey, sessionId }));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse-map a Harness session id to its conversation binding key.
|
||||
* Live bindings win; unbound sessions still resolve via sessionOrigins
|
||||
|
|
|
|||
42
src/channels/shared/delivery-session-keys.mjs
Normal file
42
src/channels/shared/delivery-session-keys.mjs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* Map a proactive-delivery target route to conversationKey candidates
|
||||
* so schedulers can resolve the live Harness session for that chat.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {object|null|undefined} target
|
||||
* @returns {string[]}
|
||||
*/
|
||||
export function conversationKeysFromDeliveryTarget(target) {
|
||||
if (!target || typeof target !== 'object') return [];
|
||||
const kind = typeof target.kind === 'string' ? target.kind.trim() : '';
|
||||
const route = target.route && typeof target.route === 'object' ? target.route : {};
|
||||
const jid = String(route.jid || route.chatId || route.openId || route.userId || '')
|
||||
.trim();
|
||||
if (!jid) return [];
|
||||
|
||||
if (kind === 'group' || jid.endsWith('@g.us')) {
|
||||
const groupJid = jid.toLowerCase().endsWith('@g.us') ? jid : `${jid}`;
|
||||
return [`group:${groupJid}`];
|
||||
}
|
||||
|
||||
// DM / user targets: prefer the native jid; phone-shaped ids already include @s.whatsapp.net.
|
||||
return [`direct:${jid}`];
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a live conversationKey belongs to a delivery target.
|
||||
* Groups accept both shared (`group:jid`) and per-user (`group:jid:user:…`) bindings.
|
||||
* @param {string} conversationKey
|
||||
* @param {object|null|undefined} target
|
||||
*/
|
||||
export function conversationKeyMatchesTarget(conversationKey, target) {
|
||||
const key = typeof conversationKey === 'string' ? conversationKey.trim() : '';
|
||||
if (!key) return false;
|
||||
const candidates = conversationKeysFromDeliveryTarget(target);
|
||||
for (const candidate of candidates) {
|
||||
if (key === candidate) return true;
|
||||
if (candidate.startsWith('group:') && key.startsWith(`${candidate}:user:`)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue