mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
fix(feishu): correct invalid scope name in permission grant URL (#32509)
* fix(feishu): correct invalid scope name in permission grant URL The Feishu API returns error code 99991672 with an authorization URL containing the non-existent scope `contact:contact.base:readonly` when the `contact.user.get` endpoint is called without the correct permission. The valid scope is `contact:user.base:readonly`. Add a scope correction map that replaces known incorrect scope names in the extracted grant URL before presenting it to the user/agent, so the authorization link actually works. Closes #31761 * chore(changelog): note feishu scope correction --------- Co-authored-by: SidQin-cyber <sidqin0410@gmail.com>
This commit is contained in:
@@ -158,6 +158,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Feishu/Probe failure backoff: cache API and timeout probe failures for one minute per account key while preserving abort-aware probe timeouts, reducing repeated health-check retries during transient credential/network outages. (#29970)
|
||||
- Feishu/Streaming block fallback: preserve markdown block stream text as final streaming-card content when final payload text is missing, while still suppressing non-card internal block chunk delivery. (#30663)
|
||||
- Feishu/Bitable API errors: unify Feishu Bitable tool error handling with structured `LarkApiError` responses and consistent API/context attribution across wiki/base metadata, field, and record operations. (#31450)
|
||||
- Feishu/Missing-scope grant URL fix: rewrite known invalid scope aliases (`contact:contact.base:readonly`) to valid scope names in permission grant links, so remediation URLs open with correct Feishu consent scopes. (#31943)
|
||||
- BlueBubbles/Message metadata: harden send response ID extraction, include sender identity in DM context, and normalize inbound `message_id` selection to avoid duplicate ID metadata. (#23970) Thanks @tyler6204.
|
||||
- WebChat/markdown tables: ensure GitHub-flavored markdown table parsing is explicitly enabled at render time and add horizontal overflow handling for wide tables, with regression coverage for table-only and mixed text+table content. (#32365) Thanks @BlueBirdBack.
|
||||
- Feishu/default account resolution: always honor explicit `channels.feishu.defaultAccount` during outbound account selection (including top-level-credential setups where the preferred id is not present in `accounts`), instead of silently falling back to another account id. (#32253) Thanks @bmendonca3.
|
||||
|
||||
@@ -47,6 +47,22 @@ type PermissionError = {
|
||||
|
||||
const IGNORED_PERMISSION_SCOPE_TOKENS = ["contact:contact.base:readonly"];
|
||||
|
||||
// Feishu API sometimes returns incorrect scope names in permission error
|
||||
// responses (e.g. "contact:contact.base:readonly" instead of the valid
|
||||
// "contact:user.base:readonly"). This map corrects known mismatches.
|
||||
const FEISHU_SCOPE_CORRECTIONS: Record<string, string> = {
|
||||
"contact:contact.base:readonly": "contact:user.base:readonly",
|
||||
};
|
||||
|
||||
function correctFeishuScopeInUrl(url: string): string {
|
||||
let corrected = url;
|
||||
for (const [wrong, right] of Object.entries(FEISHU_SCOPE_CORRECTIONS)) {
|
||||
corrected = corrected.replaceAll(encodeURIComponent(wrong), encodeURIComponent(right));
|
||||
corrected = corrected.replaceAll(wrong, right);
|
||||
}
|
||||
return corrected;
|
||||
}
|
||||
|
||||
function shouldSuppressPermissionErrorNotice(permissionError: PermissionError): boolean {
|
||||
const message = permissionError.message.toLowerCase();
|
||||
return IGNORED_PERMISSION_SCOPE_TOKENS.some((token) => message.includes(token));
|
||||
@@ -72,7 +88,7 @@ function extractPermissionError(err: unknown): PermissionError | null {
|
||||
// Extract the grant URL from the error message (contains the direct link)
|
||||
const msg = feishuErr.msg ?? "";
|
||||
const urlMatch = msg.match(/https:\/\/[^\s,]+\/app\/[^\s,]+/);
|
||||
const grantUrl = urlMatch?.[0];
|
||||
const grantUrl = urlMatch?.[0] ? correctFeishuScopeInUrl(urlMatch[0]) : undefined;
|
||||
|
||||
return {
|
||||
code: feishuErr.code,
|
||||
|
||||
Reference in New Issue
Block a user