Appgain Integration Documentation¶
Overview¶
This document explains how the Appgain integration works in ConnectGain, including how suitId and API keys are obtained and stored.
Integration Flow¶
1. User Signup Process¶
When a new user signs up for ConnectGain:
- Frontend Collection: User fills out signup form including:
- Email (required)
- Password (required)
- Organization Name (required)
- First Name (optional)
- Last Name (optional)
-
Phone Number (optional, but recommended for WhatsApp integration)
-
Appgain Webhook Call: Before creating the user account, the frontend calls the Appgain signup webhook:
-
Webhook Response: The Appgain webhook returns:
-
User Account Creation: The user account is created with Appgain credentials stored in user metadata as backup.
-
Database Trigger: The
handle_new_userdatabase trigger: - Creates the organization
- Checks for Appgain credentials in user metadata
- If not found, calls the webhook again from the database
- Stores credentials in organization settings
2. Credential Storage¶
Appgain credentials are stored in two places:
-
Organization Settings (Primary):
organizations.settingsJSONB column -
User Metadata (Backup):
auth.users.raw_user_meta_data
3. Credential Retrieval¶
Session-Based Credentials (Recommended): Credentials are now automatically loaded into the user session on login and available throughout the app:
// In any component, access credentials from session
const { appgainCredentials } = useAuth;
if (appgainCredentials) {
const { apiKey, suitId } = appgainCredentials;
// Use credentials directly
}
Database Fallback (Legacy): For backward compatibility, credentials can still be retrieved from organization settings:
const { data: orgSettings } = await supabase.from('organizations').select('settings').eq('id', organizationId).single;
const settings = orgSettings?.settings || {};
const apiKey = settings.appgain_api_key;
const suitId = settings.appgain_suit_id;
Webhook Configuration¶
Webhook URL¶
Note: This is a test webhook that requires manual activation in the n8n canvas. Click "Execute workflow" button before testing.
Webhook Payload Format¶
{
"platform": "connectGain",
"phone": "+201001383533",
"email": "yowiriy663@lespedia.com",
"name": "appgain mahmoud",
"password": "333",
"org": "app55"
}
Example cURL Command¶
curl --location 'https://n8n.instabackend.io/webhook/connectGain-onSignup' \
--header 'Content-Type: application/json' \
--data-raw '{
"platform": "connectGain",
"phone": "+201001383533",
"email": "yowiriy663@lespedia.com",
"name": "appgain mahmoud",
"password": "333",
"org": "app55"
}'
Expected Response Format¶
Error Handling¶
Frontend Error Handling¶
- If webhook call fails, user account is still created
- Warning message is shown to user
- User can configure Appgain integration later in settings
Database Error Handling¶
- Webhook failures don't prevent user creation
- Errors are logged as warnings
- Graceful fallback to manual configuration
Usage in Campaigns¶
When sending campaigns, the system now:
- Uses session credentials (faster, no database query needed)
- Extracts
apiKeyandsuitIdfrom session - Uses these credentials to authenticate with Appgain services
- Constructs API URLs:
https://notify.appgain.io/${suitId}/send
// Campaign system now uses session credentials
const { appgainCredentials } = useAuth;
if (!appgainCredentials) {
throw new Error('Appgain credentials not available. Please log in again.');
}
const { apiKey, suitId } = appgainCredentials;
// Use credentials for API calls
Testing¶
Test the Webhook¶
Manual Testing¶
- Sign up a new user with phone number
- Check browser console for webhook response
- Verify credentials are stored in organization settings
- Test campaign sending functionality
Troubleshooting¶
Common Issues¶
- Webhook Returns 404
- Check if using test URL (requires manual activation)
- Verify webhook endpoint is correct
-
Ensure n8n workflow is active
-
Missing Credentials
- Check organization settings in database
- Verify webhook response format
-
Check database trigger logs
-
Campaign Sending Fails
- Verify credentials exist in organization settings
- Check API key and suit ID format
- Test webhook endpoint manually
Database Queries¶
Check organization settings:
Check user metadata:
Security Considerations¶
- API Keys: Stored encrypted in database
- Webhook Security: Use HTTPS endpoints only
- Access Control: Only organization owners can view/update settings
- Logging: Sensitive data is masked in logs
Existing Users Support¶
For existing users who signed up before the Appgain integration was implemented:
Automatic Credential Assignment¶
- All existing organizations automatically receive the default Appgain credentials
- Credentials are added via database migration when the system is updated
- No action required from existing users
Login Process for Existing Users¶
When existing users log in, they will receive their Appgain credentials:
// After successful login, credentials are available via:
const { data: loginData } = await supabase.rpc('get_user_login_data', { _user_id: user.id });
// Returns:
{
"user_id": "user-uuid",
"email": "user@example.com",
"organization_name": "User Organization",
"appgain_credentials": {
"suitId": "YOUR_SUIT_ID",
"apiKey": "YOUR_APPGAIN_API_KEY"
}
}
Credential provisioning¶
Appgain credentials (Suit ID + API Key) are provisioned automatically for each organization and delivered to the app at login via the get_user_login_data RPC — you never paste them in by hand. Treat the API Key as a secret: it is used server-side only and is never exposed in the browser. Use placeholders such as YOUR_SUIT_ID / YOUR_APPGAIN_API_KEY in any example or request.
Session-Based Credential System¶
How It Works¶
- On Login: User credentials are automatically fetched from the database and stored in the React context
- In Components: Any component can access credentials via
useAuthhook - No Database Queries: Campaign sending and other operations use session credentials directly
- Automatic Updates: Credentials are refreshed when user logs in/out
Benefits¶
- Performance: No database queries needed for each campaign send
- Consistency: Credentials are always available when user is logged in
- Security: Credentials are stored in memory, not persisted in browser storage
- Simplicity: Single source of truth for credentials
Implementation¶
// In any component
import { useAuth } from '@/hooks/useAuth';
function MyComponent {
const { appgainCredentials, loading } = useAuth;
if (loading) return <div>Loading...</div>;
if (!appgainCredentials) {
return <div>Please log in to access Appgain features</div>;
}
const { apiKey, suitId } = appgainCredentials;
// Use credentials for API calls
}
Future Enhancements¶
- Credential Rotation: Implement automatic key rotation
- Multiple Providers: Support for multiple Appgain accounts
- Webhook Retry: Implement retry logic for failed webhook calls
- Settings UI: Add UI for manual credential configuration
- Per-User Credentials: Allow individual users to have their own Appgain credentials