Skip to main content
followup_tracker.py
"""
Gmail Follow-Up Tracker
=======================
Finds sent emails that never received a reply and drafts follow-ups.

Key concepts:
- Multi-step reasoning: agent must compare sender vs user email per thread
- add_datetime_to_context: agent calculates days_waiting from message dates
- output_schema: structured report of pending follow-ups


Setup:
1. Create OAuth credentials at https://console.cloud.google.com (enable Gmail API)
2. Export GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_PROJECT_ID env vars
3. pip install openai google-api-python-client google-auth-httplib2 google-auth-oauthlib
4. First run opens browser for OAuth consent, saves token.json for reuse
"""

from typing import List

from agno.agent import Agent
from agno.models.openai import OpenAIResponses
from agno.tools.google.gmail import GmailTools
from pydantic import BaseModel, Field

# ---------------------------------------------------------------------------
# Output Schema
# ---------------------------------------------------------------------------


class PendingFollowUp(BaseModel):
    thread_id: str = Field(..., description="Gmail thread ID")
    subject: str = Field(..., description="Original email subject")
    recipient: str = Field(..., description="Who the email was sent to")
    sent_date: str = Field(..., description="When the original email was sent")
    days_waiting: int = Field(..., description="Days since the email was sent")
    draft_created: bool = Field(
        default=False, description="Whether a follow-up draft was created"
    )


class FollowUpReport(BaseModel):
    total_checked: int = Field(..., description="Number of sent threads checked")
    needs_followup: List[PendingFollowUp] = Field(
        default_factory=list, description="Threads that need follow-up"
    )
    summary: str = Field(..., description="Brief summary of findings")


# ---------------------------------------------------------------------------
# Create Agent
# ---------------------------------------------------------------------------

agent = Agent(
    name="Follow-Up Tracker",
    model=OpenAIResponses(id="gpt-5.5"),
    tools=[GmailTools()],
    instructions=[
        "Use search_threads with 'from:me' to find sent threads, then check if the last message is from you.",
        "A thread needs follow-up if the LAST message is FROM the user (no reply received).",
        "Compare the date of the last message against today to calculate days_waiting.",
        "Keep follow-up drafts short: reference the original subject and ask if they had a chance to review.",
        "Report all findings in the output schema.",
    ],
    output_schema=FollowUpReport,
    add_datetime_to_context=True,
    markdown=True,
)

# ---------------------------------------------------------------------------
# Run Demo
# ---------------------------------------------------------------------------

if __name__ == "__main__":
    agent.print_response(
        "Check my sent emails from the last week and identify any that need a follow-up. "
        "Draft follow-ups for emails waiting more than 3 days.",
        stream=True,
    )

    # Check follow-ups for a specific recipient
    # agent.print_response(
    #     "Check if I have any unanswered emails to john@example.com from the past 2 weeks",
    #     stream=True,
    # )

Run the Example

1

Set up your virtual environment

uv venv --python 3.12
source .venv/bin/activate
uv venv --python 3.12
.venv\Scripts\activate
2

Install dependencies

uv pip install -U agno google-api-python-client google-auth google-auth-httplib2 google-auth-oauthlib openai
3

Export your OpenAI API key

export OPENAI_API_KEY="your_openai_api_key_here"
$Env:OPENAI_API_KEY="your_openai_api_key_here"
4

Run the example

Save the code above as followup_tracker.py, then run:
python followup_tracker.py
Full source: cookbook/91_tools/google/gmail/followup_tracker.py