Queries HubSpot for unprocessed tickets in the Wavelink Sales pipeline created today.
Step Functions Triggered every 5 min by EventBridge → Step Functions
ai_status not setPOST /crm/v3/objects/tickets/search
None
Enriches ticket with contact and company data. Resolves "end user" companies to their reseller.
Step Functions Runs in parallel for each ticket
GET /crm/v3/objects/tickets/{id}
GET /crm/v4/.../associations/contacts|companies
PUT /crm/v4/.../associations/... (if resolved)
None
Uses AWS Bedrock (Claude 3.5 Sonnet) to identify end customer mentioned in ticket subject/content, then searches HubSpot for that company.
Step Functions After enrich
bedrock:InvokeModel (Claude 3.5 Sonnet, temp=0)
POST /crm/v3/objects/companies/search
PUT /crm/v4/.../associations/...
EndCustomerExtracted, EndCustomerFound, EndCustomerNotFound, EndCustomerSkipped
Sends sanitized ticket data to Subrosa AI webhook for processing. Handles skip conditions (no company, Fortinet).
Step Functions After extract end customer
| Field | Source |
|---|---|
Emails | Primary contact email |
Ticket subject | Sanitized subject |
Ticket content | Sanitized body |
Ticket ID | Numeric ticket ID |
Company ID | Reseller company_id property |
End Customer ID | End customer company_id (or "") |
End Customer Name | End customer name (or "") |
WebhookSuccess, WebhookSkipped, WebhookFailed
Updates ticket with processing status and adds a conversation note documenting the action taken.
Step Functions Final step in pipeline
ai_status = skip messageai_status = skip messageai_status (Subrosa AI sets it)PATCH /crm/v3/objects/tickets/{id}
POST /conversations/v3/.../messages (or Engagements v1 fallback)
None
Scheduled Lambda that creates HubSpot quotes/deals from AI responses and posts formatted content to ticket conversations.
EventBridge Every 1 minute
ai_status (FULL, PARTIAL, NONE, etc.)ai_items_json present: create Deal (AI Generated pipeline) + Quote + Line Itemsai_reply_draft as HTML paragraphsai_items_json as styled HTML table with pricingai_status: e.g., "FULL - Applied to conversation + quote"| Column | Source Field | Calculation |
|---|---|---|
| Std Buy Price | base_price_aud | Direct |
| Discount Code | price_level | Direct (e.g., "4 Expert") |
| Discount | base_price_aud - list_price | |
| Your Price | list_price | Fallback to rate |
| Line Total | qty × list_price |
Pipeline: AI Generated (1276261847), Stage: Quote Created, Expiry: +30 days, Sender: Sales @ Wavelink, Template: Basic (443041226216)
AIRepliesApplied, QuotesCreated, QuoteValue
Syncs ticket category from presales pipeline tickets to associated deals' presales_activity field.
EventBridge Every 5 minutes
presales_activity with ticket categoryhs_ticket_category → Deal presales_activity (direct copy)POST /crm/v3/objects/tickets/search
GET /crm/v3/objects/tickets/{id}/associations/deals
PATCH /crm/v3/objects/deals/{id}
None
Bidirectional sync between HubSpot deals and NetSuite opportunities. Handles closedate, stage, and team members.
Webhook HubSpot deal change EventBridge Every 5 min (team poll)
| Property | Direction | Trigger |
|---|---|---|
| Close Date | HS → NS | Webhook |
| Deal Stage | HS → NS | Webhook |
| Team Members | HS ↔ NS | Webhook + Poll |
| BDM / CM | NS → HS | Batch sync |
make__last_sync_datetime < 30s agohubspot_owner_id, others → collaboratorsDealsSyncedToNS, DealsSyncedFromNS, DealSyncSkipped, DealSyncFailed, DealCloseDateSynced, DealStageSynced
| Code | Meaning | Has Quote Data |
|---|---|---|
FULL | Complete quote generated | Yes |
PARTIAL | Partial quote generated | Yes |
PARTIAL_MATCH_ITEMS_NOT_FOUND | Some items could not be matched | Yes (partial) |
NONE | No quote — informational response | No |
NONE_IS_NOT_AN_ORDER | Not an order request | No |
NONE_IS_ORDER_FOLLOWUP | Follow-up to existing order | No |
NONE_FSS_ERROR_GET_RESELLER | FSS error looking up reseller | No |
NONE_FSS_ERROR_CREATE_OPPORTUNITY | FSS error creating opportunity | No |
NON_SIMPLE_ORDER_TOO_MANY_ITEMS | Too many line items for simple order | No |
Preview | Preview / test mode | Varies |
After processing by Apply AI Replies, status gets suffix: e.g., "FULL - Applied to conversation + quote"
| HubSpot Stage | Stage ID | NS Status | NS ID |
|---|---|---|---|
| Discovery | 1539943921 | Discovery | 8 |
| Present Discovery Findings | 1565386186 | Present Discovery Findings | 9 |
| Pre Sales / Demo | 1565386187 | Pre Sales/Presentation/Demo | 10 |
| Eval / Pilot / POC | 1565386188 | Eval/Pilot/POC | 11 |
| Opportunity Qualified | 1539943922 | Opportunity Qualified | 22 |
| Prepare Proposal | 1539943923 | Prepare and Present Proposal | 17 |
| Negotiation | 1539943924 | Negotiation | 18 |
| Sale Agreed | 1539943925 | Sale Agreed/Verbal Confirm | 19 |
| Closed Won | 1539943926 | Closed Won | 13 |
| Closed Lost | 1539943927 | Closed - Lost | 16 |
| Closed Other | 1611558351 | Closed - Other | 24 |
| HubSpot Deal Field | NetSuite Opportunity Field | Direction |
|---|---|---|
netsuite_opportunity | Internal ID | Link key |
closedate | expectedCloseDate | HS → NS |
dealstage | entityStatus | HS → NS (mapped) |
amount | projectedTotal | Read only |
hubspot_owner_id | salesTeam (primary) | HS ↔ NS |
hs_all_collaborator_owner_ids | salesTeam (non-primary) | HS ↔ NS |
| (set by NS sync) | custbody_wl_transaction_bdm | NS → HS |
| (set by NS sync) | custbody_wl_transaction_cm | NS → HS |
| Value | Meaning | Action |
|---|---|---|
RESELLER / Reseller | Partner / reseller | Used as-is for webhook |
End Customer / end user | End customer | Resolved to reseller via contact associations |