Automation Setup Guide¶
This guide demonstrates how to create and manage workflows that enable automatic action item assignment through AI-powered phrase matching.
Overview¶
Automations allow your partner application to directly receive action items from Contio meetings based on phrase matching. When an action item matches your automation phrases, Contio will:
- Create an automation assignment linking the action item to your partner app
- Send a
automation.assignment.createdwebhook to your configured webhook URL - Send
action_item.updatedwebhooks when the action item is modified
Automation Concepts¶
What is an Automation?¶
A partner automation defines:
- Name: Display name for the automation
- Description: What the automation handles
- Actions: Array of action configurations (currently supports
phrase_matchtype)- Type:
"phrase_match"for phrase-based matching - Config: Contains
phrasesarray with matching phrases
- Type:
- Status:
activeorinactive
AI Matching Process¶
- Action items are extracted from meeting transcripts by the AI agent
- For meetings with participants connected to partner apps, active automations are loaded
- Automation trigger phrases are passed to the AI agent as EntityMappings
- The AI agent matches action items against automation phrases
- Matched items are assigned to partner automation with confidence scores
- Webhook notifications are sent to partner applications
Creating Automations¶
Initialize Admin Client¶
import { ContioPartnerSDK } from '@contio/partner-sdk';
const sdk = new ContioPartnerSDK({
apiKey: process.env.CONTIO_ADMIN_API_KEY!,
apiUrl: process.env.CONTIO_API_URL || 'https://api.contio.ai'
});
const adminClient = sdk.forAdmin();
Create a Contact Automation¶
async function createContactAutomation() {
const automation = await adminClient.createAutomation({
name: 'Create CRM Contact',
description: 'Create new contacts in CRM from meeting participants',
trigger_type: 'action_item_match',
actions: [
{
type: 'phrase_match',
config: {
phrases: [
'create contact',
'add contact',
'new contact',
'save contact information',
'add to CRM'
]
}
}
]
});
console.log('Contact automation created:', automation.id);
return automation;
}
Create a Deal Automation¶
async function createDealAutomation() {
const automation = await adminClient.createAutomation({
name: 'Create Sales Deal',
description: 'Create new deals in CRM from meeting discussions',
trigger_type: 'action_item_match',
actions: [
{
type: 'phrase_match',
config: {
phrases: [
'create deal',
'new opportunity',
'potential sale',
'follow up on proposal',
'send quote',
'prepare contract'
]
}
}
]
});
console.log('Deal automation created:', automation.id);
return automation;
}
Create a Task Automation¶
async function createTaskAutomation() {
const automation = await adminClient.createAutomation({
name: 'Assign Follow-up Task',
description: 'Create follow-up tasks in project management tool',
trigger_type: 'action_item_match',
actions: [
{
type: 'phrase_match',
config: {
phrases: [
'follow up',
'schedule meeting',
'send email',
'prepare document',
'review proposal',
'create task'
]
}
}
]
});
console.log('Task automation created:', automation.id);
return automation;
}
Configure Webhook URL¶
Before receiving webhooks, configure your partner app's webhook URL:
async function configureWebhook() {
const partnerApp = await adminClient.updatePartnerApp({
webhook_url: 'https://your-app.com/webhooks/contio',
});
console.log('Webhook URL configured:', partnerApp.webhook_url);
}
Handle Automation Webhooks¶
import { verifyWebhookSignature } from '@contio/partner-sdk';
import express from 'express';
app.post('/webhooks/contio', express.raw({ type: 'application/json' }), async (req, res) => {
const signature = req.headers['x-contio-signature'] as string;
const payload = req.body.toString();
// Verify signature using your partner app's webhook_secret
if (!verifyWebhookSignature(payload, signature, process.env.CONTIO_WEBHOOK_SECRET!)) {
return res.status(401).json({ error: 'Invalid signature' });
}
const event = JSON.parse(payload);
try {
switch (event.event_type) {
case 'automation.assignment.created':
await handleAutomationAssignmentCreated(event);
break;
case 'action_item.updated':
await handleActionItemUpdated(event);
break;
default:
console.log('Unknown event type:', event.event_type);
}
res.status(200).json({ success: true });
} catch (error) {
console.error('Webhook processing error:', error);
res.status(500).json({ error: 'Processing failed' });
}
});
Handle Automation Assignment Created¶
async function handleAutomationAssignmentCreated(event: any) {
const { automation_assignment } = event.data;
console.log('New automation assignment:', automation_assignment.id);
console.log('Automation:', automation_assignment.automation_name);
console.log('Action Item:', automation_assignment.action_item.description);
console.log('Confidence:', automation_assignment.confidence_score);
// Process based on automation
const automationName = automation_assignment.automation_name;
const actionItem = automation_assignment.action_item;
if (automationName.includes('Contact')) {
await createCRMContact(actionItem);
} else if (automationName.includes('Deal')) {
await createCRMDeal(actionItem);
} else if (automationName.includes('Task')) {
await createProjectTask(actionItem);
}
}
Handle Action Item Updates¶
async function handleActionItemUpdated(event: any) {
const { action_item } = event.data;
console.log('Action item updated:', action_item.action_item_id);
console.log('Is completed:', action_item.is_completed);
// Sync updates to your system
await syncActionItemUpdate(action_item);
}
Managing Automations¶
List Automations¶
async function listAutomations() {
const automations = await adminClient.listAutomations({
page: 1,
limit: 100,
status: 'active'
});
console.log('Active automation:');
automations.data.forEach(automation => {
console.log(`- ${automation.name}: ${automation.description}`);
console.log(` Status: ${automation.status}`);
// Display phrases
const phraseAction = automation.actions.find(a => a.type === 'phrase_match');
if (phraseAction?.config.phrases) {
console.log(` Phrases: ${phraseAction.config.phrases.join(', ')}`);
}
});
return automations;
}
Update Automations Phrases¶
async function updateAutomationmw(automationId: string) {
const updated = await adminClient.updateAutomation(automationId, {
actions: [
{
type: 'phrase_match',
config: {
phrases: [
'updated phrase',
'new keyword',
'additional trigger'
]
}
}
]
});
console.log('Automation updated:', updated);
return updated;
}
Deactivate Automation¶
async function deactivateAutomation(automationId: string) {
const updated = await adminClient.updateAutomation(automationId, {
status: 'inactive'
});
console.log('Automation deactivated:', automationId);
return updated;
}
Best Practices¶
Phrase Design¶
- Use specific, action-oriented phrases
- Include variations and synonyms (e.g., "create contact", "add contact", "new contact")
- Avoid overly broad phrases that may cause false matches
- Test phrases with sample action items before deployment
- Consider industry-specific terminology
- Keep phrases concise and focused
Webhook Security¶
- Always verify webhook signatures using the SDK's
verifyWebhookSignaturefunction - Use HTTPS endpoints only
- Implement rate limiting on your webhook endpoint
- Log all webhook events for auditing and debugging
- Store webhook secrets securely (environment variables, secret managers)
Error Handling¶
- Implement retry logic with exponential backoff for transient failures
- Return 200 OK quickly to acknowledge receipt, then process asynchronously
- Use dead letter queues for failed processing
- Monitor webhook delivery success rates
Performance Optimization¶
- Process webhooks asynchronously (queue-based processing)
- Batch operations when possible
- Cache frequently accessed data
- Monitor processing times and optimize bottlenecks
Troubleshooting¶
Automation Not Matching Action Items¶
- Review phrase list - ensure phrases are specific and action-oriented
- Verify automation status is
active - Check that users in the meeting are connected to your partner app
- Test phrases against sample action item descriptions
- Review confidence scores in webhook payloads
Webhook Delivery Failures¶
- Verify webhook URL is publicly accessible (HTTPS required)
- Check signature verification logic
- Review firewall/security settings
- Ensure webhook endpoint returns 200 OK within timeout
Missing Webhook Events¶
- Confirm
webhook_urlis configured on your partner app - Verify
webhook_secretis correctly stored - Check that action items have
has_partner_assignment = true
Next Steps¶
- OAuth 2.0 Flow - Implement user authentication
- SDK Examples - Common SDK usage patterns
- Webhook Events - All webhook event types and payloads
- API Guide - Complete API reference