Skip to main content

Knowledge > Processes > Chat Message Flow

Chat Message Flow

What happens from the moment a visitor types a message in the chatbot widget to the moment they see the response. The chatbot serves three tiers of churches: basic (PewSearch auto-provision), Pro Website ($19.95/mo), and full CWA plans (Starter/Pro/Suite). Each tier gets different capabilities.


1. User Types a Message​

  1. The visitor types into the chatbot widget (embedded on a church website, hosted chat page, or care hub).
  2. The widget sends a POST request to /api/chatbot/stream with:
    • message — the user's text (max 2,000 characters)
    • churchId — which church this chatbot belongs to
    • sessionId — conversation session identifier
    • history — array of previous messages in this session
    • agentType — optional care persona (e.g., "grief", "youth", "anxiety")
    • lensOverride / lensNameOverride — optional demo-mode theological lens

2. Rate Limiting​

  1. Extract the client IP address.
  2. Check against a rate limiter: 30 requests per 60 seconds per IP.
  3. If over limit, return 429 "Too Many Requests."

3. Input Validation​

  1. Verify message, churchId, and sessionId are all present. Return 400 if missing.
  2. Verify at least one LLM provider is configured (ANTHROPIC_API_KEY or OPENAI_API_KEY). Return 503 if not.
  3. Verify message length is under 2,000 characters. Return 400 if too long.

