Skip to main content

Building Extensions

Build custom extensions to integrate Valmi Value with any external system.

Extension Template

Start with the valext extension template:
git clone https://github.com/valmi-io/valext-template
cd valext-template
npm install  # or pip install for Python

Extension Structure

my-extension/
├── src/
│   ├── index.js          # Main extension code
│   ├── handlers/         # Event handlers
│   └── mappers/          # Data mappers
├── config/
│   └── config.json       # Extension configuration
├── tests/
│   └── test.js           # Tests
└── package.json          # Dependencies

Example Extension (Python)

from valext import Extension, EventHandler

class MyExtension(Extension):
    def __init__(self):
        super().__init__(
            name="my-extension",
            version="1.0.0",
            events=["invoice.created", "payment.successful"]
        )
    
    @EventHandler("invoice.created")
    def handle_invoice_created(self, event):
        invoice = event.data
        
        # Transform data
        payload = self.map_to_external_system(invoice)
        
        # Call external API
        response = self.call_external_api(payload)
        
        # Report result
        if response.success:
            self.report_success(event.id)
        else:
            self.report_failure(event.id, response.error)
    
    def map_to_external_system(self, invoice):
        return {
            "id": invoice.id,
            "amount": invoice.amount,
            "customer": invoice.account.name
        }
    
    def call_external_api(self, payload):
        # Your API call logic
        pass

Example Extension (Node.js)

const { Extension, EventHandler } = require('valext');

class MyExtension extends Extension {
    constructor() {
        super({
            name: 'my-extension',
            version: '1.0.0',
            events: ['invoice.created', 'payment.successful']
        });
    }
    
    @EventHandler('invoice.created')
    async handleInvoiceCreated(event) {
        const invoice = event.data;
        
        // Transform data
        const payload = this.mapToExternalSystem(invoice);
        
        // Call external API
        const response = await this.callExternalAPI(payload);
        
        // Report result
        if (response.success) {
            this.reportSuccess(event.id);
        } else {
            this.reportFailure(event.id, response.error);
        }
    }
    
    mapToExternalSystem(invoice) {
        return {
            id: invoice.id,
            amount: invoice.amount,
            customer: invoice.account.name
        };
    }
    
    async callExternalAPI(payload) {
        // Your API call logic
    }
}

Testing Extensions

Test extensions locally:
# test_extension.py
from my_extension import MyExtension

extension = MyExtension()

# Simulate event
event = {
    "id": "event_123",
    "type": "invoice.created",
    "data": {
        "id": "inv_abc123",
        "amount": 1000.00
    }
}

# Handle event
extension.handle_invoice_created(event)

Publishing Extensions

Publish extensions to the valext registry:
  1. Prepare Extension:
    • Write documentation
    • Add tests
    • Version your extension
  2. Submit to Registry:
    valext publish my-extension
    
  3. Extension Available:
    • Others can install your extension
    • Extension appears in Valmi Value UI

Extension Best Practices

  • Error Handling: Handle all error cases gracefully
  • Retries: Implement retry logic for transient failures
  • Logging: Log all operations for debugging
  • Testing: Write comprehensive tests
  • Documentation: Document configuration and usage
  • Versioning: Use semantic versioning

Extension Examples

Check out example extensions:

Extension Support

Get help building extensions: