Tag Automation System for SalesMsg AI Inbox

Status: ✅ Built and Ready for Testing
Date: 2026-02-26
Subagent: tag-automation


Overview

Automated tag-based workflow system that detects SalesMessage contact tags and triggers appropriate actions in HubSpot and Better Acquisitions.


Tag Patterns

1. Base Tag: Property View Tracking

Format: ST# ST NAME CITY STATE
Example: 1088 Peaceful Dr Corona CA

Actions:

  • ✅ Find associated HubSpot deal by property address
  • ✅ Create Property View custom object in HubSpot
  • ✅ Associate view with deal and contact
  • ✅ Track view date/time

2. Showing Request

Format: ST# ST NAME CITY STATE show req
Example: 1088 Peaceful Dr Corona CA show req

Actions:

  • ✅ Find associated HubSpot deal
  • ✅ Create Showing Request custom object (status: requested)
  • ✅ Associate with deal and contact
  • ✅ Store contact info (name, phone, email)

3. Showing Confirmed

Format: ST# ST NAME CITY STATE show conf
Example: 1088 Peaceful Dr Corona CA show conf

Actions:

  • ✅ Find associated HubSpot deal
  • ✅ Update existing Showing Request to “confirmed” status
    • OR create new Showing with “confirmed” status if none exists
  • ✅ Store confirmed date/time
  • ⏳ Create calendar event (TODO: requires calendar API integration)
  • ⏳ Schedule 24h follow-up task (TODO: requires tasks API integration)

4. Offer Submitted

Format: ST# ST NAME CITY STATE offer
Example: 1088 Peaceful Dr Corona CA offer

Actions:

  • ✅ Find associated HubSpot deal
  • ✅ Find or create contact by phone/email
  • ✅ Associate contact with deal (role: B = Buyer)
  • ✅ Create HubSpot Offer custom object
  • ✅ Create Better Acquisitions offer (Supabase)
  • ✅ Link HubSpot Offer ID to Better Acquisitions record
  • ⏳ Update deal stage (TODO: requires pipeline stage mapping)

Components

1. Tag Automation Handler

File: /workspace/scripts/tag-automation-handler.js

Core orchestrator that:

  • Parses tag format
  • Routes to appropriate handler
  • Coordinates HubSpot + Better Acq actions
  • Prevents duplicate object creation

Usage:

node tag-automation-handler.js "<tag>" [contactId] [contactName] [contactPhone] [contactEmail]

2. HubSpot Custom Object Manager

File: /workspace/scripts/hubspot-custom-object-manager.js

Manages HubSpot custom objects:

  • Property Views (2-53061858)
  • Showing Requests (2-53061855)
  • Offers (2-52966180)

Key Functions:

  • createPropertyView()
  • createShowingRequest()
  • updateShowingRequest()
  • createOffer()
  • findOrCreateContact()
  • Duplicate prevention via search

3. Better Acquisitions Offer Creator

File: /workspace/scripts/better-acq-offer-creator.js

Writes offers to Better Acquisitions Supabase:

  • Project: pxzxcfjgpteitwktkkiz
  • Table: acquisition_deals
  • Links HubSpot Offer ID
  • Stores offer details (amount, financing, contingencies)

Key Functions:

  • createOffer()
  • getOfferByHubSpotId()
  • updateOfferStatus()
  • linkHubSpotDeal()

4. Tag Management API Endpoints

Server: lovable-api-server.js (port 18799)

Three new endpoints:

POST /api/salesmsg/tags/add

Add tag to SalesMessage conversation + trigger automation

Body:

{
  "conversationId": "12345",
  "tag": "1088 Peaceful Dr Corona CA show req",
  "contactInfo": {
    "contactId": null,
    "contactName": "John Doe",
    "contactPhone": "555-1234",
    "contactEmail": "john@example.com"
  }
}

Response:

{
  "success": true,
  "conversationId": "12345",
  "tag": "1088 Peaceful Dr Corona CA show req",
  "tagAdded": { ... },
  "automation": {
    "success": true,
    "showingId": "67890",
    "dealId": "54223789480",
    "action": "showing_requested"
  }
}

POST /api/salesmsg/tags/update

Update tag (remove old, add new) + trigger automation

Body:

{
  "conversationId": "12345",
  "oldTag": "1088 Peaceful Dr Corona CA show req",
  "newTag": "1088 Peaceful Dr Corona CA show conf",
  "contactInfo": { ... }
}

POST /api/salesmsg/tags/process

Test automation without modifying SalesMessage tags

Body:

{
  "tag": "1088 Peaceful Dr Corona CA offer",
  "contactInfo": { ... }
}

Testing

Unit Test Script

File: /workspace/scripts/test-tag-automation.js

Tests all 4 tag patterns:

node scripts/test-tag-automation.js

Output:

  • ✅/❌ status for each pattern
  • Object IDs created (views, showings, offers)
  • Full results logged to logs/tag-automation-test-results.json

Manual Testing

  1. Property View:
node scripts/tag-automation-handler.js "1088 Peaceful Dr Corona CA" null "Test Viewer" "555-0001"
  1. Showing Request:
node scripts/tag-automation-handler.js "1088 Peaceful Dr Corona CA show req" null "Test Requester" "555-0002"
  1. Showing Confirmed:
node scripts/tag-automation-handler.js "1088 Peaceful Dr Corona CA show conf" null "Test Confirmed" "555-0003"
  1. Offer:
node scripts/tag-automation-handler.js "1088 Peaceful Dr Corona CA offer" null "Test Buyer" "555-0004" "buyer@test.com"

API Testing

# Test tag processing (no SalesMessage modification)
curl -X POST http://localhost:18799/api/salesmsg/tags/process \
  -H "Content-Type: application/json" \
  -d '{
    "tag": "1088 Peaceful Dr Corona CA show req",
    "contactInfo": {
      "contactName": "John Doe",
      "contactPhone": "555-1234"
    }
  }'

Deployment Checklist

Prerequisites

  • HubSpot custom objects exist (Offers, Showings, Views)
  • Better Acquisitions Supabase accessible
  • SalesMessage OAuth token valid
  • HubSpot PAT valid

Installation

cd /home/opsadmin/.openclaw/workspace
 
# Install dependencies (if needed)
npm install @supabase/supabase-js
 
# Make scripts executable
chmod +x scripts/tag-automation-handler.js
chmod +x scripts/hubspot-custom-object-manager.js
chmod +x scripts/better-acq-offer-creator.js
chmod +x scripts/test-tag-automation.js

Restart API Server

# Kill existing server
pkill -f lovable-api-server
 
# Restart with new endpoints
nohup node scripts/lovable-api-server.js > logs/lovable-api-server.log 2>&1 &

Verify Endpoints

curl http://localhost:18799/health

Integration Points

SalesMessage API

  • Add tag: POST /pub/v2.2/conversations/{id}/tags
  • Remove tag: DELETE /pub/v2.2/conversations/{id}/tags/{tag}
  • OAuth: /workspace/data/salesmessage-oauth.json

HubSpot API

  • Custom Objects: POST /crm/v3/objects/{objectType}
  • Search: POST /crm/v3/objects/{objectType}/search
  • Associations: PUT /crm/v4/objects/{fromType}/{fromId}/associations/{toType}/{toId}
  • PAT: /workspace/data/hubspot-pat.txt

Better Acquisitions Supabase

  • Project: pxzxcfjgpteitwktkkiz
  • Table: acquisition_deals
  • Key: BETTER_ACQ_SUPABASE_KEY (in .env)

Known Limitations

⏳ Calendar Event Creation

Currently returns needsCalendarEvent: true but doesn’t create event.

TODO: Integrate with calendar API (Google Calendar or HubSpot Tasks)

⏳ 24h Follow-up Tasks

Currently returns needsFollowUp: true but doesn’t create task.

TODO: Integrate with HubSpot Tasks API

⏳ Deal Stage Updates

Offer submission doesn’t update deal stage automatically.

TODO: Map pipeline stages and update via HubSpot API

Duplicate Prevention

System checks for existing objects before creating, but race conditions may occur if:

  • Multiple tags added simultaneously
  • External systems also creating objects

Mitigation: Uses unique combinations (dealId + contactId) for searches


Monitoring & Logs

Log Files

  • /workspace/logs/lovable-api-server.log - API endpoint logs
  • /workspace/logs/tag-automation-test-results.json - Test results

Success Indicators

  • ✅ Property view tracked
  • ✅ Showing request created
  • ✅ Showing confirmed (with calendar reminder)
  • ✅ Offer created in HubSpot + Better Acquisitions

Failure Scenarios

  • ❌ No deal found for address
  • ❌ HubSpot API error
  • ❌ Supabase write error
  • ❌ Invalid tag format

Support

For issues:

  1. Check logs: tail -f logs/lovable-api-server.log
  2. Verify HubSpot PAT: cat data/hubspot-pat.txt
  3. Check SalesMessage OAuth: cat data/salesmessage-oauth.json
  4. Test individual components:
    node scripts/hubspot-custom-object-manager.js
    node scripts/better-acq-offer-creator.js

Contact: Atlas agent (this workspace) or Aurora (Chief AI Operating Intelligence)


Last updated: 2026-02-26 by tag-automation subagent