4. Church Verification​

  1. Query premium_churches where church_id = churchId, chatbot_enabled = true, and status is "active" or "preview."
  2. If no matching record, return 404 "Church not found or chatbot not enabled."
    • This runs BEFORE any expensive operations — prevents abuse where attackers send arbitrary churchIds.
  3. Log suspicious origins (requests from domains that are not churchwiseai.com, the church's custom domain, or localhost).

5. Moderation Check​

  1. Call checkRestriction(churchId, sessionId) to see if this session is currently restricted.
  2. If restricted (e.g., prior abuse flagged), return the restriction message with type and expiration.
    • No LLM call is made — saves cost on known-bad sessions.

6. FAQ Short-Circuit (Zero LLM Cost)​

  1. Call matchFAQ(message, churchId, agentType) to check for canned responses in the canned_responses table.

  2. If an exact match is found (with exact_response = true): a. Track usage as "canned" source (zero tokens, zero cost). b. Increment conversation message counts (fire-and-forget). c. Return the canned answer immediately. No LLM call at all.

  3. If a fuzzy match is found (close but not exact): a. Save the match as "preferred context" — it will be injected into the LLM prompt later so the LLM can use it as a starting point.

7. Load Church Data​

  1. Query the churches table for basic info: name, denomination, address, phone, website, working_hours.
  2. Query premium_churches for premium config: plan, custom_name, custom_hours, custom_staff, custom_ministries, what_to_expect, cap_info.
  3. If chatbot is not enabled on the premium record, return 403.

8. Check Usage Limits​

  1. Normalize the plan tier (maps legacy plan names to current ones).
  2. Call checkUsageLimit(churchId, plan) — each tier has a monthly message cap.
  3. If the church has exceeded their limit, return a friendly message with the limit and usage count.

9. Load Supporting Data (in parallel where possible)​

  1. Load voice agent config from church_voice_agents for pastor name, Cal.com booking link, callback settings, sermon topic, giving URL.
  2. Load tool config from organization_settings — which tools are enabled for this church's chatbot.
  3. Detect chatbot source:
    • pewsearch_auto_provision --> basic chatbot (simple Q&A, minimal tools)
    • pro_website plan --> Pro Website chatbot (church facts + prayer request tool)
    • Anything else --> full CWA chatbot (all 33 tools, agentic personality)

10. Resolve Agent Type and Config​

  1. If an agentType was provided (e.g., "grief", "youth"): a. Map the care persona to its parent marketing agent type. b. Resolve the effective agent config (merging admin-saved overrides with plan defaults). c. Check if that agent type is enabled. If disabled, return a message suggesting the care hub.

11. Resolve Theological Lens​

  1. Priority for choosing the theological tradition:

    1. Client-side override (demo mode) — must be a valid lens ID (1-17)
    2. Church DB setting in church_theological_lenses table
    3. Auto-detect from denomination string via DENOMINATION_TO_LENS map
    4. Default: lens 10 (Christocentric)
  2. Fetch doctrinal rules from theological_contradictions table for the resolved lens:

    • "This church's position on baptism: believer's baptism only"
    • "MUST NEVER mention: infant baptism, christening"
    • Ensures the chatbot never contradicts the church's theology
  3. Fetch church-specific doctrinal overrides from organization_settings.doctrinal_overrides:

    • Example: "We practice both infant dedication AND believer's baptism"
  4. Fetch lens vocabulary from lens_knowledge — preferred terms, avoided terms, and doctrine positions.

12. RAG Retrieval (Theological + Church Knowledge)​

  1. Generate an embedding vector from the user's message (via OpenAI text-embedding-3-small).

  2. Run two parallel semantic searches: a. Theological RAG — search unified_rag_content filtered by the church's lens ID, return top 8 matches. Provides theologically grounded context. b. Church knowledge base — search church_knowledge_base for this specific church. Returns church-specific uploaded documents and FAQs.

  3. Format both result sets into context blocks for prompt injection.

13. Build Church Facts Block​

  1. Assemble a structured facts block from church + premium data:
    • Church name, address, denomination, phone, website
    • Hours (custom hours from premium record, or working_hours from churches table)
    • Staff (custom_staff from premium)
    • Ministries (custom_ministries from premium)
    • What to expect (dress code, parking, children, first visit, music style, service length)

14. Load Product Knowledge​

  1. Query product_knowledge table for all active entries, ordered by priority descending.
  2. Format as Q&A pairs — used when visitors ask about PewSearch, ChurchWiseAI, billing, or how things work.

15. Branch by Chatbot Tier​

The flow now diverges based on the chatbot tier detected in step 25.

15a. Basic Chatbot (PewSearch auto-provision)​

  1. Build a concise system prompt: "You are the AI assistant for [church name]. Answer questions using ONLY the information below. Keep answers to 1-2 sentences."
  2. Only ONE tool available: submit_prayer_request.
  3. Build messages from history (last 10 messages) + current message.
  4. Call LLM (Anthropic Claude Haiku 4.5 primary, OpenAI gpt-4o-mini fallback).
  5. If the LLM wants to call submit_prayer_request: a. Execute the tool (writes to voice_prayer_requests table). b. Send a follow-up LLM call with the tool result to get the final text response. c. After confirming the prayer request, append: "This is just one of 33 AI-powered ministry tools available with ChurchWiseAI."
  6. Run crisis safety net (see step 50).
  7. Return the response.

15b. Pro Website Chatbot ($19.95/mo)​

  1. Build a system prompt: friendly church receptionist personality, church facts, theological context, and scope enforcement.
  2. Only ONE tool available: submit_prayer_request.
  3. For anything beyond basic church info (scheduling, care, detailed theology, giving, etc.), warmly suggest contacting the church or mention ChurchWiseAI.
  4. Tool loop: up to 2 rounds of tool calling.
  5. Run crisis safety net (see step 50).
  6. Return the response with an upgradeUrl pointing to churchwiseai.com/pricing.

15c. Full CWA Chatbot (Starter/Pro/Suite plans)​

This is the agentic chatbot with up to 33 tools.

  1. Build a comprehensive system prompt with:

    • Mission: HEAR, EMPATHIZE, CONNECT, INVITE
    • Conversation style: warm, personal, max 2 paragraphs, one CTA per response
    • Empathetic hearing examples for common scenarios
    • Contact capture guidance (never ask cold, earn it through conversation)
    • Prayer request handling (respond with care, offer to pray, maintain confidentiality)
    • Sensitive topic redirection (LGBTQ+, politics, divisive doctrine --> pastoral staff)
    • Pastoral connect (Cal.com booking or callback request)
    • Safety escalation protocol (4 levels: inappropriate --> abuse --> threats --> self-harm)
    • Scope enforcement (not a general-purpose AI -- only church topics)
    • Giving behavior (natural, never guilt-inducing, max once per conversation)
    • Theological contradiction guardrails (doctrinal rules + lens vocabulary)
    • Critical local resources (church-specific crisis resources)
  2. Build agent specialization layer — if an agentType persona is active, append persona-specific prompt with domain rulesets and filtered tool guidance.

  3. Prepare tools: a. Filter tools based on agent type and enabled tools config. b. Convert OpenAI tool definitions to LLM-provider-agnostic format.

  4. Determine escalation — certain message patterns trigger use of a more capable model (Sonnet instead of Haiku).

  5. Build messages array from history (last 20 messages) + current message.

16. LLM Call with Tool Loop (Full CWA Chatbot)​

  1. Enter the tool loop (max 3 rounds):

    a. Call the LLM with system prompt, messages, and tool definitions.

    b. If the LLM returns tool calls:

    • Execute each tool (writes to DB, sends notifications, looks up data).
    • Log each tool invocation to tool_invocations table (fire-and-forget).
    • Append tool results as structured messages.
    • Loop back to step 49a for the next round.

    c. If the LLM returns text (no more tool calls):

    • This is the final response. Exit the loop.

    d. If the LLM returns empty text (edge case):

    • Retry with clean messages (no tool artifacts).
    • If still empty, escalate to Sonnet model.
    • If still empty, use hardcoded fallback:
      • Crisis message? --> provide 988, 741741, 911 resources
      • Normal message? --> "Could you say a bit more so I can help?"

17. Crisis Safety Net (All Tiers)​

  1. After the LLM response is generated, run a regex-based crisis safety net:

    • Match the user's message against a comprehensive set of crisis patterns (suicide, self-harm, domestic violence, coded language like "kms", "unalive", religious euphemisms like "going home to the Lord").
    • If the message matches AND the LLM response is missing any of: 988, 741741/686868, or 911:
      • Append a standardized crisis resources block to the response.
      • Log a warning that the safety net had to intervene.
    • This is NON-NEGOTIABLE — the safety net runs regardless of what the LLM generated.
  2. For the full CWA chatbot, also check if the LLM failed to call flag_safety_concern:

    • If the message matches safety patterns but the tool was not invoked:
      • Auto-invoke flag_safety_concern with level "urgent."
      • Log the auto-flag as a system safety net action.

18. Response Return​

  1. Track usage (input tokens, output tokens, model used, response source).
  2. Increment conversation message counts (fire-and-forget).
  3. Log the response to response_reviews for admin review (fire-and-forget, Pro Website and full chatbot only).
  4. Run moderation logging if crisis was detected (log violation, auto-escalate).
  5. Return JSON response:
    • response — the text to display to the visitor
    • source — "canned", "basic_chatbot", "pro_website", or the agent type
    • upgradeUrl — (Pro Website only) link to churchwiseai.com/pricing
    • restricted / limitReached — if applicable

Available Tools (Full CWA Chatbot — 33 tools)​

ToolWhat It Does
submit_prayer_requestSaves prayer request to voice_prayer_requests
capture_visitor_contactSaves visitor info to voice_visitor_contacts
request_callbackCreates callback request in voice_callback_requests
book_appointmentCal.com booking link generation
get_church_directionsReturns address + Google Maps link
get_first_visit_infoPersonalized first-visit guidance
get_sermon_infoCurrent sermon topic, series, theme verse
get_announcementsWeekly announcements
lookup_bible_verseBible verse lookup via API
send_connection_card_linkChurch connection card info
find_small_groupSmall group/Bible study matching
signup_for_volunteer_roleVolunteer sign-up capture
request_pastoral_visitHospital/home visit request
report_care_needCommunity care need reporting
start_visitor_followupNew visitor follow-up enrollment
conversation_summaryEnd-of-conversation summary capture
draft_follow_up_messageAI-drafted follow-up for staff review
subscribe_to_updatesNewsletter/update subscription
send_message_to_staffMessage to specific staff member
get_giving_historyGiving statement info
submit_benevolence_requestFinancial assistance request
register_child_checkinKids pre-registration
get_kids_infoChildren's/youth program info
schedule_counselingPastoral counseling scheduling
daily_devotionalDevotional thought / encouragement
facility_bookingRoom/facility reservation
find_past_sermonSermon archive search
get_worship_playlistWorship music info
send_giving_linkGiving URL delivery
register_for_eventEvent registration
flag_safety_concernSafety concern escalation
grief_support_resourcesGrief/crisis resource delivery
lookup_local_resourcesLocal community resource lookup