// scripts/lib/webexTokenClient.js // // Lightweight Webex REST client for one-off scripts that accept an // external bearer token (personal admin token) instead of the bot's // service-app OAuth flow. import axios from 'axios'; const DEFAULT_BASE_URL = process.env.WEBEX_BASE_URL || 'https://webexapis.com/v1'; /** * @param {string} accessToken * @param {object} [opts] * @param {string} [opts.baseUrl] * @returns {{ request: Function, requestRaw: Function }} */ export function createTokenClient(accessToken, { baseUrl = DEFAULT_BASE_URL } = {}) { const token = String(accessToken || '').trim(); if (!token) { throw new Error('createTokenClient: access token is required'); } const base = baseUrl.replace(/\/$/, ''); async function requestRaw(method, endpointOrUrl, data = null, params = null) { const isAbsolute = /^https?:\/\//i.test(endpointOrUrl); const url = isAbsolute ? endpointOrUrl : `${base}/${endpointOrUrl.replace(/^\//, '')}`; const response = await axios({ method, url, headers: { Authorization: `Bearer ${token}` }, data, params: isAbsolute ? undefined : params, validateStatus: () => true, }); if (response.status >= 200 && response.status < 300) { return { data: response.data, headers: response.headers, status: response.status }; } const err = new Error( response.data?.message || response.data?.errors?.[0]?.description || `Webex API ${method} ${endpointOrUrl} failed with HTTP ${response.status}`, ); err.response = response; throw err; } async function request(method, endpointOrUrl, data = null, params = null) { const { data: body } = await requestRaw(method, endpointOrUrl, data, params); return body; } return { request, requestRaw }; }