Skip to content

Comments

feat: add Revenue Leak Detector agent with HubSpot CRM + Telegram + Gmail integration#5166

Open
Siddharth2624 wants to merge 5 commits intoaden-hive:mainfrom
Siddharth2624:feat/revenue-leak-detector-clean
Open

feat: add Revenue Leak Detector agent with HubSpot CRM + Telegram + Gmail integration#5166
Siddharth2624 wants to merge 5 commits intoaden-hive:mainfrom
Siddharth2624:feat/revenue-leak-detector-clean

Conversation

@Siddharth2624
Copy link
Contributor

Fixes #5153

Overview

Adds a new revenue_leak_detector agent template — an autonomous business health monitor that continuously scans a CRM pipeline, detects revenue leak patterns, sends Telegram alerts, dispatches Gmail follow-up emails to ghosted contacts, and halts automatically when severity reaches critical.


Agent Architecture

monitor ──► analyze ──► notify ──► followup

◄───────────────────────────┘
(loops while halt != true)

Node Type What it does
monitor event_loop Calls scan_pipeline() — fetches open deals from HubSpot CRM
analyze event_loop Calls detect_revenue_leaks() — classifies leaks, calculates severity
notify event_loop Calls send_revenue_alert() — prints structured report + sends Telegram alert
followup event_loop Calls send_followup_emails() — sends Gmail re-engagement emails to GHOSTED contacts

Loop exits automatically when severity = critical (halt = True).


What It Detects

Pattern Trigger Risk
GHOSTED Deal silent for 21+ days Lost deal value
STALLED Deal stuck in same stage 10–20 days Slow pipeline velocity
OVERDUE_PAYMENT Invoice unpaid past due date Cash flow leak
CHURN_RISK 3+ open support escalations Customer churn

Integrations

HubSpot CRM (real data tested ✅)

  • Fetches open deals via CRM v3 API using hs_lastmodifieddate to calculate days_inactive
  • Batch-fetches primary contact email per deal via Associations API
  • Filters out closedwon / closedlost deals automatically
  • Falls back to empty snapshot if HUBSPOT_API_KEY is not set

Note on testing: During development, because newly created HubSpot deals always have days_inactive = 0 (their hs_lastmodifieddate is today), the GHOSTED threshold was temporarily lowered to >= 0 for demo purposes. Demo deals (DEMO-S01, DEMO-S02, DEMO-S03) were also injected to showcase all 4 leak types visually. Both of these have been reverted/removed in this PR — the agent now runs on clean production logic with the 21-day threshold.

Telegram (real delivery tested ✅)

  • Sends HTML-formatted alert messages with severity emoji, leak breakdown, and action items
  • Falls back to console output when env vars not set

Gmail SMTP (configured ✅)

  • Sends re-engagement emails to every GHOSTED contact with a personalized body
  • Dry-run preview printed to console when credentials not set

Environment Variables Required

Variable Purpose
HUBSPOT_API_KEY HubSpot Private App token (scopes: crm.objects.deals.read, crm.objects.contacts.read)
TELEGRAM_BOT_TOKEN Token from @Botfather
TELEGRAM_CHAT_ID Chat/group ID where alerts are delivered
GMAIL_USER Gmail address used to send follow-up emails
GMAIL_APP_PASSWORD Gmail App Password (requires 2FA enabled on account)

All integrations are optional — the agent runs fully offline without any credentials (console output only).


Running

# Console-only (no credentials needed)
uv run hive run examples/templates/revenue_leak_detector

# With TUI
uv run hive run examples/templates/revenue_leak_detector --tui

# Full integrations
export HUBSPOT_API_KEY="..."
export TELEGRAM_BOT_TOKEN="..."
export TELEGRAM_CHAT_ID="..."
export GMAIL_USER="..."
export GMAIL_APP_PASSWORD="..."
uv run hive run examples/templates/revenue_leak_detector --tui

Working Video of agent : https://drive.google.com/file/d/1_CqNK-SVk8j7ydqF9hEk8W8TqV99AaPL/view?usp=sharing

… Gmail integration

- 4-node event_loop graph: monitor → analyze → notify → followup
- Detects GHOSTED (21+ days), STALLED (10-20 days), OVERDUE_PAYMENT, CHURN_RISK
- HubSpot CRM v3 API integration with contact email batch-fetch
- Telegram HTML-formatted alerts via Bot API
- Gmail SMTP follow-up emails to ghosted contacts
- Graceful offline fallback when credentials not set
- Halt loop fix: str(halt).lower() != 'true' to handle any LLM casing
Copy link
Collaborator

@bryanadenhq bryanadenhq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Siddharth2624, I just left some comments for you to review. Thanks for your contribution!

@@ -0,0 +1,7 @@
from .agent import goal, nodes, edges
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing agent class, default_agnet instance, and config exports. All other template export these. WIthout an agent calss, this template can't be loaded or run the same way as others.

print(" 💰 REVENUE LEAK DETECTOR — Starting Agent")
print("=" * 64)

runner = AgentRunner.load("examples/templates/revenue_leak_detector")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other templates don't use AgentRunner.load() in main.py, they all import and instantiate their own agent class in init.py per my previous comment.

print("=" * 64)

runner = AgentRunner.load("examples/templates/revenue_leak_detector")
runner._setup()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Private class, shouldn't be called directly

# Minimal @tool decorator (framework convention)
# ---------------------------------------------------------------------------

def tool(func):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be registering tools using the TOOLS dict + tool_executor() pattern.


# ---------------------------------------------------------------------------
# Shared in-process state — survives across node calls within the same run
_CURRENT_CYCLE_DATA: dict = {}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Globals are not thread-sage and not session-isolated.

## Agent Graph

```
monitor ──► analyze ──► notify
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

readme no longer up to date

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed all. Please check if anything left.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Revenue Leak Detector Agent — HubSpot CRM integration and email follow-up

2 participants