mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-04 18:20:22 +00:00
refactor: dedupe msteams lowercase helpers
This commit is contained in:
@@ -1,3 +1,7 @@
|
|||||||
|
import {
|
||||||
|
normalizeLowercaseStringOrEmpty,
|
||||||
|
normalizeOptionalLowercaseString,
|
||||||
|
} from "openclaw/plugin-sdk/text-runtime";
|
||||||
import { fetchWithSsrFGuard, type SsrFPolicy } from "../../runtime-api.js";
|
import { fetchWithSsrFGuard, type SsrFPolicy } from "../../runtime-api.js";
|
||||||
import { getMSTeamsRuntime } from "../runtime.js";
|
import { getMSTeamsRuntime } from "../runtime.js";
|
||||||
import { ensureUserAgentHeader } from "../user-agent.js";
|
import { ensureUserAgentHeader } from "../user-agent.js";
|
||||||
@@ -46,7 +50,7 @@ export function buildMSTeamsGraphMessageUrls(params: {
|
|||||||
conversationMessageId?: string | null;
|
conversationMessageId?: string | null;
|
||||||
channelData?: unknown;
|
channelData?: unknown;
|
||||||
}): string[] {
|
}): string[] {
|
||||||
const conversationType = params.conversationType?.trim().toLowerCase() ?? "";
|
const conversationType = normalizeLowercaseStringOrEmpty(params.conversationType ?? "");
|
||||||
const messageIdCandidates = new Set<string>();
|
const messageIdCandidates = new Set<string>();
|
||||||
const pushCandidate = (value: string | null | undefined) => {
|
const pushCandidate = (value: string | null | undefined) => {
|
||||||
const trimmed = typeof value === "string" ? value.trim() : "";
|
const trimmed = typeof value === "string" ? value.trim() : "";
|
||||||
@@ -382,7 +386,7 @@ export async function downloadMSTeamsGraphMedia(params: {
|
|||||||
const filteredAttachments =
|
const filteredAttachments =
|
||||||
sharePointMedia.length > 0
|
sharePointMedia.length > 0
|
||||||
? normalizedAttachments.filter((att) => {
|
? normalizedAttachments.filter((att) => {
|
||||||
const contentType = att.contentType?.toLowerCase();
|
const contentType = normalizeOptionalLowercaseString(att.contentType);
|
||||||
if (contentType !== "reference") {
|
if (contentType !== "reference") {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,11 @@ import {
|
|||||||
normalizeHostnameSuffixAllowlist,
|
normalizeHostnameSuffixAllowlist,
|
||||||
type SsrFPolicy,
|
type SsrFPolicy,
|
||||||
} from "openclaw/plugin-sdk/ssrf-policy";
|
} from "openclaw/plugin-sdk/ssrf-policy";
|
||||||
import { isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
import {
|
||||||
|
isRecord,
|
||||||
|
normalizeLowercaseStringOrEmpty,
|
||||||
|
normalizeOptionalString,
|
||||||
|
} from "openclaw/plugin-sdk/text-runtime";
|
||||||
import type { MSTeamsAttachmentLike } from "./types.js";
|
import type { MSTeamsAttachmentLike } from "./types.js";
|
||||||
|
|
||||||
type InlineImageCandidate =
|
type InlineImageCandidate =
|
||||||
@@ -119,9 +123,9 @@ export function inferPlaceholder(params: {
|
|||||||
fileName?: string;
|
fileName?: string;
|
||||||
fileType?: string;
|
fileType?: string;
|
||||||
}): string {
|
}): string {
|
||||||
const mime = params.contentType?.toLowerCase() ?? "";
|
const mime = normalizeLowercaseStringOrEmpty(params.contentType ?? "");
|
||||||
const name = params.fileName?.toLowerCase() ?? "";
|
const name = normalizeLowercaseStringOrEmpty(params.fileName ?? "");
|
||||||
const fileType = params.fileType?.toLowerCase() ?? "";
|
const fileType = normalizeLowercaseStringOrEmpty(params.fileType ?? "");
|
||||||
|
|
||||||
const looksLikeImage =
|
const looksLikeImage =
|
||||||
mime.startsWith("image/") || IMAGE_EXT_RE.test(name) || IMAGE_EXT_RE.test(`x.${fileType}`);
|
mime.startsWith("image/") || IMAGE_EXT_RE.test(name) || IMAGE_EXT_RE.test(`x.${fileType}`);
|
||||||
@@ -232,7 +236,7 @@ function decodeDataImageWithLimits(
|
|||||||
if (!match) {
|
if (!match) {
|
||||||
return { candidate: null, estimatedBytes: 0 };
|
return { candidate: null, estimatedBytes: 0 };
|
||||||
}
|
}
|
||||||
const contentType = match[1]?.toLowerCase();
|
const contentType = normalizeLowercaseStringOrEmpty(match[1] ?? "");
|
||||||
const isBase64 = Boolean(match[2]);
|
const isBase64 = Boolean(match[2]);
|
||||||
if (!isBase64) {
|
if (!isBase64) {
|
||||||
return { candidate: null, estimatedBytes: 0 };
|
return { candidate: null, estimatedBytes: 0 };
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
* 6. Optionally sends a proactive follow-up to the user
|
* 6. Optionally sends a proactive follow-up to the user
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime";
|
||||||
import {
|
import {
|
||||||
dispatchReplyFromConfigWithSettledDispatcher,
|
dispatchReplyFromConfigWithSettledDispatcher,
|
||||||
type OpenClawConfig,
|
type OpenClawConfig,
|
||||||
@@ -241,7 +242,9 @@ export async function runFeedbackReflection(params: RunFeedbackReflectionParams)
|
|||||||
log.debug?.("failed to store reflection learning", { error: formatUnknownError(err) });
|
log.debug?.("failed to store reflection learning", { error: formatUnknownError(err) });
|
||||||
}
|
}
|
||||||
|
|
||||||
const conversationType = params.conversationRef.conversation?.conversationType?.toLowerCase();
|
const conversationType = normalizeOptionalLowercaseString(
|
||||||
|
params.conversationRef.conversation?.conversationType,
|
||||||
|
);
|
||||||
const shouldNotify =
|
const shouldNotify =
|
||||||
conversationType === "personal" &&
|
conversationType === "personal" &&
|
||||||
parsedReflection.followUp &&
|
parsedReflection.followUp &&
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
* and messenger.ts (reply path) to avoid duplication.
|
* and messenger.ts (reply path) to avoid duplication.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime";
|
||||||
import { buildFileConsentCard } from "./file-consent.js";
|
import { buildFileConsentCard } from "./file-consent.js";
|
||||||
import { storePendingUpload } from "./pending-uploads.js";
|
import { storePendingUpload } from "./pending-uploads.js";
|
||||||
|
|
||||||
@@ -66,7 +67,7 @@ export function requiresFileConsent(params: {
|
|||||||
bufferSize: number;
|
bufferSize: number;
|
||||||
thresholdBytes: number;
|
thresholdBytes: number;
|
||||||
}): boolean {
|
}): boolean {
|
||||||
const isPersonal = params.conversationType?.toLowerCase() === "personal";
|
const isPersonal = normalizeOptionalLowercaseString(params.conversationType) === "personal";
|
||||||
const isImage = params.contentType?.startsWith("image/") ?? false;
|
const isImage = params.contentType?.startsWith("image/") ?? false;
|
||||||
const isLargeFile = params.bufferSize >= params.thresholdBytes;
|
const isLargeFile = params.bufferSize >= params.thresholdBytes;
|
||||||
return isPersonal && (isLargeFile || !isImage);
|
return isPersonal && (isLargeFile || !isImage);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime";
|
||||||
import {
|
import {
|
||||||
createChannelReplyPipeline,
|
createChannelReplyPipeline,
|
||||||
logTypingFailure,
|
logTypingFailure,
|
||||||
@@ -47,7 +48,9 @@ export function createMSTeamsReplyDispatcher(params: {
|
|||||||
}) {
|
}) {
|
||||||
const core = getMSTeamsRuntime();
|
const core = getMSTeamsRuntime();
|
||||||
const msteamsCfg = params.cfg.channels?.msteams;
|
const msteamsCfg = params.cfg.channels?.msteams;
|
||||||
const conversationType = params.conversationRef.conversation?.conversationType?.toLowerCase();
|
const conversationType = normalizeOptionalLowercaseString(
|
||||||
|
params.conversationRef.conversation?.conversationType,
|
||||||
|
);
|
||||||
const isTypingSupported = conversationType === "personal" || conversationType === "groupchat";
|
const isTypingSupported = conversationType === "personal" || conversationType === "groupchat";
|
||||||
|
|
||||||
const sendTypingIndicator = isTypingSupported
|
const sendTypingIndicator = isTypingSupported
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime";
|
||||||
import type { ReplyPayload } from "../runtime-api.js";
|
import type { ReplyPayload } from "../runtime-api.js";
|
||||||
import { formatUnknownError } from "./errors.js";
|
import { formatUnknownError } from "./errors.js";
|
||||||
import type { MSTeamsMonitorLogger } from "./monitor-types.js";
|
import type { MSTeamsMonitorLogger } from "./monitor-types.js";
|
||||||
@@ -23,7 +24,7 @@ export function createTeamsReplyStreamController(params: {
|
|||||||
log: MSTeamsMonitorLogger;
|
log: MSTeamsMonitorLogger;
|
||||||
random?: () => number;
|
random?: () => number;
|
||||||
}) {
|
}) {
|
||||||
const isPersonal = params.conversationType?.toLowerCase() === "personal";
|
const isPersonal = normalizeOptionalLowercaseString(params.conversationType) === "personal";
|
||||||
const stream = isPersonal
|
const stream = isPersonal
|
||||||
? new TeamsHttpStream({
|
? new TeamsHttpStream({
|
||||||
sendActivity: (activity) => params.context.sendActivity(activity),
|
sendActivity: (activity) => params.context.sendActivity(activity),
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
import { mapAllowlistResolutionInputs } from "openclaw/plugin-sdk/allow-from";
|
import { mapAllowlistResolutionInputs } from "openclaw/plugin-sdk/allow-from";
|
||||||
|
import {
|
||||||
|
normalizeLowercaseStringOrEmpty,
|
||||||
|
normalizeOptionalLowercaseString,
|
||||||
|
} from "openclaw/plugin-sdk/text-runtime";
|
||||||
import { searchGraphUsers } from "./graph-users.js";
|
import { searchGraphUsers } from "./graph-users.js";
|
||||||
import {
|
import {
|
||||||
listChannelsForTeam,
|
listChannelsForTeam,
|
||||||
@@ -135,7 +139,9 @@ export async function resolveMSTeamsChannelAllowlist(params: {
|
|||||||
} catch {
|
} catch {
|
||||||
// API failure (rate limit, network error) — fall back to Graph GUID as team key
|
// API failure (rate limit, network error) — fall back to Graph GUID as team key
|
||||||
}
|
}
|
||||||
const generalChannel = teamChannels.find((ch) => ch.displayName?.toLowerCase() === "general");
|
const generalChannel = teamChannels.find(
|
||||||
|
(ch) => normalizeOptionalLowercaseString(ch.displayName) === "general",
|
||||||
|
);
|
||||||
// Use the General channel's conversation ID as the team key — this
|
// Use the General channel's conversation ID as the team key — this
|
||||||
// matches what Bot Framework sends at runtime. Fall back to the Graph
|
// matches what Bot Framework sends at runtime. Fall back to the Graph
|
||||||
// GUID if the General channel isn't found (renamed or deleted).
|
// GUID if the General channel isn't found (renamed or deleted).
|
||||||
@@ -150,11 +156,14 @@ export async function resolveMSTeamsChannelAllowlist(params: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
// Reuse teamChannels — already fetched above
|
// Reuse teamChannels — already fetched above
|
||||||
|
const normalizedChannel = normalizeOptionalLowercaseString(channel);
|
||||||
const channelMatch =
|
const channelMatch =
|
||||||
teamChannels.find((item) => item.id === channel) ??
|
teamChannels.find((item) => item.id === channel) ??
|
||||||
teamChannels.find((item) => item.displayName?.toLowerCase() === channel.toLowerCase()) ??
|
teamChannels.find(
|
||||||
|
(item) => normalizeOptionalLowercaseString(item.displayName) === normalizedChannel,
|
||||||
|
) ??
|
||||||
teamChannels.find((item) =>
|
teamChannels.find((item) =>
|
||||||
item.displayName?.toLowerCase().includes(channel.toLowerCase() ?? ""),
|
normalizeLowercaseStringOrEmpty(item.displayName ?? "").includes(normalizedChannel ?? ""),
|
||||||
);
|
);
|
||||||
if (!channelMatch?.id) {
|
if (!channelMatch?.id) {
|
||||||
return { input, resolved: false, note: "channel not found" };
|
return { input, resolved: false, note: "channel not found" };
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
stripTargetKindPrefix,
|
stripTargetKindPrefix,
|
||||||
type ChannelOutboundSessionRouteParams,
|
type ChannelOutboundSessionRouteParams,
|
||||||
} from "openclaw/plugin-sdk/core";
|
} from "openclaw/plugin-sdk/core";
|
||||||
|
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||||
|
|
||||||
export function resolveMSTeamsOutboundSessionRoute(params: ChannelOutboundSessionRouteParams) {
|
export function resolveMSTeamsOutboundSessionRoute(params: ChannelOutboundSessionRouteParams) {
|
||||||
let trimmed = stripChannelTargetPrefix(params.target, "msteams", "teams");
|
let trimmed = stripChannelTargetPrefix(params.target, "msteams", "teams");
|
||||||
@@ -11,7 +12,7 @@ export function resolveMSTeamsOutboundSessionRoute(params: ChannelOutboundSessio
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lower = trimmed.toLowerCase();
|
const lower = normalizeLowercaseStringOrEmpty(trimmed);
|
||||||
const isUser = lower.startsWith("user:");
|
const isUser = lower.startsWith("user:");
|
||||||
const rawId = stripTargetKindPrefix(trimmed);
|
const rawId = stripTargetKindPrefix(trimmed);
|
||||||
if (!rawId) {
|
if (!rawId) {
|
||||||
|
|||||||
Reference in New Issue
Block a user