mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-12 20:32:54 +00:00
feat(slack): track thread participation for auto-reply without @mention (#29165)
* feat(slack): track thread participation for auto-reply without @mention * fix(slack): scope thread participation cache by accountId and capture actual reply thread ts * fix(slack): capture reply thread ts from all delivery paths and only after success * Slack: add changelog for thread participation cache behavior --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
61
src/slack/sent-thread-cache.ts
Normal file
61
src/slack/sent-thread-cache.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* In-memory cache of Slack threads the bot has participated in.
|
||||
* Used to auto-respond in threads without requiring @mention after the first reply.
|
||||
* Follows a similar TTL pattern to the MS Teams and Telegram sent-message caches.
|
||||
*/
|
||||
|
||||
const TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
||||
const MAX_ENTRIES = 5000;
|
||||
|
||||
const threadParticipation = new Map<string, number>();
|
||||
|
||||
function makeKey(accountId: string, channelId: string, threadTs: string): string {
|
||||
return `${accountId}:${channelId}:${threadTs}`;
|
||||
}
|
||||
|
||||
function evictExpired(): void {
|
||||
const now = Date.now();
|
||||
for (const [key, timestamp] of threadParticipation) {
|
||||
if (now - timestamp > TTL_MS) {
|
||||
threadParticipation.delete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function recordSlackThreadParticipation(
|
||||
accountId: string,
|
||||
channelId: string,
|
||||
threadTs: string,
|
||||
): void {
|
||||
if (!accountId || !channelId || !threadTs) {
|
||||
return;
|
||||
}
|
||||
if (threadParticipation.size >= MAX_ENTRIES) {
|
||||
evictExpired();
|
||||
}
|
||||
threadParticipation.set(makeKey(accountId, channelId, threadTs), Date.now());
|
||||
}
|
||||
|
||||
export function hasSlackThreadParticipation(
|
||||
accountId: string,
|
||||
channelId: string,
|
||||
threadTs: string,
|
||||
): boolean {
|
||||
if (!accountId || !channelId || !threadTs) {
|
||||
return false;
|
||||
}
|
||||
const key = makeKey(accountId, channelId, threadTs);
|
||||
const timestamp = threadParticipation.get(key);
|
||||
if (timestamp == null) {
|
||||
return false;
|
||||
}
|
||||
if (Date.now() - timestamp > TTL_MS) {
|
||||
threadParticipation.delete(key);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export function clearSlackThreadParticipationCache(): void {
|
||||
threadParticipation.clear();
|
||||
}
|
||||
Reference in New Issue
Block a user