Attentive

Omneo Attentive Extension

A multi-tenant Omneo extension that provides bidirectional synchronization between Omneo and Attentive, enabling unified customer profile management and marketing automation across both platforms.

πŸš€ Features

  • Bidirectional Profile Sync: Real-time synchronization of customer profiles between Omneo and Attentive
  • Smart Consent Management: Intelligent handling of email and SMS consent preferences with regional awareness
  • Event-Driven Architecture: Webhook-based communication ensuring data consistency
  • Multi-Region Support: Configurable for multiple Attentive instances with isolated configurations
  • Configurable Field Mapping: Flexible mapping between Omneo and Attentive profile fields
  • OAuth Authentication: Secure installation flow with Attentive OAuth integration
  • Cloud-Native: Built for Google Cloud Run with automatic scaling and deployment

πŸ“‹ Prerequisites

Before setting up the extension, ensure you have:

Omneo Credentials

  • Omneo URL: Your tenant URL (e.g., tenant.getomneo.com)
  • Omneo Token: API token with required scopes: create-profiles read-profiles update-profiles read-identities
  • Omneo Secret: Webhook verification secret from General Settings - App Key

Attentive Credentials

  • Client ID: The Attentive application client ID
  • Client Secret: The Attentive application client secret
  • Redirect URL: OAuth redirect URL for the installation flow

Infrastructure

  • Google Cloud Project with Cloud Run and Datastore enabled
  • GitHub repository with secrets configured
  • Domain for webhook endpoints

πŸ”§ Installation

1. OAuth Flow Setup

The extension provides a web-based installation flow. Currently, installation is done via the distribution URL acquired from the application.

  1. Authenticate with Attentive in the clients instance
  2. Paste distribution URL into browser
  3. Enter below details to authenticate
DataExample
Tenant NameThe Omneo tenant name, eg if your api url is https://api.sandbox.getomneo.com/api/v3 your tenant name is sandbox
Region HandleThe Omneo Region handle for this instance eg au. You only need to enter a value here if you are installing the application for multiple Attentive Instances on one Omneo instance
UsernameYour username to log in to CX Manager
PasswordYour password to log in to CX Manager

Once you have received a success manager, you're all done! The app has generated a bearer token and stored it securely in Omneo for use.

πŸ”„ Data Synchronization

Omneo β†’ Attentive Sync

Triggered by Omneo webhook events (profile.created, profile.updated):

  • Profile Creation: Creates new subscriber in Attentive with mapped attributes
  • Profile Updates: Updates existing Attentive subscriber with changed fields
  • Consent Management: Syncs email/SMS preferences based on Omneo communication settings
  • Regional Filtering: Will keep records isolated in the right instance

Attentive β†’ Omneo Sync

Triggered by Attentive webhook events:

  • email.subscribed / email.unsubscribed: Updates email preferences
  • sms.subscribed / sms.unsubscribed: Updates SMS preferences
  • custom_attribute.set: Syncs custom attribute changes

Supported Events

EventDirectionDescription
profile.createdOmneo β†’ AttentiveNew profile creation
profile.updatedOmneo β†’ AttentiveProfile field updates
email.subscribedAttentive β†’ OmneoEmail subscription
email.unsubscribedAttentive β†’ OmneoEmail unsubscription
sms.subscribedAttentive β†’ OmneoSMS subscription
sms.unsubscribedAttentive β†’ OmneoSMS unsubscription
custom_attribute.setAttentive β†’ OmneoCustom attribute updates

πŸ—ΊοΈ Field Mapping

The extension uses configurable field mappings stored in Google Cloud Datastore:

Default Mappings

Mappings should be stored in key:value pairs under each relevant area. The extension will be installed with some preset empty arrays for each required area, eg custom for custom_attributes and subscriber for subscriber specific mappings. Example:

{
  "custom": [
    {
      "omneo": "aggregations.most_transacted_location.name",
      "attentive": "oag_most_transacted_location_name"
    }
  ]
}

Core Profile Fields (Subscriber):

{
  "email": "email",
  "first_name": "first_name", 
  "last_name": "last_name",
  "mobile_phone": "phone"
}

Custom Attributes:

  • Configurable mapping between Omneo custom attributes and Attentive user properties
  • Supports nested attribute resolution
  • Bidirectional transformation

Consent Logic

Email Consent:

  • true: User opted in and not bounced
  • false: User opted out or email bounced
  • null: No subscription history (never subscribed)

SMS Consent:

  • true: User opted in for SMS and not bounced
  • false: User opted out or SMS bounced
  • null: No SMS subscription history

Sending Events To Attentive

