UNPKG

@jaimeflneto/n8n-nodes-google-ads-conversion

Version:

n8n node for tracking conversions in Google Ads with support for batch processing, enhanced conversions, and comprehensive privacy compliance

525 lines (410 loc) 14.3 kB
# Google Ads Conversion Node - Developer Guide ## Table of Contents 1. [Architecture Overview](#architecture-overview) 2. [Project Structure](#project-structure) 3. [Development Setup](#development-setup) 4. [Implementation Details](#implementation-details) 5. [Testing](#testing) 6. [Error Handling](#error-handling) 7. [Performance Considerations](#performance-considerations) 8. [Security & Privacy](#security--privacy) 9. [Contributing](#contributing) 10. [Release Process](#release-process) ## Architecture Overview The Google Ads Conversion Node is built as a custom n8n node that integrates with the Google Ads API v14 to enable automated conversion tracking. The node follows n8n's architecture patterns and implements advanced features for production-grade usage. ### Core Components ``` GoogleAdsConversion.node.ts ├── Node Definition (INodeTypeDescription) ├── Authentication Handling (OAuth2) ├── Input Validation & Sanitization ├── Batch Processing Engine ├── Retry Logic with Exponential Backoff ├── Error Classification & Handling ├── Privacy-Compliant Data Processing └── Debug & Monitoring Features ``` ### Design Principles - **SOLID Principles**: Single responsibility, open/closed, dependency inversion - **DRY**: Reusable components and utilities - **Security-First**: Automatic data hashing and privacy compliance - **Production-Ready**: Comprehensive error handling and monitoring - **Performance-Optimized**: Batch processing and efficient API usage ## Project Structure ``` google-ads-conversion/ ├── nodes/ └── GoogleAdsConversion/ ├── GoogleAdsConversion.node.ts # Main node implementation ├── description.ts # Node properties definition └── googleAds.svg # Node icon ├── credentials/ └── GoogleAdsOAuth2.credentials.ts # OAuth2 credential definition ├── docs/ ├── user-guide.md # User documentation ├── developer-guide.md # This file └── api-reference.md # API reference ├── tests/ ├── run-tests.js # Test runner ├── test-data.json # Test data └── examples/ # Usage examples ├── package.json # Package configuration ├── tsconfig.json # TypeScript configuration └── README.md # Project overview ``` ## Development Setup ### Prerequisites - Node.js 18+ and npm - TypeScript 4.9+ - n8n development environment - Google Ads API access (for testing) ### Local Development 1. **Clone Repository**: ```bash git clone <repository-url> cd google-ads-conversion ``` 2. **Install Dependencies**: ```bash npm install ``` 3. **Build Project**: ```bash npm run build ``` 4. **Link to n8n** (for testing): ```bash # In your n8n installation npm link /path/to/google-ads-conversion ``` 5. **Start n8n**: ```bash n8n start ``` ### Development Commands ```bash # Build TypeScript npm run build # Watch mode for development npm run dev # Run tests npm test # Lint code npm run lint # Format code npm run format # Package for distribution npm run package ``` ## Implementation Details ### Authentication Flow The node uses OAuth2 authentication with Google Ads API: ```typescript // Credential validation and header setup private async getAuthenticatedHeaders(executeFunctions: IExecuteFunctions): Promise<Record<string, string>> { const credentials = await executeFunctions.getCredentials('googleAdsOAuth2'); return { 'developer-token': credentials.developerToken, 'login-customer-id': credentials.customerId, 'Accept': 'application/json', 'Content-Type': 'application/json', }; } ``` ### Data Processing Pipeline 1. **Input Validation**: Comprehensive parameter validation 2. **Data Transformation**: Convert n8n parameters to API format 3. **Privacy Processing**: Automatic hashing for enhanced conversions 4. **Batch Organization**: Group items for optimal API usage 5. **API Communication**: Execute with retry logic 6. **Response Processing**: Parse and format results ### Enhanced Conversions Implementation User data is automatically hashed using SHA-256 for privacy compliance: ```typescript private async hashString(input: string): Promise<string> { if (!input || input.trim() === '') { return ''; } const normalized = input.toLowerCase().trim(); return createHash('sha256').update(normalized, 'utf8').digest('hex'); } ``` ### Batch Processing Engine The batch processing system efficiently handles large datasets: ```typescript // Configurable batch processing private async processBatchItems(executeFunctions: IExecuteFunctions, items: INodeExecutionData[]): Promise<INodeExecutionData[]> { const batchSize = Math.min(Math.max(this.getBatchSize(), 1), 2000); const batches = this.groupIntoBatches(conversions, batchSize); // Process batches with configurable error handling for (const [index, batch] of batches.entries()) { await this.processBatch(batch, index, batches.length); } } ``` ### Error Classification System Custom error classes provide detailed error categorization: ```typescript // Hierarchical error classification class GoogleAdsAuthenticationError extends NodeOperationError { } class GoogleAdsValidationError extends NodeOperationError { } class GoogleAdsApiError extends NodeOperationError { } class GoogleAdsRateLimitError extends NodeOperationError { } ``` ### Retry Logic Intelligent retry system with exponential backoff: ```typescript private async executeWithRetry<T>( operation: () => Promise<T>, context: string, debugMode: boolean ): Promise<T> { const config = this.getRetryConfig(); for (let attempt = 0; attempt <= config.maxRetries; attempt++) { try { return await operation(); } catch (error) { if (!this.shouldRetry(error, attempt, config)) { throw this.parseApiError(error); } const delay = this.calculateDelay(attempt, config); await this.sleep(delay); } } } ``` ## Testing ### Test Structure The project includes comprehensive testing: ```javascript // Automated test runner const tests = [ { name: 'Node Structure Validation', test: validateNodeStructure }, { name: 'Credentials Validation', test: validateCredentials }, { name: 'Package Configuration', test: validatePackage }, { name: 'Documentation Completeness', test: validateDocumentation }, { name: 'Test Data Validation', test: validateTestData } ]; ``` ### Running Tests ```bash # Run all tests npm test # Run specific test node tests/run-tests.js # Validate package structure npm run validate ``` ### Test Data Example test data for different scenarios: ```json { "gclid_conversion": { "conversionAction": "customers/1234567890/conversionActions/987654321", "gclid": "test_gclid_123", "conversionDateTime": "2024-01-15 14:30:00+00:00", "conversionValue": 99.99 }, "enhanced_conversion": { "conversionAction": "customers/1234567890/conversionActions/987654321", "email": "test@example.com", "phoneNumber": "+1234567890", "conversionDateTime": "2024-01-15 14:30:00+00:00" } } ``` ### Integration Testing For full integration testing with Google Ads API: 1. Set up test Google Ads account 2. Configure OAuth2 credentials 3. Use validation mode for safe testing 4. Test all identification methods 5. Verify batch processing functionality ## Error Handling ### Error Classification Matrix | Error Type | HTTP Code | Retry | Description | |------------|-----------|-------|-------------| | Authentication | 401, 403 | No | Invalid credentials | | Validation | 400 | No | Invalid input data | | Rate Limit | 429 | Yes | API quota exceeded | | Server Error | 5xx | Yes | Temporary server issues | | Network Error | - | Yes | Connection problems | ### Custom Error Classes ```typescript // Authentication errors class GoogleAdsAuthenticationError extends NodeOperationError { constructor(node: any, message: string) { super(node, `Authentication Error: ${message}`); this.name = 'GoogleAdsAuthenticationError'; } } // API errors with HTTP details class GoogleAdsApiError extends NodeOperationError { public httpCode: number; public apiErrorCode?: string; constructor(node: any, message: string, httpCode: number, apiErrorCode?: string) { super(node, `Google Ads API Error: ${message}`); this.httpCode = httpCode; this.apiErrorCode = apiErrorCode; } } ``` ### Error Response Format Consistent error response structure: ```json { "success": false, "error": "Authentication failed. Please verify your OAuth2 credentials.", "errorType": "GoogleAdsAuthenticationError", "itemIndex": 0, "retryable": false, "debugInfo": { "httpCode": 401, "timestamp": "2024-01-15T14:30:00Z" } } ``` ## Performance Considerations ### Batch Processing Optimization - **Optimal Batch Size**: 100-500 items for best performance - **Memory Management**: Streaming for large datasets - **API Efficiency**: Up to 2000x reduction in API calls - **Rate Limit Compliance**: Automatic throttling ### Memory Usage ```typescript // Memory-efficient batch processing private groupIntoBatches<T>(items: T[], batchSize: number): T[][] { const batches: T[][] = []; for (let i = 0; i < items.length; i += batchSize) { batches.push(items.slice(i, i + batchSize)); } return batches; } ``` ### Monitoring & Observability Built-in metrics and logging: - Request/response timing - Batch processing statistics - Error rates and types - API quota usage - Authentication events ## Security & Privacy ### Data Handling - **Automatic Hashing**: SHA-256 for user identifiers - **No Data Storage**: Processed data not persisted - **Secure Transmission**: HTTPS-only communication - **Credential Management**: OAuth2 with token refresh ### Privacy Compliance - **GDPR Compliance**: Consent field handling - **Data Minimization**: Only required fields processed - **Right to Erasure**: No data retention - **Audit Trail**: Comprehensive logging ### Security Best Practices ```typescript // Secure string hashing private async hashString(input: string): Promise<string> { const normalized = input.toLowerCase().trim(); return createHash('sha256').update(normalized, 'utf8').digest('hex'); } // Credential validation private async validateCredentials(headers: Record<string, string>): Promise<void> { // Test API connectivity without exposing credentials const testPayload = { query: 'SELECT customer.id FROM customer LIMIT 1' }; await this.executeWithRetry(() => this.apiRequest(testPayload)); } ``` ## Contributing ### Development Workflow 1. **Fork Repository**: Create a personal fork 2. **Create Branch**: `git checkout -b feature/new-feature` 3. **Implement Changes**: Follow coding standards 4. **Add Tests**: Ensure comprehensive test coverage 5. **Update Documentation**: Keep docs current 6. **Submit PR**: Create pull request with description ### Coding Standards - **TypeScript**: Strict mode enabled - **ESLint**: Configured for n8n patterns - **Prettier**: Automatic code formatting - **No Comments**: Self-documenting code preferred - **SOLID Principles**: Follow design patterns ### Code Review Checklist - [ ] All tests pass - [ ] Code follows style guidelines - [ ] Documentation updated - [ ] Security considerations addressed - [ ] Performance impact assessed - [ ] Backward compatibility maintained ### Commit Message Format ``` type(scope): description Examples: feat(batch): add parallel processing support fix(auth): resolve token refresh issue docs(api): update authentication examples test(integration): add Google Ads API tests ``` ## Release Process ### Version Management Follow semantic versioning (SemVer): - **Major**: Breaking changes - **Minor**: New features, backward compatible - **Patch**: Bug fixes, backward compatible ### Release Checklist 1. **Update Version**: Bump in package.json 2. **Update Changelog**: Document all changes 3. **Run Tests**: Ensure all tests pass 4. **Build Package**: `npm run package` 5. **Test Package**: Verify installation 6. **Create Release**: Tag and publish 7. **Update Documentation**: Publish updated docs ### Continuous Integration ```yaml # GitHub Actions workflow name: CI/CD on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 - run: npm ci - run: npm test - run: npm run build ``` ### Distribution - **npm Registry**: Primary distribution method - **GitHub Releases**: Source code and binaries - **n8n Community**: Community node registry - **Documentation**: Updated websites and wikis ## API Reference ### Node Properties | Property | Type | Required | Description | |----------|------|----------|-------------| | operation | string | Yes | Operation type | | conversionAction | string | Yes | Conversion action ID | | conversionDateTime | string | Yes | Conversion timestamp | | identificationMethod | string | Yes | User identification method | | enableBatchProcessing | boolean | No | Enable batch mode | | debugMode | boolean | No | Enable debug logging | ### Credential Properties | Property | Type | Required | Description | |----------|------|----------|-------------| | developerToken | string | Yes | Google Ads developer token | | customerId | string | Yes | Google Ads customer ID | | clientId | string | Yes | OAuth2 client ID | | clientSecret | string | Yes | OAuth2 client secret | ### Response Format ```typescript interface ConversionResponse { success: boolean; message: string; operation: string; conversion: object; response?: object; error?: string; debugInfo?: object; } ``` --- *This developer guide is for Google Ads Conversion Node v1.0.0*