UNPKG

n8n-nodes-plaid

Version:

n8n community node for Plaid financial data integration - the definitive financial node for n8n

557 lines (449 loc) โ€ข 15.1 kB
# n8n-nodes-plaid [![Test Suite](https://github.com/jcdotio/n8n-nodes-plaid/workflows/Test%20Suite/badge.svg)](https://github.com/jcdotio/n8n-nodes-plaid/actions/workflows/test.yml) [![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen)](https://github.com/jcdotio/n8n-nodes-plaid/actions/workflows/test.yml) [![Tests](https://img.shields.io/badge/tests-59%2F59%20passing-brightgreen)](https://github.com/jcdotio/n8n-nodes-plaid/actions/workflows/test.yml) [![npm version](https://img.shields.io/npm/v/n8n-nodes-plaid.svg)](https://www.npmjs.com/package/n8n-nodes-plaid) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) The definitive Plaid financial integration node for n8n. Connect to bank accounts, fetch transactions, and build powerful financial workflows with ease. ## ๐Ÿš€ Features - **Complete Plaid API Coverage**: Transactions, Accounts, Auth, Institutions, Items, Identity - **Modern API Support**: Uses latest Plaid Node.js SDK v34.0.0 and API version 2020-09-14 - **Real-time & Batch**: Support for both `/transactions/sync` and `/transactions/get` - **Enhanced Data**: Personal finance categorization, spending scores, recurring detection - **Secure**: Encrypted credential storage with environment isolation - **Production Ready**: Comprehensive error handling and rate limiting - **Easy Setup**: One-click installation and visual configuration ## ๐Ÿ“ฆ Installation ### ๐Ÿš€ Quick Start **New to Plaid + n8n?** Follow our **[Quick Start Guide](QUICK_START.md)** - get running in 10 minutes! ### ๐Ÿ“– Complete Setup **Need detailed instructions?** See our **[Complete Setup Guide](docs/PLAID_SETUP_GUIDE.md)** with troubleshooting. ### Via n8n GUI (Recommended) 1. Go to **Settings** โ†’ **Community Nodes** 2. Click **Install** 3. Enter: `n8n-nodes-plaid` 4. Click **Install** ### Via npm ```bash npm install n8n-nodes-plaid ``` ## ๐Ÿ”ง Setup ### 1. Get Plaid API Keys 1. Sign up at [Plaid Dashboard](https://dashboard.plaid.com) 2. Get your **Client ID** and **Secret** from API section 3. Set up Plaid Link to get user **Access Tokens** ### 2. Configure Credentials in n8n 1. Go to **Settings** โ†’ **Credentials** โ†’ **Add Credential** 2. Select **Plaid API** 3. Fill in: - **Environment**: Sandbox (for testing) or Production - **Client ID**: Your Plaid Client ID - **Secret**: Your Plaid Secret Key - **Access Token**: User access token from Plaid Link ### 3. Create Your First Workflow #### Basic Transaction Sync ``` [Cron: Every 6 hours] โ†’ [Plaid: Sync Transactions] โ†’ [Function: Process] โ†’ [Google Sheets: Log] ``` #### Real-time Spending Alert ``` [Cron: Hourly] โ†’ [Plaid: Sync Transactions] โ†’ [IF: Amount > $500] โ†’ [Slack: Alert] ``` ## ๐Ÿ“Š Supported Operations ### Transactions - **Sync**: Get new/updated transactions using cursor (recommended) - **Get Range**: Get transactions within specific date range ### Accounts - **Get All**: Get all connected accounts (cached data) - **Get Balances**: Get real-time account balances ### Auth - **Get**: Get bank account and routing numbers for ACH/wire transfers ### Institutions - **Search**: Find financial institutions by name - **Get by ID**: Get detailed institution information ### Items - **Get**: Get connection information and status - **Remove**: Disconnect bank account safely ### Identity - **Get**: Get account owner information and identity data ## ๐Ÿ’ก Example Workflows ### Daily Financial Summary ```json { "name": "Daily Financial Summary", "nodes": [ { "name": "Daily at 9 AM", "type": "n8n-nodes-base.cron" }, { "name": "Get Yesterday's Transactions", "type": "n8n-nodes-plaid.plaid", "parameters": { "resource": "transaction", "operation": "getRange", "startDate": "{{$today.minus({days: 1}).toFormat('yyyy-MM-dd')}}", "endDate": "{{$today.toFormat('yyyy-MM-dd')}}" } }, { "name": "Calculate Daily Spending", "type": "n8n-nodes-base.function" }, { "name": "Send Summary Email", "type": "n8n-nodes-base.gmail" } ] } ``` ### High Spending Alert ```json { "name": "High Spending Alert", "nodes": [ { "name": "Every Hour", "type": "n8n-nodes-base.cron" }, { "name": "Sync Recent Transactions", "type": "n8n-nodes-plaid.plaid", "parameters": { "resource": "transaction", "operation": "sync" } }, { "name": "Filter High Amounts", "type": "n8n-nodes-base.if", "parameters": { "conditions": { "number": [{ "value1": "={{$json.amount}}", "operation": "larger", "value2": 500 }] } } }, { "name": "Send Slack Alert", "type": "n8n-nodes-base.slack" } ] } ``` ## ๐Ÿ”’ Security & Best Practices ### Credential Security - All API keys encrypted by n8n - Environment isolation (Sandbox vs Production) - Access tokens never logged or exposed ### API Best Practices - Automatic rate limiting compliance - Proper error handling with retry logic - Request ID tracking for support - Efficient cursor-based pagination ### Data Handling - Enhanced categorization and enrichment - Spending analysis and scoring - Recurring transaction detection - Comprehensive transaction metadata ## ๐Ÿ› Troubleshooting ### Common Issues #### "Invalid access token" - Verify access token is correctly set in credentials - Ensure token is for the correct environment (Sandbox vs Production) - Check if user has revoked access in their bank portal #### "Institution not found" - Verify institution ID is correct - Check if institution supports requested products - Ensure country code matches institution location #### "Rate limit exceeded" - Node automatically handles rate limiting - Reduce frequency of cron triggers if needed - Use cursor-based sync instead of date ranges ### Getting Help 1. Check [Plaid API Status](https://status.plaid.com) 2. Review [Plaid Documentation](https://plaid.com/docs) 3. Open issue on [GitHub](https://github.com/jcdotio/n8n-nodes-plaid) ## ๐Ÿ“š Advanced Usage ### Custom Transaction Processing ```javascript // In Function node after Plaid node const transactions = $input.all(); const processedTransactions = transactions.map(item => { const transaction = item.json; return { json: { ...transaction, // Custom categorization custom_category: categorizeTransaction(transaction.name), // Business vs personal is_business: isBusinessTransaction(transaction), // Custom scoring priority_score: calculatePriority(transaction) } }; }); return processedTransactions; function categorizeTransaction(description) { if (description.includes('UBER') || description.includes('LYFT')) { return 'rideshare'; } if (description.includes('STARBUCKS') || description.includes('COFFEE')) { return 'coffee'; } return 'other'; } function isBusinessTransaction(transaction) { const businessKeywords = ['OFFICE', 'SUPPLIES', 'CONFERENCE', 'TRAVEL']; return businessKeywords.some(keyword => transaction.name.toUpperCase().includes(keyword) ); } function calculatePriority(transaction) { let score = 0; if (transaction.amount > 1000) score += 5; if (transaction.category_primary === 'Travel') score += 3; if (transaction.is_recurring) score -= 2; return Math.max(0, Math.min(10, score)); } ``` ### Multi-Account Processing ```javascript // Process multiple accounts with different logic const items = $input.all(); const accountRules = { 'checking': { limit: 1000, alert: true }, 'savings': { limit: 5000, alert: false }, 'credit': { limit: 500, alert: true } }; return items.map(item => { const transaction = item.json; const accountType = transaction.account_type; const rules = accountRules[accountType] || accountRules['checking']; return { json: { ...transaction, requires_alert: transaction.amount > rules.limit && rules.alert, account_rules: rules } }; }); ``` ## ๐Ÿ”„ Migration from HTTP Request Node If you're currently using HTTP Request nodes to call Plaid API directly: ### Before (HTTP Request) ```json { "name": "Manual Plaid Call", "type": "n8n-nodes-base.httpRequest", "parameters": { "method": "POST", "url": "https://sandbox.plaid.com/transactions/get", "body": { "access_token": "{{$credentials.plaidApi.accessToken}}", "start_date": "2024-01-01", "end_date": "2024-01-31" }, "headers": { "PLAID-CLIENT-ID": "{{$credentials.plaidApi.clientId}}", "PLAID-SECRET": "{{$credentials.plaidApi.secret}}" } } } ``` ### After (Plaid Node) ```json { "name": "Plaid Transactions", "type": "n8n-nodes-plaid.plaid", "parameters": { "resource": "transaction", "operation": "getRange", "startDate": "2024-01-01", "endDate": "2024-01-31" } } ``` ### Migration Benefits - โœ… **Simplified configuration** - no manual API calls - โœ… **Enhanced data** - automatic categorization and enrichment - โœ… **Better error handling** - user-friendly error messages - โœ… **Type safety** - proper TypeScript support - โœ… **Documentation** - built-in help and examples ## ๐Ÿ“ˆ Roadmap ### v1.1 (Next Release) - [ ] Webhook trigger node for real-time events - [ ] Investment accounts support - [ ] Liabilities data (loans, credit cards) - [ ] Enhanced spending analytics ### v1.2 (Future) - [ ] Assets product support - [ ] Income verification - [ ] Payment initiation - [ ] Multi-language support ### v2.0 (Long-term) - [ ] Advanced AI categorization - [ ] Fraud detection algorithms - [ ] Comprehensive reporting tools - [ ] Enterprise features ## ๐Ÿงช Testing This package includes a comprehensive testing suite to ensure reliability and quality. ### Quick Start ```bash # Run all tests npm test # Run with coverage npm run test:coverage # Run in watch mode npm run test:watch # Run specific test types npm run test:unit # Unit tests only npm run test:integration # Integration tests only npm run test:ci # CI/CD optimized run ``` ### Test Structure ``` tests/ โ”œโ”€โ”€ unit/ # Unit tests for individual components โ”‚ โ”œโ”€โ”€ Plaid.node.test.ts # Main node functionality โ”‚ โ””โ”€โ”€ PlaidHelpers.test.ts # Utility functions โ”œโ”€โ”€ integration/ # Integration tests for workflows โ”‚ โ””โ”€โ”€ PlaidWorkflow.test.ts # End-to-end workflow tests โ”œโ”€โ”€ mocks/ # Mock data and responses โ”‚ โ””โ”€โ”€ plaidApiMocks.ts # Plaid API mock responses โ””โ”€โ”€ README.md # Detailed testing guide ``` ### Test Coverage โœ… **51 total tests** covering: - **Transaction Operations**: Sync, range queries, filtering - **Account Operations**: Get all accounts, real-time balances - **Auth Operations**: Routing numbers, account numbers - **Institution Operations**: Search, details retrieval - **Item Management**: Get info, remove connections - **Identity Operations**: Account owner information - **Error Handling**: API errors, network issues, validation - **Environment Switching**: Sandbox โ†” Production - **Data Processing**: Enrichment, categorization, scoring - **Workflow Integration**: Multi-step processes, pagination ### Running Specific Tests ```bash # Unit tests only npm test -- tests/unit/ # Integration tests only npm test -- tests/integration/ # Specific test file npm test -- tests/unit/Plaid.node.test.ts # Test with verbose output npm test -- --verbose # Test specific pattern npm test -- --testNamePattern="should sync transactions" ``` ### Test Features #### Comprehensive Mocking - **Plaid API**: Complete SDK mocking for reliable tests - **n8n Runtime**: Mock execution context simulation - **Realistic Data**: Production-like mock responses #### Error Scenarios - API authentication failures - Network connectivity issues - Rate limiting responses - Invalid parameter handling - Data corruption scenarios #### Workflow Testing - Multi-step financial workflows - Cursor-based pagination - Batch processing - Error recovery patterns - Environment configuration ### Coverage Report Current coverage: **68%** with goals to reach 90%+ ```bash # Generate coverage report npm test -- --coverage # View HTML coverage report open coverage/lcov-report/index.html ``` ### Writing Tests Follow these patterns when adding new tests: ```typescript import { Plaid } from '../../nodes/Plaid/Plaid.node'; import { mockCredentials } from '../mocks/plaidApiMocks'; describe('New Feature', () => { let plaidNode: Plaid; beforeEach(() => { plaidNode = new Plaid(); // Setup mocks }); it('should handle specific scenario', async () => { // Arrange: Setup test data and mocks mockPlaidClient.newMethod.mockResolvedValue(mockResponse); // Act: Execute the functionality const result = await plaidNode.execute.call(mockExecute); // Assert: Verify expected outcomes expect(result).toBeDefined(); expect(mockPlaidClient.newMethod).toHaveBeenCalledWith(expectedParams); }); }); ``` ### Manual Testing For testing with real Plaid sandbox: 1. Get sandbox credentials from [Plaid Dashboard](https://dashboard.plaid.com) 2. Set environment variables: ```bash export PLAID_CLIENT_ID=your_sandbox_client_id export PLAID_SECRET=your_sandbox_secret export PLAID_ACCESS_TOKEN=your_sandbox_access_token ``` 3. Run integration tests: ```bash npm run test:integration ``` ### Continuous Integration Tests run automatically on: - Every commit - Pull requests - Release builds See [tests/README.md](tests/README.md) for complete testing documentation. ## ๐Ÿค Contributing We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details. ### Development Setup ```bash # Clone the repository git clone https://github.com/jcdotio/n8n-nodes-plaid.git cd n8n-nodes-plaid # Install dependencies npm install # Start development mode npm run dev # Run tests (important!) npm test # Build for production npm run build # Lint code npm run lint ``` ### Development Workflow 1. **Fork** the repository 2. **Create** a feature branch 3. **Write** tests for new functionality 4. **Implement** the feature 5. **Ensure** all tests pass (`npm test`) 6. **Submit** a pull request ### Code Quality Standards - โœ… All tests must pass - โœ… Code coverage > 68% (aim for 90%+) - โœ… ESLint compliance - โœ… TypeScript strict mode - โœ… Documentation updates ## ๐Ÿ“„ License MIT License - see [LICENSE](LICENSE) file for details. ## ๐Ÿ™ Acknowledgments - [Plaid](https://plaid.com) for their excellent financial API - [n8n](https://n8n.io) for the powerful workflow automation platform - The open source community for contributions and feedback --- **Made with โค๏ธ for the n8n community** Transform your financial data workflows with the power of Plaid and n8n!