The extension can template target data sent from Omneo to send custom events to Attentive for any use case you can think of. For example, if you want to know when a customer has made a transaction, you can configure a reaction/target combination in Omneo to then trigger a namespaced, easily identified event in Attentive for looking at data on the customer! Example data from target using a profile.updated/created event context:

{
    "type": "Testing Event",
    "externalEventId": "{{ A unique identifier to go here }}",
    "properties": {
        "profile_id": "{{ id }}",
        "example": "Information in a string"
    },
    "user": {
        "email": "{{ email }}"
    }
}

πŸ—οΈ Architecture

Core Components

  • Fastify Server: High-performance web framework
  • Plugin System: Modular architecture with Omneo and Attentive clients
  • Webhook Handlers: Event processing for both platforms
  • Job Processors: Background profile synchronization
  • Configuration Manager: Datastore-based tenant configuration

File Structure

src/
β”œβ”€β”€ public/
β”‚   └── pages/          # Public served pages for authentication
β”œβ”€β”€ routes/
β”‚   β”œβ”€β”€ auth/           # OAuth installation flow
β”‚   β”œβ”€β”€ webhooks/       # Webhook event handlers
β”‚   └── config/         # Configuration management
β”œβ”€β”€ plugins/
β”‚   β”œβ”€β”€ attentive/      # Attentive API client
β”‚   β”œβ”€β”€ omneo/          # Omneo API client
β”‚   └── util/           # Shared utilities
β”œβ”€β”€ jobs/
β”‚   β”œβ”€β”€ attentive/      # Attentive sync jobs
β”‚   └── omneo/          # Omneo sync jobs
└── types.ts            # TypeScript definitions

πŸ› οΈ Development

Local Setup

For developing locally you will need to either create a new test application in the Omneo Attentive sandbox instance, or use an existing one. Follow instructions from Attentive on App Setup

  1. Install dependencies:

    npm install
  2. Configure environment:

    cp .env.example .env
    # Edit .env with your configuration
  3. Start development server:

    # Terminal 1: Set up an ngrok tunnel
    ngrok http 3000
    
    Add ngrok URL to your .env file CLOUD_RUN_URL=
    
    # Terminal 2: Start Application
    npm run watch

Environment Variables

NODE_ENV=development
ATTENTIVE_APP_CLIENT_ID=your_client_id
ATTENTIVE_APP_CLIENT_SECRET=your_client_secret
ATTENTIVE_APP_REDIRECT_URL=your_redirect_url
CLOUD_RUN_URL=your_ngrok_url_for_local_dev

Testing with Datastore Emulator

# Start local datastore
npm run datastore-dev-start

# Reset datastore
npm run datastore-dev-reset

# Disable emulator
npm run datastore-dev-disable

Using Cloud Tasks Locally

For local development with Cloud Tasks:

  1. Set up ngrok: ngrok http 3000
  2. Set CLOUD_RUN_URL to your ngrok URL
  3. Cloud Tasks will call your local development server

🚒 Deployment

GitHub Actions

The repository includes automated deployment via GitHub Actions:

# Triggered on push to main branch
- Build Docker image
- Deploy to Google Cloud Run
- Set environment variables
- Configure service settings

Required GitHub Secrets

  • GCP_PROJECT_ID: Google Cloud project ID
  • GCP_SA_KEY: Service account key for deployment
  • ATTENTIVE_APP_CLIENT_ID: Attentive OAuth client ID
  • ATTENTIVE_APP_CLIENT_SECRET: Attentive OAuth client secret
  • ATTENTIVE_APP_REDIRECT_URL: OAuth redirect URL

Manual Deployment

# Build and deploy
gcloud builds submit --tag gcr.io/PROJECT_ID/extension-attentive
gcloud run deploy extension-attentive \
  --image gcr.io/PROJECT_ID/extension-attentive \
  --region australia-southeast1 \
  --allow-unauthenticated

πŸ” Monitoring & Logging

Structured Logging

All operations include structured logs with:

  • Profile IDs
  • Tenant information
  • Event types
  • Error details
  • Performance metrics

Health Checks

  • GET /health: Service health status
  • Webhook endpoint validation
  • Database connectivity checks

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/new-feature
  3. Make changes and add tests
  4. Run linting: npm run lint-fix
  5. Commit changes: git commit -m 'Add new feature'
  6. Push to branch: git push origin feature/new-feature
  7. Submit a pull request

πŸ“ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ†˜ Support

For support and questions:

  • Create an issue in this repository
  • Contact the Omneo development team
  • Check the Omneo documentation

Built with ❀️ by the Omneo team