Webhook-based AI agent system that integrates GoHighLevel (GHL) with LoopMessage for intelligent iMessage automation.
- Webhook-Based Architecture: Receive triggers from GHL automations and send results back
- AI-Powered Decisions: Uses Anthropic Claude for intelligent message generation and decision-making
- Context-Aware Responses: Integrates with Pinecone for relevant context retrieval
- Conversation Management: Tracks and manages conversation history
- iMessage Automation: Send and receive iMessages via LoopMessage API
- Comprehensive Logging: Winston-based logging for debugging and monitoring
- Rate Limiting: Built-in protection against abuse
- Auto-Response: Automatically responds to inbound messages with AI-generated replies
GHL Automation β Webhook β AI Agent β LoopMessage β iMessage
β β
Callback β Results β Processing β Response β Inbound Message
- Node.js v18+ and npm
- MongoDB (or MongoDB Atlas)
- LoopMessage account with API credentials
- Anthropic API key
- (Optional) Pinecone account for context retrieval
- Domain with HTTPS for webhook endpoints
git clone https://github.com/yourusername/ghl-loopmessage-integration.git
cd ghl-loopmessage-integration
npm installCopy env.example.txt to .env and fill in your credentials:
cp env.example.txt .env
nano .envRequired environment variables:
LOOPMESSAGE_AUTH_KEY- Your LoopMessage Authorization KeyLOOPMESSAGE_SECRET_KEY- Your LoopMessage Secret KeyLOOPMESSAGE_SENDER_NAME- Your sender name (e.g.,your.name@imsg.co)ANTHROPIC_API_KEY- Your Anthropic API keyWEBHOOK_SECRET- Create a strong random token for webhook authenticationDATABASE_URL- MongoDB connection string
npm run db:setupDevelopment mode:
npm run devProduction mode:
npm startServer will start on port 3000 (or your configured PORT).
GHL Inbound Webhook
POST /webhook/ghl-inbound
Receives triggers from GHL automations. Requires Authorization: Bearer {WEBHOOK_SECRET} header.
LoopMessage Callback
POST /webhook/loopmessage-callback
Receives inbound messages and status updates from LoopMessage.
Health Check
GET /health
Returns server health status and database connection status.
Get Conversation History
GET /api/conversation/:phone?limit=20
Retrieves conversation history for a specific phone number.
Get Webhook Logs
GET /api/logs?limit=50
Retrieves recent webhook logs.
- Go to Automations β Workflows
- Create new workflow
- Add your desired trigger (e.g., "Contact Tag Added")
URL:
https://your-domain.com/webhook/ghl-inbound
Method: POST
Headers:
{
"Content-Type": "application/json",
"Authorization": "Bearer your_webhook_secret_here"
}Body:
{
"event_type": "{{trigger_type}}",
"contact": {
"id": "{{contact.id}}",
"first_name": "{{contact.first_name}}",
"last_name": "{{contact.last_name}}",
"phone": "{{contact.phone}}",
"email": "{{contact.email}}"
},
"metadata": {
"trigger": "{{workflow.trigger}}",
"workflow_id": "{{workflow.id}}"
},
"callback_url": "{{webhook.url}}"
}Add a "Webhook Response" action after your webhook to receive the AI processing results.
Access the response data in subsequent actions:
{{webhook.response.status}}- Processing status{{webhook.response.ai_response.intent_detected}}- Detected intent{{webhook.response.ai_response.sentiment}}- Customer sentiment{{webhook.response.data.message_sent}}- Whether message was sent{{webhook.response.data.message_id}}- LoopMessage message ID
- Log in to LoopMessage Dashboard
- Go to Settings β Webhooks
- Set Webhook URL to:
https://your-domain.com/webhook/loopmessage-callback - Save settings
- Go to Settings β API Credentials
- Copy your Authorization Key and Secret Key
- Add them to your
.envfile
Edit prompts in src/services/ai-decision.js:
buildDecisionPrompt()- Controls AI decision-making for GHL webhooksbuildResponsePrompt()- Controls AI responses to inbound messages
buildDecisionPrompt(data, context, conversationHistory) {
return {
model: config.anthropic.model,
max_tokens: 1024,
messages: [{
role: "user",
content: `You are a friendly sales assistant for [YOUR COMPANY].
// Your custom instructions here
Always be professional and helpful...`
}]
};
}Stores all inbound and outbound messages:
contactPhone- Contact's phone numbermessageId- Unique message ID from LoopMessagedirection- 'inbound' or 'outbound'content- Message textstatus- Message delivery statusaiInsights- AI-generated insights (intent, sentiment, confidence)
Stores all webhook requests and responses:
requestId- Unique request identifiersource- 'ghl' or 'loopmessage'type- Webhook typepayload- Request payloadtimestamp- When webhook was received
# Login to Heroku
heroku login
# Create app
heroku create your-app-name
# Add MongoDB addon
heroku addons:create mongolab:sandbox
# Set environment variables
heroku config:set LOOPMESSAGE_AUTH_KEY=your_key
heroku config:set LOOPMESSAGE_SECRET_KEY=your_secret
heroku config:set ANTHROPIC_API_KEY=your_key
heroku config:set WEBHOOK_SECRET=your_secret
# Deploy
git push heroku main- Connect your GitHub repository
- Add environment variables in Railway dashboard
- Deploy automatically on push
# Build image
docker build -t ghl-loopmessage-integration .
# Run container
docker run -p 3000:3000 --env-file .env ghl-loopmessage-integrationLogs are stored in the logs/ directory:
combined.log- All logserror.log- Error logs only
Monitor server health:
curl https://your-domain.com/healthCheck conversation stats:
const Conversation = require('./src/models/Conversation');
const stats = await Conversation.getStats('+13231112233');- Use Strong Webhook Secret: Generate a cryptographically strong random token
- HTTPS Only: Always use HTTPS for webhook endpoints
- Validate All Input: Server validates all webhook payloads
- Rate Limiting: Built-in rate limiting protects against abuse
- Secure Credentials: Never commit
.envfile to version control - Monitor Logs: Regularly review logs for suspicious activity
- Check URL is correct and uses HTTPS
- Verify
Authorizationheader matchesWEBHOOK_SECRET - Check server logs for incoming requests
- Ensure firewall allows incoming connections
- Verify LoopMessage API credentials
- Check sender name is active in LoopMessage dashboard
- Ensure phone number is in correct format (+1XXXXXXXXXX)
- Review LoopMessage webhook logs for delivery status
- Verify
ANTHROPIC_API_KEYis valid - Check API quota/limits
- Review logs for API errors
- Test with simpler prompts
- Verify
DATABASE_URLis correct - Check MongoDB server is running
- Ensure IP whitelist includes your server (for MongoDB Atlas)
- Review database logs
- LoopMessage API Documentation
- Anthropic API Documentation
- GHL API Documentation
- Pinecone Documentation
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
MIT License - See LICENSE file for details
For issues or questions:
- Check the documentation in
Build Plan/directory - Review logs for error details
- Create an issue on GitHub
- Contact support@yourdomain.com
- Initial release with webhook-based architecture
- AI-powered decision making
- Conversation management
- Auto-response to inbound messages
Built with β€οΈ for seamless GHL-iMessage integration