import { RegisterClass } from '@memberjunction/global'; import { SurveyMonkeyBaseAction, SurveyMonkeySurveyDetails } from '../surveymonkey-base.action'; import { ActionParam, ActionResultSimple, RunActionParams } from '@memberjunction/actions-base'; import { BaseAction } from '@memberjunction/actions'; /** * Action to update an existing SurveyMonkey survey * * IMPORTANT: When MergeWithExisting is true (default), fetches the current survey * and merges your changes. When false, replaces entire survey data (use with caution). * * The action uses PATCH for partial updates when MergeWithExisting=true, which is * the recommended approach for most use cases. * * Security: Uses secure credential lookup via CompanyID instead of accepting tokens directly. * * @example * ```typescript * await runAction({ * ActionName: 'Update SurveyMonkey', * Params: [{ * Name: 'CompanyID', * Value: 'your-company-id' * }, { * Name: 'SurveyID', * Value: 'abc123' * }, { * Name: 'Title', * Value: 'Updated Survey Title' * }, { * Name: 'MergeWithExisting', * Value: true * }] * }); * ``` */ @RegisterClass(BaseAction, 'UpdateSurveyMonkeyAction') export class UpdateSurveyMonkeyAction extends SurveyMonkeyBaseAction { public get Description(): string { return 'Updates an existing SurveyMonkey survey. Set MergeWithExisting=true (default) to safely update only specified properties while preserving others. Set to false to replace entire survey data (not recommended).'; } protected async InternalRunAction(params: RunActionParams): Promise { try { const contextUser = params.ContextUser; if (!contextUser) { return { Success: false, ResultCode: 'MISSING_CONTEXT_USER', Message: 'Context user is required for SurveyMonkey API calls', }; } const companyId = this.getParamValue(params.Params, 'CompanyID'); const surveyId = this.getParamValue(params.Params, 'SurveyID'); if (!surveyId) { return { Success: false, ResultCode: 'MISSING_SURVEY_ID', Message: 'SurveyID parameter is required', }; } const accessToken = await this.getSecureAPIToken(companyId, contextUser); const mergeWithExisting = this.getParamValue(params.Params, 'MergeWithExisting') !== false; const title = this.getParamValue(params.Params, 'Title'); const pages = this.getParamValue(params.Params, 'Pages'); const language = this.getParamValue(params.Params, 'Language'); const buttonsText = this.getParamValue(params.Params, 'ButtonsText'); // Check if any updates are provided if (!title && !pages && !language && !buttonsText) { return { Success: false, ResultCode: 'NO_CHANGES_PROVIDED', Message: 'At least one of Title, Pages, Language, or ButtonsText must be provided', }; } const updatedFields: string[] = []; let existingSurvey: SurveyMonkeySurveyDetails | null = null; // Get existing survey if merging if (mergeWithExisting) { existingSurvey = await this.getSurveyMonkeyDetails(surveyId, accessToken); } // Build update data object const updateData: { title?: string; nickname?: string; language?: string; buttons_text?: { next_button?: string; prev_button?: string; done_button?: string; exit_button?: string; }; custom_variables?: Record; } = {}; // Add title if provided if (title) { updateData.title = title; updatedFields.push('title'); } // Add language if provided if (language) { updateData.language = language; updatedFields.push('language'); } // Handle buttons text if (buttonsText) { const buttonsObj = typeof buttonsText === 'string' ? JSON.parse(buttonsText) : buttonsText; if (mergeWithExisting && existingSurvey?.buttons_text) { updateData.buttons_text = { ...existingSurvey.buttons_text, ...buttonsObj }; } else { updateData.buttons_text = buttonsObj; } updatedFields.push('buttons_text'); } // Handle pages (if provided) // Note: Pages require separate API calls to update individual pages/questions // For now, we'll track it but handle basic survey properties only if (pages) { // Pages would need to be handled via separate API calls to /surveys/{id}/pages // This is a more complex operation and may require additional implementation updatedFields.push('pages (note: page updates require separate API calls)'); } // Update the survey using PATCH (partial update) const updatedSurvey = await this.updateSurveyMonkey(surveyId, accessToken, updateData); // Build output parameters const outputParams: ActionParam[] = [ { Name: 'Survey', Type: 'Output', Value: updatedSurvey, }, { Name: 'SurveyID', Type: 'Output', Value: updatedSurvey.id, }, { Name: 'Title', Type: 'Output', Value: updatedSurvey.title, }, { Name: 'UpdatedFields', Type: 'Output', Value: updatedFields, }, { Name: 'PageCount', Type: 'Output', Value: updatedSurvey.page_count, }, ]; // Add output params to result for (const outputParam of outputParams) { const existingParam = params.Params.find((p) => p.Name === outputParam.Name); if (existingParam) { existingParam.Value = outputParam.Value; } else { params.Params.push(outputParam); } } return { Success: true, ResultCode: 'SUCCESS', Message: `Successfully updated survey "${updatedSurvey.title}" (ID: ${updatedSurvey.id}). Updated fields: ${updatedFields.join(', ')}`, }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; return { Success: false, ResultCode: 'ERROR', Message: this.buildFormErrorMessage('Update SurveyMonkey', errorMessage, error), }; } } public get Params(): ActionParam[] { return [ { Name: 'CompanyID', Type: 'Input', Value: null, }, { Name: 'SurveyID', Type: 'Input', Value: null, }, { Name: 'MergeWithExisting', Type: 'Input', Value: true, }, { Name: 'Title', Type: 'Input', Value: null, }, { Name: 'Pages', Type: 'Input', Value: null, }, { Name: 'Language', Type: 'Input', Value: null, }, { Name: 'ButtonsText', Type: 'Input', Value: null, }, ]; } }