Chat-only commands reset voicemail mailbox and voice portal passcodes via telephony_config_write, with extension lookup and unit tests. Co-authored-by: Cursor <cursoragent@cursor.com>
54 lines
1.9 KiB
JavaScript
54 lines
1.9 KiB
JavaScript
// services/voicePin/resetVoicemailPin.js
|
|
// PUT /v1/telephony/config/people/{personId}/voicemail/passcode
|
|
//
|
|
// Admin API to set a custom voicemail PIN (spark-admin:telephony_config_write).
|
|
// Do NOT use people/{id}/features/voicemail/passcode — that path does not exist.
|
|
// For org-default reset only: POST people/{id}/features/voicemail/actions/resetPin/invoke
|
|
|
|
import { logger } from '../../utils/logger.js';
|
|
import { generatePin } from './generatePin.js';
|
|
|
|
const LOG_SCOPE = 'resetvmpin:service';
|
|
const VM_PIN_LENGTH = 6;
|
|
const MAX_PUT_ATTEMPTS = 5;
|
|
|
|
function vmPasscodeEndpoint(personId) {
|
|
return `telephony/config/people/${personId}/voicemail/passcode`;
|
|
}
|
|
|
|
/**
|
|
* Reset a user's voicemail mailbox PIN.
|
|
*
|
|
* @param {string} personId
|
|
* @param {object} [opts]
|
|
* @param {object} [opts.webexClient] injectable client for tests
|
|
* @returns {Promise<string>} new PIN (never log this value)
|
|
*/
|
|
export async function resetVoicemailPin(personId, opts = {}) {
|
|
if (!personId) {
|
|
throw new Error('personId is required');
|
|
}
|
|
|
|
const client = opts.webexClient || (await import('../../integrations/webex/WebexClient.js')).default;
|
|
const endpoint = vmPasscodeEndpoint(personId);
|
|
|
|
let lastError = null;
|
|
for (let attempt = 0; attempt < MAX_PUT_ATTEMPTS; attempt += 1) {
|
|
const passcode = generatePin({ minLength: VM_PIN_LENGTH, maxLength: VM_PIN_LENGTH });
|
|
try {
|
|
await client.request('PUT', endpoint, { passcode });
|
|
logger(LOG_SCOPE, `Voicemail PIN reset succeeded for person ${personId}`, 'info');
|
|
return passcode;
|
|
} catch (err) {
|
|
lastError = err;
|
|
const status = err?.response?.status;
|
|
if (status === 400 && attempt < MAX_PUT_ATTEMPTS - 1) {
|
|
logger(LOG_SCOPE, `Voicemail PIN rejected for ${personId} (attempt ${attempt + 1}), retrying`, 'warn');
|
|
continue;
|
|
}
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
throw lastError || new Error('Voicemail PIN reset failed');
|
|
}
|