#!/usr/bin/env node import { readFileSync } from "node:fs"; import { XftOpenApiClient } from "../dist/src/xft-open-api.js"; const [appId, secretFile, enterpriseId, dingTalkUserId, historyBillId] = process.argv.slice(2); if (!appId || !secretFile || !enterpriseId || !dingTalkUserId) { console.error("usage: node scripts/xft-open-api-readonly.mjs "); process.exit(2); } const config = { clientId: "readonly-smoke-test", clientSecret: "readonly-smoke-test", apiBaseUrl: "https://api.dingtalk.com", oapiBaseUrl: "https://oapi.dingtalk.com", publicBaseUrl: "https://localhost", port: 3000, requestTimeoutMs: 15_000, officialLookbackDays: 120, officialScanConcurrency: 2, officialClientOnlyProcessCodes: [], batchLimit: 20, xftOpenApi: { appId, authoritySecret: (() => { const lines = readFileSync(secretFile, "utf8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean); return lines.length >= 2 ? lines[1] : lines[0]; })(), enterpriseId, apiBaseUrl: "https://api.cmbchina.com", encrypted: true, dingTalkAppCode: "DDingTalk", }, }; const client = new XftOpenApiClient(config); if (historyBillId && historyBillId !== "--auth-only") { try { const history = await client.request( `/itrip/xft-api/v1/bills/taskHistory/${encodeURIComponent(historyBillId)}`, undefined, "GET", ); console.log(JSON.stringify({ historyProbe: "ok", responseType: Array.isArray(history) ? "array" : typeof history })); } catch (error) { console.log(JSON.stringify({ historyProbe: "failed", message: error instanceof Error ? error.message : String(error) })); } } const user = { userId: dingTalkUserId }; const auth = await client.authStatus(user); if (historyBillId === "--auth-only") { console.log(JSON.stringify({ authenticated: auth.authenticated, identity: auth.identity }, null, 2)); process.exit(0); } const todos = await client.listMyTodos(user, 200); const detailCandidates = ["COMMON_REIM", "TRAVEL_REIM"] .map((eventType) => todos.items.find((item) => item.eventType === eventType)) .filter(Boolean); const details = await Promise.all(detailCandidates.map((item) => client.getTodoDetail(user, item.billId))); console.log(JSON.stringify({ authenticated: auth.authenticated, identity: auth.identity, todoCount: todos.totalCount, sample: todos.items.slice(0, 3).map(({ billId, title, applicantName, amount, eventType }) => ({ billId, title, applicantName, amount, eventType })), detailProbes: details.map((detail) => ({ billId: detail.todo.billId, eventType: detail.todo.eventType, formType: Array.isArray(detail.form) ? "array" : typeof detail.form, formTopLevelKeys: detail.form && typeof detail.form === "object" && !Array.isArray(detail.form) ? Object.keys(detail.form).slice(0, 30) : [], })), diagnostics: todos.diagnostics, }, null, 2));