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
- The visitor types into the chatbot widget (embedded on a church website, hosted chat page, or care hub).
- The widget sends a POST request to
/api/chatbot/streamwith:message— the user's text (max 2,000 characters)churchId— which church this chatbot belongs tosessionId— conversation session identifierhistory— array of previous messages in this sessionagentType— optional care persona (e.g., "grief", "youth", "anxiety")lensOverride/lensNameOverride— optional demo-mode theological lens
2. Rate Limiting
- Extract the client IP address.
- Check against a rate limiter: 30 requests per 60 seconds per IP.
- If over limit, return 429 "Too Many Requests."
3. Input Validation
- Verify
message,churchId, andsessionIdare all present. Return 400 if missing. - Verify at least one LLM provider is configured (ANTHROPIC_API_KEY or OPENAI_API_KEY). Return 503 if not.
- Verify message length is under 2,000 characters. Return 400 if too long.
4. Church Verification
- Query
premium_churcheswherechurch_id= churchId,chatbot_enabled= true, and status is "active" or "preview." - 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.
- Log suspicious origins (requests from domains that are not churchwiseai.com, the church's custom domain, or localhost).
5. Moderation Check
- Call
checkRestriction(churchId, sessionId)to see if this session is currently restricted. - 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)
-
Call
matchFAQ(message, churchId, agentType)to check for canned responses in thecanned_responsestable. -
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. -
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
- Query the
churchestable for basic info: name, denomination, address, phone, website, working_hours. - Query
premium_churchesfor premium config: plan, custom_name, custom_hours, custom_staff, custom_ministries, what_to_expect, cap_info. - If chatbot is not enabled on the premium record, return 403.
8. Check Usage Limits
- Normalize the plan tier (maps legacy plan names to current ones).
- Call
checkUsageLimit(churchId, plan)— each tier has a monthly message cap. - 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)
- Load voice agent config from
church_voice_agentsfor pastor name, Cal.com booking link, callback settings, sermon topic, giving URL. - Load tool config from
organization_settings— which tools are enabled for this church's chatbot. - Detect chatbot source:
pewsearch_auto_provision--> basic chatbot (simple Q&A, minimal tools)pro_websiteplan --> Pro Website chatbot (church facts + prayer request tool)- Anything else --> full CWA chatbot (all 33 tools, agentic personality)
10. Resolve Agent Type and Config
- If an
agentTypewas 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
-
Priority for choosing the theological tradition:
- Client-side override (demo mode) — must be a valid lens ID (1-17)
- Church DB setting in
church_theological_lensestable - Auto-detect from denomination string via
DENOMINATION_TO_LENSmap - Default: lens 10 (Christocentric)
-
Fetch doctrinal rules from
theological_contradictionstable 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
-
Fetch church-specific doctrinal overrides from
organization_settings.doctrinal_overrides:- Example: "We practice both infant dedication AND believer's baptism"
-
Fetch lens vocabulary from
lens_knowledge— preferred terms, avoided terms, and doctrine positions.
12. RAG Retrieval (Theological + Church Knowledge)
-
Generate an embedding vector from the user's message (via OpenAI text-embedding-3-small).
-
Run two parallel semantic searches: a. Theological RAG — search
unified_rag_contentfiltered by the church's lens ID, return top 8 matches. Provides theologically grounded context. b. Church knowledge base — searchchurch_knowledge_basefor this specific church. Returns church-specific uploaded documents and FAQs. -
Format both result sets into context blocks for prompt injection.
13. Build Church Facts Block
- 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
- Query
product_knowledgetable for all active entries, ordered by priority descending. - 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)
- 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."
- Only ONE tool available:
submit_prayer_request. - Build messages from history (last 10 messages) + current message.
- Call LLM (Anthropic Claude Haiku 4.5 primary, OpenAI gpt-4o-mini fallback).
- If the LLM wants to call
submit_prayer_request: a. Execute the tool (writes tovoice_prayer_requeststable). 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." - Run crisis safety net (see step 50).
- Return the response.
15b. Pro Website Chatbot ($19.95/mo)
- Build a system prompt: friendly church receptionist personality, church facts, theological context, and scope enforcement.
- Only ONE tool available:
submit_prayer_request. - For anything beyond basic church info (scheduling, care, detailed theology, giving, etc.), warmly suggest contacting the church or mention ChurchWiseAI.
- Tool loop: up to 2 rounds of tool calling.
- Run crisis safety net (see step 50).
- Return the response with an
upgradeUrlpointing to churchwiseai.com/pricing.
15c. Full CWA Chatbot (Starter/Pro/Suite plans)
This is the agentic chatbot with up to 33 tools.
-
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)
-
Build agent specialization layer — if an agentType persona is active, append persona-specific prompt with domain rulesets and filtered tool guidance.
-
Prepare tools: a. Filter tools based on agent type and enabled tools config. b. Convert OpenAI tool definitions to LLM-provider-agnostic format.
-
Determine escalation — certain message patterns trigger use of a more capable model (Sonnet instead of Haiku).
-
Build messages array from history (last 20 messages) + current message.
16. LLM Call with Tool Loop (Full CWA Chatbot)
-
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_invocationstable (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)
-
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.
-
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_concernwith level "urgent." - Log the auto-flag as a system safety net action.
- Auto-invoke
- If the message matches safety patterns but the tool was not invoked:
18. Response Return
- Track usage (input tokens, output tokens, model used, response source).
- Increment conversation message counts (fire-and-forget).
- Log the response to
response_reviewsfor admin review (fire-and-forget, Pro Website and full chatbot only). - Run moderation logging if crisis was detected (log violation, auto-escalate).
- Return JSON response:
response— the text to display to the visitorsource— "canned", "basic_chatbot", "pro_website", or the agent typeupgradeUrl— (Pro Website only) link to churchwiseai.com/pricingrestricted/limitReached— if applicable
Available Tools (Full CWA Chatbot — 33 tools)
| Tool | What It Does |
|---|---|
| submit_prayer_request | Saves prayer request to voice_prayer_requests |
| capture_visitor_contact | Saves visitor info to voice_visitor_contacts |
| request_callback | Creates callback request in voice_callback_requests |
| book_appointment | Cal.com booking link generation |
| get_church_directions | Returns address + Google Maps link |
| get_first_visit_info | Personalized first-visit guidance |
| get_sermon_info | Current sermon topic, series, theme verse |
| get_announcements | Weekly announcements |
| lookup_bible_verse | Bible verse lookup via API |
| send_connection_card_link | Church connection card info |
| find_small_group | Small group/Bible study matching |
| signup_for_volunteer_role | Volunteer sign-up capture |
| request_pastoral_visit | Hospital/home visit request |
| report_care_need | Community care need reporting |
| start_visitor_followup | New visitor follow-up enrollment |
| conversation_summary | End-of-conversation summary capture |
| draft_follow_up_message | AI-drafted follow-up for staff review |
| subscribe_to_updates | Newsletter/update subscription |
| send_message_to_staff | Message to specific staff member |
| get_giving_history | Giving statement info |
| submit_benevolence_request | Financial assistance request |
| register_child_checkin | Kids pre-registration |
| get_kids_info | Children's/youth program info |
| schedule_counseling | Pastoral counseling scheduling |
| daily_devotional | Devotional thought / encouragement |
| facility_booking | Room/facility reservation |
| find_past_sermon | Sermon archive search |
| get_worship_playlist | Worship music info |
| send_giving_link | Giving URL delivery |
| register_for_event | Event registration |
| flag_safety_concern | Safety concern escalation |
| grief_support_resources | Grief/crisis resource delivery |
| lookup_local_resources | Local community resource lookup |