How rvs-30/yikes-slack-bot works
1. What this repo is
Yikes is a Slack memory system built as a Node.js service. It ingests Slack channel messages, stores them in PostgreSQL/Supabase, enriches them with Gemini, embeds thread history for vector search, and answers /memory queries with RAG-style retrieval.
2. Top-level runtime shape
The app is split into a main Slack-facing process and a background worker process. index.js and src/app.js boot the Bolt-based Slack app and HTTP listener, while src/workers/startAwarenessWorker.js launches the asynchronous enrichment worker. This separation is important because ingestion/response latency is kept distinct from AI processing.
3. Slack event ingress
src/listeners/events/message.js handles message events, and src/listeners/events/app-mention.js handles direct mentions. src/listeners/commands/memory.js handles the /memory slash command. These listeners form the only inbound surface from Slack and are the first architectural boundary.
4. Persistence layer
src/repositories/ and src/models/ encapsulate database access to PostgreSQL. The core stores are:
- messages: raw Slack message ingestion plus processing state
- thread_embeddings: vectorized thread summaries/content
- interaction_log: audit trail and context window for commands
- users and user_channel_memberships: identity cache and access-control data
The repo is designed around Supabase with pgvector enabled.
5. Ingestion pipeline
When a Slack message arrives, it is persisted, then marked for downstream processing. The README describes the flow as: Slack event → PostgreSQL → BullMQ/Redis queue → awareness worker. The queue boundary is implemented in src/queues/awareness.queue.js, which decouples event intake from AI enrichment.
6. Background enrichment
src/workers/awareness.worker.js is the asynchronous AI enrichment stage. It uses services in src/services/awareness.service.js, embedding.service.js, summary.service.js, search.service.js, and related modules to classify messages, extract entities, score importance, and mark threads as dirty for later embedding.
7. Embedding pipeline
src/schedulers/embedding.scheduler.js is the periodic batch job, driven by node-cron. It picks up dirty threads, rebuilds thread content through context.service.js and rag.service.js, then writes a 768-dimensional embedding to thread_embeddings. This is the persistent semantic memory layer, backed by an HNSW vector index in PostgreSQL.
8. Query and answer path
/memory requests go through membership checks first, then into hybrid retrieval. The query path uses membership.service.js to resolve which channels the user can access, search.service.js to combine vector and keyword search, and rag.service.js/context.service.js to feed retrieved context into Gemini for answer generation. Responses can be ephemeral or posted back to Slack.
9. Security boundary
The architecture is intentionally channel-gated. DMs are blocked at the listener layer, and every query is constrained by user_channel_memberships at the SQL level so inaccessible private-channel data cannot leak. Membership state is cached in PostgreSQL and refreshed from Slack on a TTL basis.
10. Cross-cutting utilities and middleware
src/middleware/logger.middleware.js provides request/event logging. src/config/database.js and src/config/environment.js centralize connection/env setup. src/utils/text.utils.js supports text normalization and content assembly. These are supporting pieces rather than core subsystems, but they keep the ingestion, worker, and query paths consistent.
11. External services that materially shape the design
The architecture depends on Slack Bolt for event/command handling, PostgreSQL on Supabase for durable storage and vector search, Redis/BullMQ for async processing, and Gemini for both classification and generation. Those choices explain why the repo is organized around event listeners, queues, schedulers, and service layers rather than a single synchronous request handler.
12. How to draw the architecture
A good diagram would show three main flows: inbound Slack events into persistence and queueing; background worker/scheduler turning stored messages into embeddings; and /memory queries reading from membership-gated PostgreSQL and Gemini-backed retrieval. The clear trust boundaries are Slack ingress, database access, background AI processing, and membership-enforced query access.
Main entry points: app.js Slack app · index.js Listeners · rag.service.js RAG · memory.js /memory
Components 23
Slack runtime
Main Bolt app and inbound Slack handlers.
- index.js · Boots the service process.
index.js - Slack app · Initializes the Bolt listener and HTTP server.
src/app.js - Listeners · Routes Slack events and commands.
src/listeners/index.js - Message event · Ingests channel messages from Slack.
src/listeners/events/message.js - Mention event · Handles direct app mentions.
src/listeners/events/app-mention.js - /memory · Handles retrieval queries from Slack.
src/listeners/commands/memory.js
AI pipeline
Background enrichment, embedding, and retrieval stages.
- Awareness queue · Decouples ingestion from AI enrichment.
src/queues/awareness.queue.js - Awareness worker · Processes queued messages for enrichment.
src/workers/awareness.worker.js - Worker boot · Starts the background worker process.
src/workers/startAwarenessWorker.js - Awareness · Classifies messages and marks threads dirty.
src/services/awareness.service.js - Summary · Builds thread summaries for memory.
src/services/summary.service.js - Embeddings · Creates vectors for thread memory.
src/services/embedding.service.js - Search · Combines keyword and vector search.
src/services/search.service.js - RAG · Assembles context and generates answers.
src/services/rag.service.js - Context · Reconstructs thread and query context.
src/services/context.service.js - Embedding job · Rebuilds dirty thread embeddings on a schedule.
src/schedulers/embedding.scheduler.js
Data layer
Persistence, models, and PostgreSQL-backed state.
- Messages · Represents Slack message records and state.
src/models/message.model.js - Message repo · Persistence operations for message storage.
src/repositories/message.repository.js - Membership · Resolves channel access for users.
src/services/membership.service.js - Save service · Stores inbound messages and processing metadata.
src/services/save.service.js
Support
Cross-cutting config, middleware, and utilities.
- Logger · Central event and request logging.
src/middleware/logger.middleware.js - Config · Environment and database configuration.
src/config/environment.js - Text utils · Normalizes and assembles text content.
src/utils/text.utils.js
Connections 25
- index.js → Slack app: boot · Starts the main Slack-facing process.
- Slack app → Listeners: register · Wires inbound Slack handlers.
- Listeners → Message event: message · Routes channel message events.
- Listeners → Mention event: mention · Routes app mentions.
- Listeners → /memory: command · Routes /memory queries.
- Slack app → Logger: log · Applies event/request logging.
- Slack app → Config: init · Loads runtime and database settings.
- Message event → Save service: persist · Stores inbound Slack messages.
- Save service → Message repo: db write · Writes message records to PostgreSQL.
- Message repo → Messages: maps · Persists the message model.
- Save service → Awareness queue: enqueue · Marks messages for async processing.
- Awareness queue → Worker boot: start · Consumes jobs in the background.
- Worker boot → Awareness worker: run · Launches the enrichment worker.
- Awareness worker → Awareness: enrich · Classifies and scores messages.
- Awareness → Summary: summarize · Builds thread summaries.
- Awareness → Embeddings: prepare · Prepares content for vectorization.
- Embedding job → Context: build · Reconstructs thread context for batching.
- Embedding job → RAG: assemble · Feeds retrieval context into memory generation.
- RAG → Search: retrieve · Performs hybrid search over stored memory.
- Search → Membership: gate · Limits retrieval to accessible channels.
- Membership → Message repo: lookup · Reads membership-aware state from the database.
- RAG → Context: context · Builds prompt context for Gemini.
- /memory → Membership: authorize · Checks user channel access before answering.
- /memory → RAG: answer · Generates the /memory response.
- Context → Text utils: normalize · Uses shared text assembly helpers.