mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 05:57:28 +00:00
fix(slack): land #26878 allowlist channel ID case-insensitive match (thanks @lbo728)
Land contributor PR #26878 from @lbo728; include changelog credit and regression tests. Co-authored-by: lbo728 <extreme0728@gmail.com>
This commit is contained in:
@@ -49,6 +49,7 @@ Docs: https://docs.openclaw.ai
|
|||||||
- Discord/Typing indicator: prevent stuck typing indicators by sealing channel typing keepalive callbacks after idle/cleanup and ensuring Discord dispatch always marks typing idle even if preview-stream cleanup fails. (#26295) Thanks @ngutman.
|
- Discord/Typing indicator: prevent stuck typing indicators by sealing channel typing keepalive callbacks after idle/cleanup and ensuring Discord dispatch always marks typing idle even if preview-stream cleanup fails. (#26295) Thanks @ngutman.
|
||||||
- Channels/Typing indicator: guard typing keepalive start callbacks after idle/cleanup close so post-close ticks cannot re-trigger stale typing indicators. (#26325) Thanks @win4r.
|
- Channels/Typing indicator: guard typing keepalive start callbacks after idle/cleanup close so post-close ticks cannot re-trigger stale typing indicators. (#26325) Thanks @win4r.
|
||||||
- Followups/Typing indicator: ensure followup turns mark dispatch idle on every exit path (including `NO_REPLY`, empty payloads, and agent errors) so typing keepalive cleanup always runs and channel typing indicators do not get stuck after queued/silent followups. (#26881) Thanks @codexGW.
|
- Followups/Typing indicator: ensure followup turns mark dispatch idle on every exit path (including `NO_REPLY`, empty payloads, and agent errors) so typing keepalive cleanup always runs and channel typing indicators do not get stuck after queued/silent followups. (#26881) Thanks @codexGW.
|
||||||
|
- Slack/Allowlist channels: match channel IDs case-insensitively during channel allowlist resolution so lowercase config keys (for example `c0abc12345`) correctly match Slack runtime IDs (`C0ABC12345`) under `groupPolicy: "allowlist"`, preventing silent channel-event drops. (#26878) Thanks @lbo728.
|
||||||
- Tests/Low-memory stability: disable Vitest `vmForks` by default on low-memory local hosts (`<64 GiB`), keep low-profile extension lane parallelism at 4 workers, and align cron isolated-agent tests with `setSessionRuntimeModel` usage to avoid deterministic suite failures. (#26324) Thanks @ngutman.
|
- Tests/Low-memory stability: disable Vitest `vmForks` by default on low-memory local hosts (`<64 GiB`), keep low-profile extension lane parallelism at 4 workers, and align cron isolated-agent tests with `setSessionRuntimeModel` usage to avoid deterministic suite failures. (#26324) Thanks @ngutman.
|
||||||
- Slack/Inbound media fallback: deliver file-only messages even when Slack media downloads fail by adding a filename placeholder fallback, capping fallback names to the shared media-file limit, and normalizing empty filenames to `file` so attachment-only messages are not silently dropped. (#25181) Thanks @justinhuangcode.
|
- Slack/Inbound media fallback: deliver file-only messages even when Slack media downloads fail by adding a filename placeholder fallback, capping fallback names to the shared media-file limit, and normalizing empty filenames to `file` so attachment-only messages are not silently dropped. (#25181) Thanks @justinhuangcode.
|
||||||
|
|
||||||
|
|||||||
@@ -96,8 +96,16 @@ export function resolveSlackChannelConfig(params: {
|
|||||||
const keys = Object.keys(entries);
|
const keys = Object.keys(entries);
|
||||||
const normalizedName = channelName ? normalizeSlackSlug(channelName) : "";
|
const normalizedName = channelName ? normalizeSlackSlug(channelName) : "";
|
||||||
const directName = channelName ? channelName.trim() : "";
|
const directName = channelName ? channelName.trim() : "";
|
||||||
|
// Slack always delivers channel IDs in uppercase (e.g. C0ABC12345) but
|
||||||
|
// operators commonly write them in lowercase in their config. Add both
|
||||||
|
// case variants so the lookup is case-insensitive without requiring a full
|
||||||
|
// entry-scan. buildChannelKeyCandidates deduplicates identical keys.
|
||||||
|
const channelIdLower = channelId.toLowerCase();
|
||||||
|
const channelIdUpper = channelId.toUpperCase();
|
||||||
const candidates = buildChannelKeyCandidates(
|
const candidates = buildChannelKeyCandidates(
|
||||||
channelId,
|
channelId,
|
||||||
|
channelIdLower !== channelId ? channelIdLower : undefined,
|
||||||
|
channelIdUpper !== channelId ? channelIdUpper : undefined,
|
||||||
channelName ? `#${directName}` : undefined,
|
channelName ? `#${directName}` : undefined,
|
||||||
directName,
|
directName,
|
||||||
normalizedName,
|
normalizedName,
|
||||||
|
|||||||
@@ -60,6 +60,27 @@ describe("resolveSlackChannelConfig", () => {
|
|||||||
matchSource: "direct",
|
matchSource: "direct",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("matches channel config key stored in lowercase when Slack delivers uppercase channel ID", () => {
|
||||||
|
// Slack always delivers channel IDs in uppercase (e.g. C0ABC12345).
|
||||||
|
// Users commonly copy them in lowercase from docs or older CLI output.
|
||||||
|
const res = resolveSlackChannelConfig({
|
||||||
|
channelId: "C0ABC12345",
|
||||||
|
channels: { c0abc12345: { allow: true, requireMention: false } },
|
||||||
|
defaultRequireMention: true,
|
||||||
|
});
|
||||||
|
expect(res).toMatchObject({ allowed: true, requireMention: false });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("matches channel config key stored in uppercase when user types lowercase channel ID", () => {
|
||||||
|
// Defensive: also handle the inverse direction.
|
||||||
|
const res = resolveSlackChannelConfig({
|
||||||
|
channelId: "c0abc12345",
|
||||||
|
channels: { C0ABC12345: { allow: true, requireMention: false } },
|
||||||
|
defaultRequireMention: true,
|
||||||
|
});
|
||||||
|
expect(res).toMatchObject({ allowed: true, requireMention: false });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const baseParams = () => ({
|
const baseParams = () => ({
|
||||||
|
|||||||
Reference in New Issue
Block a user