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