Member Junction
    Preparing search index...

    Module @memberjunction/actions-bizapps-formbuilders - v5.49.0

    @memberjunction/actions-bizapps-formbuilders

    Form builder and survey platform integration actions for MemberJunction. This package provides a unified interface across four major form/survey platforms, enabling AI agents, workflows, and applications to programmatically retrieve responses, analyze submissions, and manage forms through the MemberJunction Actions framework.

    This package is part of the BizApps Actions collection within the broader MemberJunction Actions Framework. For core action architecture, design philosophy, and when to use actions versus direct code, see the Actions CLAUDE.md.

    The package follows a three-tier class hierarchy: a shared base class providing common form operations, provider-specific base classes handling API authentication and data normalization, and individual action classes implementing specific operations.

    graph TD
        subgraph Framework["Actions Framework"]
            BA["BaseAction
    @memberjunction/actions"] end subgraph Base["Shared Base Layer"] BFBA["BaseFormBuilderAction
    Credential management, CSV export,
    statistics helpers, response normalization"] end subgraph Providers["Provider Base Classes"] TF["TypeformBaseAction
    Bearer token auth
    Axios + rate limiting"] JF["JotFormBaseAction
    API key (query param)
    Regional endpoints"] SM["SurveyMonkeyBaseAction
    OAuth 2.0 Bearer
    Paginated responses"] GF["GoogleFormsBaseAction
    OAuth 2.0 Bearer
    Read-only API"] end subgraph Actions["Action Classes (34 total)"] TFA["Typeform Actions (10)"] JFA["JotForm Actions (8)"] SMA["SurveyMonkey Actions (8)"] GFA["Google Forms Actions (4)"] end subgraph Shared["Shared Utilities"] FCP["FileContentProcessor
    PDF, Excel, Word,
    image extraction"] end BA --> BFBA BFBA --> TF BFBA --> JF BFBA --> SM BFBA --> GF TF --> TFA JF --> JFA SM --> SMA GF --> GFA TFA -.-> FCP style Framework fill:#64748b,stroke:#475569,color:#fff style Base fill:#2d6a9f,stroke:#1a4971,color:#fff style TF fill:#7c5295,stroke:#563a6b,color:#fff style JF fill:#7c5295,stroke:#563a6b,color:#fff style SM fill:#7c5295,stroke:#563a6b,color:#fff style GF fill:#7c5295,stroke:#563a6b,color:#fff style TFA fill:#2d8659,stroke:#1a5c3a,color:#fff style JFA fill:#2d8659,stroke:#1a5c3a,color:#fff style SMA fill:#2d8659,stroke:#1a5c3a,color:#fff style GFA fill:#2d8659,stroke:#1a5c3a,color:#fff style FCP fill:#b8762f,stroke:#8a5722,color:#fff
    Platform Auth Method Actions Capabilities
    Typeform Bearer token (personal access token) 10 Full CRUD: responses, forms, file content
    JotForm API key (query parameter) 8 Full CRUD: submissions, forms
    SurveyMonkey OAuth 2.0 Bearer token 8 Full CRUD: responses, surveys, collectors
    Google Forms OAuth 2.0 Bearer token 4 Read-only: responses, form details
    npm install @memberjunction/actions-bizapps-formbuilders
    

    This package is part of the MemberJunction monorepo. When working within the monorepo, add the dependency to your package's package.json and run npm install at the repository root.

    Action Class Registration Name Description
    GetTypeformResponsesAction GetTypeformResponsesAction Retrieve responses with filtering, pagination, and auto-paginate support
    GetSingleTypeformResponseAction GetSingleTypeformResponseAction Retrieve a specific response by token
    GetTypeformStatisticsAction GetTypeformStatisticsAction Calculate aggregate analytics (completion rates, distributions, top answers)
    ExportTypeformCSVAction ExportTypeformCSVAction Export responses to CSV format with optional metadata
    WatchNewTypeformResponsesAction WatchNewTypeformResponsesAction Poll for new submissions since a given timestamp
    GetTypeformAction GetTypeformAction Retrieve complete form configuration and field definitions
    GetTypeformFormsAction GetTypeformFormsAction List all forms in a workspace
    TypeformGetFileContentAction TypeformGetFileContentAction Download and process file upload answers (PDF, Excel, Word, images)
    CreateTypeformAction CreateTypeformAction Create new forms programmatically with fields, settings, and logic
    UpdateTypeformAction UpdateTypeformAction Modify existing forms with safe merge mode
    Action Class Registration Name Description
    GetJotFormSubmissionsAction GetJotFormSubmissionsAction Retrieve submissions with filtering and pagination
    GetSingleJotFormSubmissionAction GetSingleJotFormSubmissionAction Retrieve a specific submission by ID
    GetJotFormStatisticsAction GetJotFormStatisticsAction Calculate aggregate analytics from submissions
    ExportJotFormCSVAction ExportJotFormCSVAction Export submissions to CSV format
    WatchNewJotFormSubmissionsAction WatchNewJotFormSubmissionsAction Poll for new submissions since a given timestamp
    GetJotFormAction GetJotFormAction Retrieve form details and questions
    CreateJotFormAction CreateJotFormAction Create new forms with questions and properties
    UpdateJotFormAction UpdateJotFormAction Modify existing form configuration
    Action Class Registration Name Description
    GetSurveyMonkeyResponsesAction GetSurveyMonkeyResponsesAction Retrieve responses with date range and status filtering
    GetSingleSurveyMonkeyResponseAction GetSingleSurveyMonkeyResponseAction Retrieve a specific response by ID
    GetSurveyMonkeyStatisticsAction GetSurveyMonkeyStatisticsAction Calculate aggregate analytics from responses
    ExportSurveyMonkeyCSVAction ExportSurveyMonkeyCSVAction Export responses to CSV format
    WatchNewSurveyMonkeyResponsesAction WatchNewSurveyMonkeyResponsesAction Poll for new responses since a given timestamp
    GetSurveyMonkeyAction GetSurveyMonkeyAction Retrieve survey details and configuration
    CreateSurveyMonkeyAction CreateSurveyMonkeyAction Create new surveys with pages and questions
    UpdateSurveyMonkeyAction UpdateSurveyMonkeyAction Modify existing survey properties
    Action Class Registration Name Description
    GetSingleGoogleFormsResponseAction GetSingleGoogleFormsResponseAction Retrieve a specific response by ID
    GetGoogleFormsStatisticsAction GetGoogleFormsStatisticsAction Calculate aggregate analytics from responses
    ExportGoogleFormsCSVAction ExportGoogleFormsCSVAction Export responses to CSV format
    GetGoogleFormAction GetGoogleFormAction Retrieve form details, questions, and quiz settings

    Note: Google Forms API is read-only. There are no endpoints for creating or updating forms programmatically.

    All providers normalize their responses into a shared FormResponse interface, enabling provider-agnostic processing downstream.

    classDiagram
        class FormResponse {
            +string responseId
            +string formId
            +Date submittedAt
            +boolean completed
            +FormAnswer[] answerDetails
            +Record answers
            +metadata
            +calculatedFields
            +hiddenFields
        }
    
        class FormAnswer {
            +string fieldId
            +string fieldType
            +string question
            +answer
            +string[] choices
        }
    
        class FormStatistics {
            +number totalResponses
            +number completedResponses
            +number partialResponses
            +number completionRate
            +number averageCompletionTime
            +Record responsesByDate
            +topAnswers
        }
    
        FormResponse --> FormAnswer : answerDetails
    
        style FormResponse fill:#2d6a9f,stroke:#1a4971,color:#fff
        style FormAnswer fill:#7c5295,stroke:#563a6b,color:#fff
        style FormStatistics fill:#2d8659,stroke:#1a5c3a,color:#fff
    

    All form builder actions use a secure credential resolution chain. Credentials are never passed as direct action parameters; instead, they are resolved from environment variables or the MemberJunction Company Integrations entity.

    1. Environment variables (company-specific): BIZAPPS_{PROVIDER}_{COMPANY_ID}_{CREDENTIAL_TYPE}
    2. Environment variables (default): BIZAPPS_{PROVIDER}_{CREDENTIAL_TYPE}
    3. Database (Company Integrations entity): AccessToken, APIKey fields
    # Typeform - Personal access token
    export BIZAPPS_TYPEFORM_API_TOKEN=tfp_your_token_here
    export BIZAPPS_TYPEFORM_12345_API_TOKEN=tfp_company_specific_token

    # JotForm - API key
    export BIZAPPS_JOTFORM_API_KEY=your_jotform_api_key
    export BIZAPPS_JOTFORM_12345_API_KEY=company_specific_key

    # SurveyMonkey - OAuth 2.0 access token
    export BIZAPPS_SURVEYMONKEY_ACCESS_TOKEN=your_oauth_token

    # Google Forms - OAuth 2.0 access token
    export BIZAPPS_GOOGLE_FORMS_ACCESS_TOKEN=your_google_oauth_token

    # OAuth2 client credentials (for token refresh)
    export BIZAPPS_TYPEFORM_CLIENT_ID=your_client_id
    export BIZAPPS_TYPEFORM_CLIENT_SECRET=your_client_secret

    Store credentials in the Company Integrations entity linked to the appropriate Integration record:

    -- 1. Create Integration record for the platform
    INSERT INTO Integration (Name, Description, NavigationBaseURL, ClassName)
    VALUES ('Typeform', 'Typeform form builder', 'https://api.typeform.com', 'TypeformIntegration');
    
    -- 2. Link to Company with credentials
    INSERT INTO CompanyIntegration (CompanyID, IntegrationID, AccessToken, IsActive)
    VALUES (@CompanyID, @IntegrationID, 'tfp_your_token', 1);
    
    import { ActionEngineServer } from '@memberjunction/actions';

    const engine = ActionEngineServer.Instance;

    // Get Typeform responses with date filtering
    const result = await engine.RunAction({
    Action: engine.Actions.find(a => a.Name === 'Get Typeform Responses'),
    Params: [
    { Name: 'CompanyID', Type: 'Input', Value: 'company-123' },
    { Name: 'FormID', Type: 'Input', Value: 'abc123' },
    { Name: 'Since', Type: 'Input', Value: '2024-01-01T00:00:00Z' },
    { Name: 'GetAllPages', Type: 'Input', Value: true }
    ],
    ContextUser: currentUser
    });

    if (result.Success) {
    const responses = result.Params.find(p => p.Name === 'Responses')?.Value;
    console.log(`Retrieved ${responses.length} responses`);
    }
    const exportResult = await engine.RunAction({
    Action: engine.Actions.find(a => a.Name === 'Export JotForm Responses to CSV'),
    Params: [
    { Name: 'CompanyID', Type: 'Input', Value: 'company-123' },
    { Name: 'FormID', Type: 'Input', Value: '240123456789' },
    { Name: 'IncludeMetadata', Type: 'Input', Value: true }
    ],
    ContextUser: currentUser
    });

    const csvData = exportResult.Params.find(p => p.Name === 'CSVData')?.Value;
    const createResult = await engine.RunAction({
    Action: engine.Actions.find(a => a.Name === 'Create Typeform'),
    Params: [
    { Name: 'CompanyID', Type: 'Input', Value: 'company-123' },
    { Name: 'Title', Type: 'Input', Value: 'Customer Feedback Survey' },
    {
    Name: 'Fields', Type: 'Input', Value: [
    {
    type: 'short_text',
    title: 'What is your name?',
    ref: 'name'
    },
    {
    type: 'rating',
    title: 'How satisfied are you?',
    ref: 'satisfaction',
    properties: { steps: 5, shape: 'star' }
    },
    {
    type: 'long_text',
    title: 'Any additional feedback?',
    ref: 'feedback'
    }
    ]
    }
    ],
    ContextUser: currentUser
    });

    const formUrl = createResult.Params.find(p => p.Name === 'FormURL')?.Value;
    // Poll for new SurveyMonkey responses
    const watchResult = await engine.RunAction({
    Action: engine.Actions.find(a => a.Name === 'Watch for New SurveyMonkey Responses'),
    Params: [
    { Name: 'CompanyID', Type: 'Input', Value: 'company-123' },
    { Name: 'SurveyID', Type: 'Input', Value: 'survey-456' },
    { Name: 'LastCheckedTimestamp', Type: 'Input', Value: '2024-06-01T00:00:00Z' },
    { Name: 'OnlyCompleted', Type: 'Input', Value: true }
    ],
    ContextUser: currentUser
    });

    const hasNew = watchResult.Params.find(p => p.Name === 'HasNewResponses')?.Value;
    const newResponses = watchResult.Params.find(p => p.Name === 'NewResponses')?.Value;

    The package includes a FileContentProcessor utility used by the Typeform GetFileContentAction to intelligently extract content from file upload answers. It supports multiple file formats:

    Format Processing Output
    PDF Text extraction via pdf-parse Plain text
    Excel (.xlsx, .xls) Sheet parsing via exceljs Structured JSON
    Word (.docx, .doc) Text extraction via mammoth Plain text
    Images Base64 encoding Base64 string (for LLM vision)
    Text/JSON/XML/CSV UTF-8 decoding Plain text
    Other binary Base64 encoding Base64 string

    All actions return consistent error information through the ActionResultSimple interface:

    Result Code Description
    SUCCESS Operation completed successfully
    MISSING_FORM_ID Required FormID parameter was not provided
    MISSING_API_TOKEN No API credentials could be resolved
    MISSING_CONTEXT_USER Context user is required for credential lookup
    ERROR General error (check Message for details)

    Each provider automatically handles platform-specific HTTP errors:

    • 401 - Invalid or expired API token
    • 403 - Insufficient permissions / scope
    • 404 - Form or response not found
    • 429 - Rate limit exceeded (automatic retry with exponential backoff)

    All providers include built-in rate limit handling with automatic retry:

    • Respects Retry-After headers when provided
    • Falls back to 60-second wait when no header is present
    • Adds 100ms delays between pagination requests to avoid hitting limits
    • JotForm: Regional endpoints (US, EU, HIPAA) for data residency compliance
    Package Purpose
    @memberjunction/actions Action engine and BaseAction class
    @memberjunction/actions-base ActionParam types and base interfaces
    @memberjunction/core RunView, Metadata, UserInfo, logging
    @memberjunction/core-entities CompanyIntegrationEntity for credential lookup
    @memberjunction/global @RegisterClass decorator
    axios HTTP client for all provider API calls
    exceljs Excel file parsing in FileContentProcessor
    mammoth Word document text extraction
    pdf-parse PDF text extraction

    To integrate a new form/survey platform:

    1. Create provider directory: src/providers/{platform}/
    2. Implement a provider base class extending BaseFormBuilderAction with:
      • formPlatform and integrationName properties
      • Axios instance with authentication and rate limit interceptors
      • API client methods for the provider's endpoints
      • Response normalization to the shared FormResponse interface
      • Provider-specific error handling
    3. Create individual action classes in src/providers/{platform}/actions/
    4. Export all classes from src/providers/{platform}/index.ts
    5. Add the provider export to src/index.ts

    Classes

    BaseFormBuilderAction
    CreateJotFormAction
    CreateSurveyMonkeyAction
    CreateTypeformAction
    ExportGoogleFormsCSVAction
    ExportJotFormCSVAction
    ExportSurveyMonkeyCSVAction
    ExportTypeformCSVAction
    GetGoogleFormAction
    GetGoogleFormsStatisticsAction
    GetJotFormAction
    GetJotFormStatisticsAction
    GetJotFormSubmissionsAction
    GetSingleGoogleFormsResponseAction
    GetSingleJotFormSubmissionAction
    GetSingleSurveyMonkeyResponseAction
    GetSingleTypeformResponseAction
    GetSurveyMonkeyDetailsAction
    GetSurveyMonkeyResponsesAction
    GetSurveyMonkeyStatisticsAction
    GetTypeformAction
    GetTypeformFileContentAction
    GetTypeformFormsAction
    GetTypeformResponsesAction
    GetTypeformStatisticsAction
    GoogleFormsBaseAction
    JotFormBaseAction
    SurveyMonkeyBaseAction
    TypeformBaseAction
    UpdateJotFormAction
    UpdateSurveyMonkeyAction
    UpdateTypeformAction
    WatchNewJotFormSubmissionsAction
    WatchNewSurveyMonkeyResponsesAction
    WatchNewTypeformResponsesAction

    Interfaces

    FormAnswer
    FormResponse
    FormStatistics
    GoogleFormItem
    GoogleFormsAnswer
    GoogleFormsDetails
    GoogleFormsResponseItem
    GoogleFormsResponsesResult
    JotFormSubmission
    JotFormSubmissionsResult
    SurveyMonkeyCollector
    SurveyMonkeyResponse
    SurveyMonkeyResponsesResult
    SurveyMonkeySurveyDetails
    TypeformResponseItem
    TypeformResponsesResult