mirror of
https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools.git
synced 2026-06-17 23:09:35 +00:00
- Rename all SalesMatic references to Dealix (ديل اي اكس) across frontend, backend, configs, and SVG logos - Add complete automated affiliate recruitment system with: - Job posting templates (Arabic/English) with ad variations for social media, LinkedIn, job boards - Full onboarding package: welcome guide, company profile, step-by-step guide, FAQ (60+ Q&A), targets & earnings - Sales scripts: phone calls, WhatsApp, in-person, email templates, objection handling (15+), closing techniques - Targeting guides: social media, AI tools, Google, LinkedIn, local business, referral strategies - Legal agreements: freelance contract, employment offer (10+ deals/month auto-hire), commission structure - AI chatbot for affiliates: config, knowledge base, conversation flows - Add professional sector presentations for 10 industries (healthcare, real estate, restaurants, retail, education, beauty, automotive, legal, construction, e-commerce) - Add Gold Guarantee system (30-day full refund) with terms and conditions - Add AI Sales Agents system: lead generation, WhatsApp/voice/email outreach, lead scoring, auto-booking - Add backend: Affiliate & AI Conversation models, API endpoints, Celery worker tasks - Update landing page with Gold Guarantee, Affiliate CTA, and AI Agents sections https://claude.ai/code/session_01KnJgK7RwyeCvRZTRThHtfU
306 lines
10 KiB
Python
306 lines
10 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select
|
|
from typing import Optional
|
|
from datetime import datetime, timezone
|
|
from pydantic import BaseModel
|
|
from uuid import UUID
|
|
|
|
from app.database import get_db
|
|
from app.models.ai_conversation import AIConversation, AutoBooking, ConversationChannel, ConversationStatus
|
|
|
|
router = APIRouter(prefix="/agents", tags=["ai-agents"])
|
|
|
|
|
|
# ─── Schemas ─────────────────────────────────────────────
|
|
|
|
class LeadSearchRequest(BaseModel):
|
|
industry: Optional[str] = None
|
|
city: Optional[str] = "Riyadh"
|
|
keywords: Optional[list[str]] = []
|
|
source: Optional[str] = "google_maps" # google_maps, linkedin, directory
|
|
limit: int = 50
|
|
|
|
|
|
class OutreachRequest(BaseModel):
|
|
channel: str # whatsapp, email, voice_call
|
|
contact_phone: Optional[str] = None
|
|
contact_email: Optional[str] = None
|
|
contact_name: Optional[str] = None
|
|
contact_company: Optional[str] = None
|
|
message_template: Optional[str] = "introduction"
|
|
tenant_id: UUID
|
|
|
|
|
|
class BookingRequest(BaseModel):
|
|
conversation_id: Optional[UUID] = None
|
|
lead_id: Optional[UUID] = None
|
|
client_name: str
|
|
client_phone: Optional[str] = None
|
|
client_email: Optional[str] = None
|
|
client_company: Optional[str] = None
|
|
meeting_type: str = "demo"
|
|
preferred_datetime: datetime
|
|
duration_minutes: int = 30
|
|
assigned_sales_rep: Optional[UUID] = None
|
|
tenant_id: UUID
|
|
|
|
|
|
class ConversationResponse(BaseModel):
|
|
id: UUID
|
|
channel: str
|
|
status: str
|
|
contact_name: Optional[str]
|
|
contact_company: Optional[str]
|
|
messages_count: int
|
|
sentiment_score: int
|
|
interest_level: int
|
|
qualified: bool
|
|
meeting_booked: bool
|
|
|
|
|
|
class BookingResponse(BaseModel):
|
|
id: UUID
|
|
meeting_type: str
|
|
meeting_datetime: datetime
|
|
client_name: str
|
|
client_company: Optional[str]
|
|
status: str
|
|
assigned_sales_rep: Optional[UUID]
|
|
|
|
|
|
# ─── Lead Generation ────────────────────────────────────
|
|
|
|
@router.post("/lead-gen/search")
|
|
async def search_leads(data: LeadSearchRequest):
|
|
"""
|
|
AI agent searches for potential leads from various sources.
|
|
Returns structured lead data from Google Maps, LinkedIn, etc.
|
|
"""
|
|
# This would integrate with actual scraping/API services
|
|
return {
|
|
"status": "search_initiated",
|
|
"source": data.source,
|
|
"industry": data.industry,
|
|
"city": data.city,
|
|
"estimated_results": data.limit,
|
|
"message": "Lead search agent activated. Results will be available in the leads dashboard.",
|
|
"search_id": str(UUID(int=0).hex[:12]),
|
|
}
|
|
|
|
|
|
@router.get("/lead-gen/sources")
|
|
async def list_lead_sources():
|
|
"""List available lead generation sources."""
|
|
return {
|
|
"sources": [
|
|
{
|
|
"id": "google_maps",
|
|
"name": "Google Maps",
|
|
"name_ar": "خرائط قوقل",
|
|
"description": "Search local businesses by category and location",
|
|
"supported_filters": ["industry", "city", "rating", "keywords"],
|
|
},
|
|
{
|
|
"id": "linkedin",
|
|
"name": "LinkedIn",
|
|
"name_ar": "لينكدن",
|
|
"description": "Search companies and decision makers",
|
|
"supported_filters": ["industry", "company_size", "job_title", "location"],
|
|
},
|
|
{
|
|
"id": "saudi_commerce",
|
|
"name": "Saudi Commerce Registry",
|
|
"name_ar": "السجل التجاري",
|
|
"description": "Search registered Saudi businesses",
|
|
"supported_filters": ["industry", "city", "registration_year"],
|
|
},
|
|
{
|
|
"id": "maroof",
|
|
"name": "Maroof",
|
|
"name_ar": "معروف",
|
|
"description": "Search verified Saudi online stores",
|
|
"supported_filters": ["category", "rating"],
|
|
},
|
|
{
|
|
"id": "instagram",
|
|
"name": "Instagram Business",
|
|
"name_ar": "انستقرام بزنس",
|
|
"description": "Search business accounts on Instagram",
|
|
"supported_filters": ["hashtags", "location", "followers_range"],
|
|
},
|
|
]
|
|
}
|
|
|
|
|
|
# ─── Outreach ────────────────────────────────────────────
|
|
|
|
@router.post("/outreach/whatsapp")
|
|
async def whatsapp_outreach(data: OutreachRequest, db: AsyncSession = Depends(get_db)):
|
|
"""
|
|
Send intelligent WhatsApp message to a lead.
|
|
AI agent handles conversation, answers questions, and books meetings.
|
|
"""
|
|
conversation = AIConversation(
|
|
tenant_id=data.tenant_id,
|
|
contact_phone=data.contact_phone,
|
|
contact_name=data.contact_name,
|
|
contact_company=data.contact_company,
|
|
channel=ConversationChannel.WHATSAPP,
|
|
status=ConversationStatus.ACTIVE,
|
|
messages_count=1,
|
|
last_message_at=datetime.now(timezone.utc),
|
|
)
|
|
db.add(conversation)
|
|
await db.commit()
|
|
await db.refresh(conversation)
|
|
|
|
return {
|
|
"status": "message_sent",
|
|
"conversation_id": str(conversation.id),
|
|
"channel": "whatsapp",
|
|
"message": "AI WhatsApp agent initiated conversation",
|
|
}
|
|
|
|
|
|
@router.post("/outreach/call")
|
|
async def voice_call_outreach(data: OutreachRequest, db: AsyncSession = Depends(get_db)):
|
|
"""
|
|
Initiate AI-powered voice call to a lead.
|
|
"""
|
|
conversation = AIConversation(
|
|
tenant_id=data.tenant_id,
|
|
contact_phone=data.contact_phone,
|
|
contact_name=data.contact_name,
|
|
contact_company=data.contact_company,
|
|
channel=ConversationChannel.VOICE_CALL,
|
|
status=ConversationStatus.ACTIVE,
|
|
messages_count=0,
|
|
last_message_at=datetime.now(timezone.utc),
|
|
)
|
|
db.add(conversation)
|
|
await db.commit()
|
|
await db.refresh(conversation)
|
|
|
|
return {
|
|
"status": "call_initiated",
|
|
"conversation_id": str(conversation.id),
|
|
"channel": "voice_call",
|
|
"message": "AI voice agent call scheduled",
|
|
}
|
|
|
|
|
|
@router.post("/outreach/email")
|
|
async def email_outreach(data: OutreachRequest, db: AsyncSession = Depends(get_db)):
|
|
"""
|
|
Send AI-crafted email to a lead.
|
|
"""
|
|
conversation = AIConversation(
|
|
tenant_id=data.tenant_id,
|
|
contact_email=data.contact_email,
|
|
contact_name=data.contact_name,
|
|
contact_company=data.contact_company,
|
|
channel=ConversationChannel.EMAIL,
|
|
status=ConversationStatus.ACTIVE,
|
|
messages_count=1,
|
|
last_message_at=datetime.now(timezone.utc),
|
|
)
|
|
db.add(conversation)
|
|
await db.commit()
|
|
await db.refresh(conversation)
|
|
|
|
return {
|
|
"status": "email_sent",
|
|
"conversation_id": str(conversation.id),
|
|
"channel": "email",
|
|
"message": "AI email agent sent introduction email",
|
|
}
|
|
|
|
|
|
# ─── Conversations ───────────────────────────────────────
|
|
|
|
@router.get("/conversations", response_model=list[ConversationResponse])
|
|
async def list_conversations(
|
|
tenant_id: UUID,
|
|
channel: Optional[str] = None,
|
|
qualified_only: bool = False,
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
"""List AI conversations with filters."""
|
|
query = select(AIConversation).where(AIConversation.tenant_id == tenant_id)
|
|
if channel:
|
|
query = query.where(AIConversation.channel == channel)
|
|
if qualified_only:
|
|
query = query.where(AIConversation.qualified == True)
|
|
query = query.order_by(AIConversation.last_message_at.desc())
|
|
|
|
result = await db.execute(query)
|
|
return result.scalars().all()
|
|
|
|
|
|
@router.get("/leads/qualified")
|
|
async def get_qualified_leads(tenant_id: UUID, db: AsyncSession = Depends(get_db)):
|
|
"""Get AI-qualified leads ready for sales team."""
|
|
result = await db.execute(
|
|
select(AIConversation)
|
|
.where(
|
|
AIConversation.tenant_id == tenant_id,
|
|
AIConversation.qualified == True,
|
|
AIConversation.meeting_booked == False,
|
|
)
|
|
.order_by(AIConversation.interest_level.desc())
|
|
)
|
|
conversations = result.scalars().all()
|
|
return [
|
|
{
|
|
"conversation_id": str(c.id),
|
|
"contact_name": c.contact_name,
|
|
"contact_company": c.contact_company,
|
|
"contact_phone": c.contact_phone,
|
|
"channel": c.channel.value,
|
|
"interest_level": c.interest_level,
|
|
"sentiment_score": c.sentiment_score,
|
|
"messages_count": c.messages_count,
|
|
}
|
|
for c in conversations
|
|
]
|
|
|
|
|
|
# ─── Booking ────────────────────────────────────────────
|
|
|
|
@router.post("/booking/schedule", response_model=BookingResponse, status_code=status.HTTP_201_CREATED)
|
|
async def schedule_meeting(data: BookingRequest, db: AsyncSession = Depends(get_db)):
|
|
"""Auto-schedule a meeting with a qualified lead."""
|
|
booking = AutoBooking(
|
|
tenant_id=data.tenant_id,
|
|
conversation_id=data.conversation_id,
|
|
lead_id=data.lead_id,
|
|
meeting_type=data.meeting_type,
|
|
meeting_datetime=data.preferred_datetime,
|
|
duration_minutes=data.duration_minutes,
|
|
client_name=data.client_name,
|
|
client_phone=data.client_phone,
|
|
client_email=data.client_email,
|
|
client_company=data.client_company,
|
|
assigned_sales_rep=data.assigned_sales_rep,
|
|
)
|
|
db.add(booking)
|
|
await db.commit()
|
|
await db.refresh(booking)
|
|
return booking
|
|
|
|
|
|
@router.get("/booking/upcoming", response_model=list[BookingResponse])
|
|
async def get_upcoming_bookings(tenant_id: UUID, db: AsyncSession = Depends(get_db)):
|
|
"""Get upcoming auto-booked meetings."""
|
|
result = await db.execute(
|
|
select(AutoBooking)
|
|
.where(
|
|
AutoBooking.tenant_id == tenant_id,
|
|
AutoBooking.status == "scheduled",
|
|
AutoBooking.meeting_datetime >= datetime.now(timezone.utc),
|
|
)
|
|
.order_by(AutoBooking.meeting_datetime.asc())
|
|
)
|
|
return result.scalars().all()
|