refactor!: rename chat providers to channels
This commit is contained in:
80
src/channels/plugins/whatsapp-heartbeat.ts
Normal file
80
src/channels/plugins/whatsapp-heartbeat.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { normalizeChatChannelId } from "../../channels/registry.js";
|
||||
import type { ClawdbotConfig } from "../../config/config.js";
|
||||
import { loadSessionStore, resolveStorePath } from "../../config/sessions.js";
|
||||
import { normalizeE164 } from "../../utils.js";
|
||||
|
||||
type HeartbeatRecipientsResult = { recipients: string[]; source: string };
|
||||
type HeartbeatRecipientsOpts = { to?: string; all?: boolean };
|
||||
|
||||
function getSessionRecipients(cfg: ClawdbotConfig) {
|
||||
const sessionCfg = cfg.session;
|
||||
const scope = sessionCfg?.scope ?? "per-sender";
|
||||
if (scope === "global") return [];
|
||||
const storePath = resolveStorePath(cfg.session?.store);
|
||||
const store = loadSessionStore(storePath);
|
||||
const isGroupKey = (key: string) =>
|
||||
key.startsWith("group:") ||
|
||||
key.includes(":group:") ||
|
||||
key.includes(":channel:") ||
|
||||
key.includes("@g.us");
|
||||
const isCronKey = (key: string) => key.startsWith("cron:");
|
||||
|
||||
const recipients = Object.entries(store)
|
||||
.filter(([key]) => key !== "global" && key !== "unknown")
|
||||
.filter(([key]) => !isGroupKey(key) && !isCronKey(key))
|
||||
.map(([_, entry]) => ({
|
||||
to:
|
||||
normalizeChatChannelId(entry?.lastChannel) === "whatsapp" &&
|
||||
entry?.lastTo
|
||||
? normalizeE164(entry.lastTo)
|
||||
: "",
|
||||
updatedAt: entry?.updatedAt ?? 0,
|
||||
}))
|
||||
.filter(({ to }) => to.length > 1)
|
||||
.sort((a, b) => b.updatedAt - a.updatedAt);
|
||||
|
||||
// Dedupe while preserving recency ordering.
|
||||
const seen = new Set<string>();
|
||||
return recipients.filter((r) => {
|
||||
if (seen.has(r.to)) return false;
|
||||
seen.add(r.to);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
export function resolveWhatsAppHeartbeatRecipients(
|
||||
cfg: ClawdbotConfig,
|
||||
opts: HeartbeatRecipientsOpts = {},
|
||||
): HeartbeatRecipientsResult {
|
||||
if (opts.to) {
|
||||
return { recipients: [normalizeE164(opts.to)], source: "flag" };
|
||||
}
|
||||
|
||||
const sessionRecipients = getSessionRecipients(cfg);
|
||||
const allowFrom =
|
||||
Array.isArray(cfg.channels?.whatsapp?.allowFrom) &&
|
||||
cfg.channels.whatsapp.allowFrom.length > 0
|
||||
? cfg.channels.whatsapp.allowFrom
|
||||
.filter((v) => v !== "*")
|
||||
.map(normalizeE164)
|
||||
: [];
|
||||
|
||||
const unique = (list: string[]) => [...new Set(list.filter(Boolean))];
|
||||
|
||||
if (opts.all) {
|
||||
const all = unique([...sessionRecipients.map((s) => s.to), ...allowFrom]);
|
||||
return { recipients: all, source: "all" };
|
||||
}
|
||||
|
||||
if (sessionRecipients.length === 1) {
|
||||
return { recipients: [sessionRecipients[0].to], source: "session-single" };
|
||||
}
|
||||
if (sessionRecipients.length > 1) {
|
||||
return {
|
||||
recipients: sessionRecipients.map((s) => s.to),
|
||||
source: "session-ambiguous",
|
||||
};
|
||||
}
|
||||
|
||||
return { recipients: allowFrom, source: "allowFrom" };
|
||||
}
|
||||
Reference in New Issue
Block a user