sparrow-starter-kit
v1.0.0
Published
comprehensive OAuth integration framework for automated survey distribution with data mapping and trigger capabilities
Maintainers
Readme
🚀 Integration Framework
A comprehensive OAuth integration framework for automated survey distribution with data mapping and trigger capabilities
✨ Features
- 🔐 OAuth 2.0 Integration - Complete authentication flow with automatic token refresh
- 🗺️ Data Mapping Engine - Transform external data to survey variables
- ⚡ Trigger System - Event-driven survey automation with polling capabilities
- 💾 Persistent Storage - Built-in storage management for tokens and configurations
- 📊 Multi-Channel Support - Email, SMS, and other survey distribution channels
- 🔄 FHIR API Integration - Healthcare data polling and processing
- 📈 Comprehensive Logging - Detailed monitoring and error tracking
📦 Installation
npm install blindgate🚀 Quick Start
Import All Components
const { BackendTemplate, Mapping, Trigger } = require('blindgate');🔐 OAuth Integration (BackendTemplate)
Handle complete OAuth 2.0 flow with automatic token management:
const integration = new BackendTemplate(
'appnest-user-123', // AppNest User ID
'product-456', // Product ID
'user-789', // User ID
'your-client-id', // OAuth Client ID
'your-client-secret', // OAuth Client Secret
'https://your-app.com/callback', // Redirect URI
'MyIntegration' // Integration Name
);
// Exchange authorization code for tokens
async function authenticate(authCode) {
try {
const tokens = await integration.exchangeAuthCode(authCode);
console.log('Authentication successful:', tokens);
} catch (error) {
console.error('Auth failed:', error);
}
}
// Make authenticated API requests
async function fetchData() {
try {
const response = await integration.makeRequest({
method: 'GET',
endPoint: '/v3/users',
queryString: 'limit=10'
});
return response.data;
} catch (error) {
console.error('API request failed:', error);
}
}
// Check user features
async function checkFeature() {
const hasAdvancedFeature = await integration.checkHasFeature('advanced_surveys');
console.log('Advanced surveys available:', hasAdvancedFeature);
}🗺️ Data Mapping Engine
Transform external system data to survey-compatible format:
const mapper = new Mapping(parentLayer, 'MyIntegration');
// Save field mappings
async function setupMappings() {
const mappings = [
{
fields: [
{
surveySparrowField: { value: 'patient_name' },
integrationField: { value: 'fullName' },
mappedType: { value: 'QUESTION' },
defaultValue: { value: 'Unknown Patient' }
},
{
surveySparrowField: { value: 'appointment_date' },
integrationField: { value: 'scheduledDate' },
mappedType: { value: 'VARIABLE' },
defaultValue: { value: new Date().toISOString() }
}
]
}
];
await mapper.handleSaveMapping('survey-123', mappings, parentLayer);
}
// Transform data using mappings
async function transformData() {
const externalData = {
data: {
answers: { 'patient_name': { answer: 'John Doe' } },
variables: { 'appointment_date': '2024-01-15T10:00:00Z' },
expressions: {},
contact: { email: '[email protected]', phone: '+1234567890' }
}
};
const mapping = await mapper.handleGetMappings('survey-123', parentLayer);
const transformedData = await mapper.getAnswerMapping(mapping.data.data[0], externalData);
console.log('Transformed data:', transformedData);
// Output: { fullName: 'John Doe', scheduledDate: '2024-01-15T10:00:00Z' }
}⚡ Trigger System
Automate survey distribution based on external events:
const triggerEngine = new Trigger(parentLayer, 'MyIntegration');
// Setup polling triggers
async function setupTriggers() {
const triggers = [
{
id: 'patient-survey-trigger',
isEnabled: true,
object: 'Patient', // FHIR resource type
triggerDetails: {
variables: [
{ value: 'patient_id', type: 'TEXT' },
{ value: 'visit_date', type: 'DATE' },
{ value: 'satisfaction_score', type: 'NUMBER' }
]
}
}
];
// Save triggers and start polling (every 10 minutes)
await triggerEngine.handleSaveTrigger(
'survey-123', // Survey ID
triggers, // Trigger configurations
'patient-survey-trigger', // Trigger ID
parentLayer, // Context
true // Enable polling
);
}
// Handle scheduled polling events
async function handlePollingEvent() {
await triggerEngine.handleScheduleEvent('survey-123', parentLayer);
}
// Manual survey triggering
async function triggerSurvey() {
const variables = {
patient_id: 'P-12345',
visit_date: '2024-01-15',
satisfaction_score: 0
};
const contact = {
email: '[email protected]',
firstName: 'John',
lastName: 'Doe'
};
await triggerEngine.triggerSurvey(
'survey-123',
variables,
contact,
'EMAIL' // or 'SMS'
);
}🏗️ Complete Integration Example
Build a healthcare patient feedback system:
const { BackendTemplate, Mapping, Trigger } = require('blindgate');
class HealthcareIntegration {
constructor(config) {
this.oauth = new BackendTemplate(
config.appnestUserId,
config.productId,
config.userId,
config.clientId,
config.clientSecret,
config.redirectUri,
'HealthcareFeedback'
);
this.mapper = new Mapping(config.parentLayer, 'HealthcareFeedback');
this.trigger = new Trigger(config.parentLayer, 'HealthcareFeedback');
this.surveyId = config.surveyId;
this.parentLayer = config.parentLayer;
}
async initialize(authCode) {
// 1. Complete OAuth flow
await this.oauth.exchangeAuthCode(authCode);
// 2. Setup field mappings
await this.setupFieldMappings();
// 3. Configure triggers
await this.setupEventTriggers();
console.log('Healthcare integration initialized successfully');
}
async setupFieldMappings() {
const mappings = [{
fields: [
{
surveySparrowField: { value: 'patient_name' },
integrationField: { value: 'fullName' },
mappedType: { value: 'CONTACT' }
},
{
surveySparrowField: { value: 'appointment_type' },
integrationField: { value: 'serviceType' },
mappedType: { value: 'VARIABLE' }
},
{
surveySparrowField: { value: 'provider_name' },
integrationField: { value: 'doctorName' },
mappedType: { value: 'VARIABLE' }
}
]
}];
await this.mapper.handleSaveMapping(this.surveyId, mappings, this.parentLayer);
}
async setupEventTriggers() {
const triggers = [{
id: 'appointment-completed',
isEnabled: true,
object: 'Encounter',
triggerDetails: {
variables: [
{ value: 'appointment_id', type: 'TEXT' },
{ value: 'completion_time', type: 'DATETIME' },
{ value: 'service_type', type: 'TEXT' }
]
}
}];
await this.trigger.handleSaveTrigger(
this.surveyId,
triggers,
'appointment-completed',
this.parentLayer,
true // Enable polling
);
}
async sendPatientSurvey(patientData, appointmentData) {
const variables = {
appointment_id: appointmentData.id,
service_type: appointmentData.serviceType,
doctor_name: appointmentData.provider
};
const contact = {
email: patientData.email,
firstName: patientData.firstName,
lastName: patientData.lastName,
phone: patientData.phone
};
await this.trigger.triggerSurvey(
this.surveyId,
variables,
contact,
'EMAIL'
);
}
}
// Usage
const integration = new HealthcareIntegration({
appnestUserId: 'user-123',
productId: 'healthcare-app',
userId: 'clinic-456',
clientId: process.env.OAUTH_CLIENT_ID,
clientSecret: process.env.OAUTH_CLIENT_SECRET,
redirectUri: 'https://myapp.com/oauth/callback',
surveyId: 'patient-satisfaction-survey',
parentLayer: { /* context object */ }
});🔧 Storage Management
Both BackendTemplate and components provide storage utilities:
// Store configuration data
await integration.setStorageV2({
key: 'integration_settings',
data: {
pollInterval: 600000,
maxRetries: 3,
enableNotifications: true
}
});
// Retrieve stored data
const settings = await integration.getStorageV2({
key: 'integration_settings'
});📊 Error Handling & Logging
The framework includes comprehensive error handling:
try {
await integration.makeRequest({
method: 'POST',
endPoint: '/v3/surveys/trigger',
payload: surveyData
});
} catch (error) {
// Automatic error logging and alerting
await integration.alert(error);
console.error('Survey trigger failed:', error);
}🛠️ API Reference
BackendTemplate
makeRequest(options)- Authenticated HTTP requestsexchangeAuthCode(code)- OAuth token exchangegetUser()- Get current user infocheckHasFeature(feature)- Feature availability checksetStorageV2(data)/getStorageV2(key)- Data persistence
Mapping
handleSaveMapping(id, mappings, context)- Save field mappingshandleGetMappings(id, context)- Retrieve mappingsgetAnswerMapping(mapping, data)- Transform data
Trigger
handleSaveTrigger(surveyId, triggers, triggerId, context, polling)- Configure triggerstriggerSurvey(surveyId, variables, contact, channel)- Send surveyhandleScheduleEvent(surveyId, context)- Process scheduled events
📄 License
MIT © 2024
