mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-05 15:20:23 +00:00
refactor(slack): move Slack channel code to extensions/slack/src/ (#45621)
Move all Slack channel implementation files from src/slack/ to extensions/slack/src/ and replace originals with shim re-exports. This follows the extension migration pattern for channel plugins. - Copy all .ts files to extensions/slack/src/ (preserving directory structure: monitor/, http/, monitor/events/, monitor/message-handler/) - Transform import paths: external src/ imports use relative paths back to src/, internal slack imports stay relative within extension - Replace all src/slack/ files with shim re-exports pointing to the extension copies - Update tsconfig.plugin-sdk.dts.json rootDir from "src" to "." so the DTS build can follow shim chains into extensions/ - Update write-plugin-sdk-entry-dts.ts re-export path accordingly - Preserve extensions/slack/index.ts, package.json, openclaw.plugin.json, src/channel.ts, src/runtime.ts, src/channel.test.ts (untouched)
This commit is contained in:
79
extensions/slack/src/sent-thread-cache.ts
Normal file
79
extensions/slack/src/sent-thread-cache.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { resolveGlobalMap } from "../../../src/shared/global-singleton.js";
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Keep Slack thread participation shared across bundled chunks so thread
|
||||
* auto-reply gating does not diverge between prepare/dispatch call paths.
|
||||
*/
|
||||
const SLACK_THREAD_PARTICIPATION_KEY = Symbol.for("openclaw.slackThreadParticipation");
|
||||
|
||||
const threadParticipation = resolveGlobalMap<string, number>(SLACK_THREAD_PARTICIPATION_KEY);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function evictOldest(): void {
|
||||
const oldest = threadParticipation.keys().next().value;
|
||||
if (oldest) {
|
||||
threadParticipation.delete(oldest);
|
||||
}
|
||||
}
|
||||
|
||||
export function recordSlackThreadParticipation(
|
||||
accountId: string,
|
||||
channelId: string,
|
||||
threadTs: string,
|
||||
): void {
|
||||
if (!accountId || !channelId || !threadTs) {
|
||||
return;
|
||||
}
|
||||
if (threadParticipation.size >= MAX_ENTRIES) {
|
||||
evictExpired();
|
||||
}
|
||||
if (threadParticipation.size >= MAX_ENTRIES) {
|
||||
evictOldest();
|
||||
}
|
||||
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