mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 11:28:38 +00:00
refactor: dedupe synology chat client webhook payloads
This commit is contained in:
@@ -27,6 +27,12 @@ type ChatUserCacheEntry = {
|
|||||||
cachedAt: number;
|
cachedAt: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type ChatWebhookPayload = {
|
||||||
|
text?: string;
|
||||||
|
file_url?: string;
|
||||||
|
user_ids?: number[];
|
||||||
|
};
|
||||||
|
|
||||||
// Cache user lists per bot endpoint to avoid cross-account bleed.
|
// Cache user lists per bot endpoint to avoid cross-account bleed.
|
||||||
const chatUserCache = new Map<string, ChatUserCacheEntry>();
|
const chatUserCache = new Map<string, ChatUserCacheEntry>();
|
||||||
const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
||||||
@@ -47,16 +53,7 @@ export async function sendMessage(
|
|||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
// Synology Chat API requires user_ids (numeric) to specify the recipient
|
// Synology Chat API requires user_ids (numeric) to specify the recipient
|
||||||
// The @mention is optional but user_ids is mandatory
|
// The @mention is optional but user_ids is mandatory
|
||||||
const payloadObj: Record<string, any> = { text };
|
const body = buildWebhookBody({ text }, userId);
|
||||||
if (userId) {
|
|
||||||
// userId can be numeric ID or username - if numeric, add to user_ids
|
|
||||||
const numericId = typeof userId === "number" ? userId : parseInt(userId, 10);
|
|
||||||
if (!isNaN(numericId)) {
|
|
||||||
payloadObj.user_ids = [numericId];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const payload = JSON.stringify(payloadObj);
|
|
||||||
const body = `payload=${encodeURIComponent(payload)}`;
|
|
||||||
|
|
||||||
// Internal rate limit: min 500ms between sends
|
// Internal rate limit: min 500ms between sends
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
@@ -95,15 +92,7 @@ export async function sendFileUrl(
|
|||||||
userId?: string | number,
|
userId?: string | number,
|
||||||
allowInsecureSsl = true,
|
allowInsecureSsl = true,
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const payloadObj: Record<string, any> = { file_url: fileUrl };
|
const body = buildWebhookBody({ file_url: fileUrl }, userId);
|
||||||
if (userId) {
|
|
||||||
const numericId = typeof userId === "number" ? userId : parseInt(userId, 10);
|
|
||||||
if (!isNaN(numericId)) {
|
|
||||||
payloadObj.user_ids = [numericId];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const payload = JSON.stringify(payloadObj);
|
|
||||||
const body = `payload=${encodeURIComponent(payload)}`;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const ok = await doPost(incomingUrl, body, allowInsecureSsl);
|
const ok = await doPost(incomingUrl, body, allowInsecureSsl);
|
||||||
@@ -215,6 +204,22 @@ export async function resolveChatUserId(
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildWebhookBody(payload: ChatWebhookPayload, userId?: string | number): string {
|
||||||
|
const numericId = parseNumericUserId(userId);
|
||||||
|
if (numericId !== undefined) {
|
||||||
|
payload.user_ids = [numericId];
|
||||||
|
}
|
||||||
|
return `payload=${encodeURIComponent(JSON.stringify(payload))}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseNumericUserId(userId?: string | number): number | undefined {
|
||||||
|
if (userId === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const numericId = typeof userId === "number" ? userId : parseInt(userId, 10);
|
||||||
|
return Number.isNaN(numericId) ? undefined : numericId;
|
||||||
|
}
|
||||||
|
|
||||||
function doPost(url: string, body: string, allowInsecureSsl = true): Promise<boolean> {
|
function doPost(url: string, body: string, allowInsecureSsl = true): Promise<boolean> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let parsedUrl: URL;
|
let parsedUrl: URL;
|
||||||
|
|||||||
Reference in New Issue
Block a user