# ssldxss/vrcnotifier architecture

> Architecture diagram of the GitHub repository ssldxss/vrcnotifier, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-10-01). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ssldxss/vrcnotifier
- Repository: https://github.com/ssldxss/vrcnotifier

## Overview

vrcnotifier monitors VRChat friends and sends event notifications through a QQ bot, with a web panel for login, configuration, friend status, and logs. The principal workflow is VRChat WebSocket events plus REST reconciliation, state-transition processing, persistence, and notification dispatch; recovery handles reconnects and authentication challenges. The README also documents avatar caching, health/status, and log history. The graph reflects sampled wiring and documented capabilities; some UI and backend subsystem internals were not sampled, so their detailed links are omitted.

Main entry points: [`src/index.js`](https://github.com/ssldxss/vrcnotifier/blob/main/src/index.js) (App Assembly), [`src/server.js`](https://github.com/ssldxss/vrcnotifier/blob/main/src/server.js) (HTTP API), [`public/ui.js`](https://github.com/ssldxss/vrcnotifier/blob/main/public/ui.js) (Web Interface), [`src/monitor.js`](https://github.com/ssldxss/vrcnotifier/blob/main/src/monitor.js) (Monitor Orchestrator)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Web Panel"]
  node_webui["Web Interface<br/>[ui.js]"]
  node_friendsui["Friend Views<br/>[friends.js]"]
  node_overviewui["Overview<br/>[overview.js]"]
  node_settingsui["Settings<br/>[settings.js]"]
  node_logui["Log Panel<br/>[logpanel.js]"]
end

subgraph group_service["Application Service"]
  node_http["HTTP API<br/>[server.js]"]
  node_bootstrap["App Assembly<br/>[index.js]"]
  node_recovery["Login Recovery<br/>[server.js]"]
  node_health["Health Monitor<br/>[health.js]"]
  node_vrcstatus["VRChat Status<br/>[vrcstatus.js]"]
end

subgraph group_monitoring["Friend Monitoring"]
  node_monitor["Monitor Orchestrator<br/>[monitor.js]"]
  node_ws["WebSocket Pipeline<br/>[pipeline.js]"]
  node_state["Friend State Machine<br/>[state.js]"]
  node_world["World Names<br/>[world.js]"]
end

subgraph group_integrations["External Integrations"]
  node_vrcapi["VRChat API Client<br/>[vrcapi.js]"]
  node_qqbot["QQ Bot Gateway<br/>[qq.js]"]
  node_commands["QQ Commands<br/>[qq-commands.js]"]
  node_notify["Notification Templates<br/>[notify.js]"]
  node_avatar["Avatar Cache<br/>[avatar.js]"]
end

subgraph group_persistence["Persistence and Logs"]
  node_db[("SQLite Store<br/>[db.js]")]
  node_crypto["Data Encryption<br/>[crypto.js]"]
  node_filelog["Segmented Logs<br/>[filelog.js]"]
  node_logstream["Live Log Stream<br/>[logstream.js]"]
end

node_operator(("Operator"))
node_vrchat{{"VRChat Services"}}

node_operator -->|"uses"| node_webui
node_webui -->|"calls API"| node_http
node_http -->|"serves panel"| node_operator
node_bootstrap -->|"starts"| node_http
node_bootstrap -->|"assembles"| node_monitor
node_bootstrap -->|"creates"| node_ws
node_bootstrap -->|"creates"| node_db
node_bootstrap -->|"creates"| node_avatar
node_bootstrap -->|"starts"| node_health
node_bootstrap -->|"creates"| node_vrcstatus
node_ws -->|"gets token"| node_vrcapi
node_ws -.->|"dispatches events"| node_monitor
node_monitor -->|"applies transitions"| node_state
node_monitor -->|"reads and writes"| node_db
node_monitor -->|"reconciles via REST"| node_vrcapi
node_vrcapi -->|"calls REST API"| node_vrchat
node_monitor -.->|"resolves names"| node_world
node_monitor -.->|"dispatches notices"| node_notify
node_notify -->|"formats messages"| node_qqbot
node_qqbot -->|"handles commands"| node_commands
node_qqbot -->|"reads binding"| node_db
node_qqbot -->|"connects gateway"| node_vrchat
node_http -->|"handles auth"| node_recovery
node_recovery -->|"re-authenticates"| node_vrcapi
node_recovery -.->|"requests reconnect"| node_ws
node_http -->|"serves cached images"| node_avatar
node_http -->|"broadcasts logs"| node_logstream
node_logstream -->|"streams log events"| node_logui
node_http -->|"serves static UI"| node_webui
node_webui -.->|"shows friends"| node_friendsui
node_webui -.->|"shows overview"| node_overviewui
node_webui -.->|"configures service"| node_settingsui
node_http -.->|"exposes health"| node_health
node_health -.->|"streams health"| node_webui
node_vrcstatus -.->|"provides status"| node_webui
node_bootstrap -->|"opens log files"| node_filelog
node_bootstrap -->|"creates stream"| node_logstream
node_db -.->|"encrypts fields"| node_crypto

click node_webui "https://github.com/ssldxss/vrcnotifier/blob/main/public/ui.js"
click node_friendsui "https://github.com/ssldxss/vrcnotifier/blob/main/public/friends.js"
click node_overviewui "https://github.com/ssldxss/vrcnotifier/blob/main/public/overview.js"
click node_settingsui "https://github.com/ssldxss/vrcnotifier/blob/main/public/settings.js"
click node_logui "https://github.com/ssldxss/vrcnotifier/blob/main/public/logpanel.js"
click node_http "https://github.com/ssldxss/vrcnotifier/blob/main/src/server.js"
click node_bootstrap "https://github.com/ssldxss/vrcnotifier/blob/main/src/index.js"
click node_recovery "https://github.com/ssldxss/vrcnotifier/blob/main/src/server.js"
click node_monitor "https://github.com/ssldxss/vrcnotifier/blob/main/src/monitor.js"
click node_ws "https://github.com/ssldxss/vrcnotifier/blob/main/src/pipeline.js"
click node_state "https://github.com/ssldxss/vrcnotifier/blob/main/src/state.js"
click node_world "https://github.com/ssldxss/vrcnotifier/blob/main/src/world.js"
click node_vrcapi "https://github.com/ssldxss/vrcnotifier/blob/main/src/vrcapi.js"
click node_qqbot "https://github.com/ssldxss/vrcnotifier/blob/main/src/qq.js"
click node_commands "https://github.com/ssldxss/vrcnotifier/blob/main/src/qq-commands.js"
click node_notify "https://github.com/ssldxss/vrcnotifier/blob/main/src/notify.js"
click node_avatar "https://github.com/ssldxss/vrcnotifier/blob/main/src/avatar.js"
click node_db "https://github.com/ssldxss/vrcnotifier/blob/main/src/db.js"
click node_crypto "https://github.com/ssldxss/vrcnotifier/blob/main/src/crypto.js"
click node_filelog "https://github.com/ssldxss/vrcnotifier/blob/main/src/filelog.js"
click node_logstream "https://github.com/ssldxss/vrcnotifier/blob/main/src/logstream.js"
click node_health "https://github.com/ssldxss/vrcnotifier/blob/main/src/health.js"
click node_vrcstatus "https://github.com/ssldxss/vrcnotifier/blob/main/src/vrcstatus.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_webui,node_friendsui,node_overviewui,node_settingsui,node_logui toneBlue
class node_http,node_bootstrap,node_recovery,node_health,node_vrcstatus toneAmber
class node_monitor,node_ws,node_state,node_world toneMint
class node_vrcapi,node_qqbot,node_commands,node_notify,node_avatar toneRose
class node_db,node_crypto,node_filelog,node_logstream,node_operator,node_vrchat toneIndigo
```

## Components

### Web Panel

- [Web Interface](https://github.com/ssldxss/vrcnotifier/blob/main/public/ui.js): `public/ui.js`
- [Friend Views](https://github.com/ssldxss/vrcnotifier/blob/main/public/friends.js): `public/friends.js`
- [Overview](https://github.com/ssldxss/vrcnotifier/blob/main/public/overview.js): `public/overview.js`
- [Settings](https://github.com/ssldxss/vrcnotifier/blob/main/public/settings.js): `public/settings.js`
- [Log Panel](https://github.com/ssldxss/vrcnotifier/blob/main/public/logpanel.js): `public/logpanel.js`

### Application Service

- [HTTP API](https://github.com/ssldxss/vrcnotifier/blob/main/src/server.js): `src/server.js`
- [App Assembly](https://github.com/ssldxss/vrcnotifier/blob/main/src/index.js): `src/index.js`
- [Login Recovery](https://github.com/ssldxss/vrcnotifier/blob/main/src/server.js): `src/server.js`
- [Health Monitor](https://github.com/ssldxss/vrcnotifier/blob/main/src/health.js): `src/health.js`
- [VRChat Status](https://github.com/ssldxss/vrcnotifier/blob/main/src/vrcstatus.js): `src/vrcstatus.js`

### Friend Monitoring

- [Monitor Orchestrator](https://github.com/ssldxss/vrcnotifier/blob/main/src/monitor.js): `src/monitor.js`
- [WebSocket Pipeline](https://github.com/ssldxss/vrcnotifier/blob/main/src/pipeline.js): `src/pipeline.js`
- [Friend State Machine](https://github.com/ssldxss/vrcnotifier/blob/main/src/state.js): `src/state.js`
- [World Names](https://github.com/ssldxss/vrcnotifier/blob/main/src/world.js): `src/world.js`

### External Integrations

- [VRChat API Client](https://github.com/ssldxss/vrcnotifier/blob/main/src/vrcapi.js): `src/vrcapi.js`
- [QQ Bot Gateway](https://github.com/ssldxss/vrcnotifier/blob/main/src/qq.js): `src/qq.js`
- [QQ Commands](https://github.com/ssldxss/vrcnotifier/blob/main/src/qq-commands.js): `src/qq-commands.js`
- [Notification Templates](https://github.com/ssldxss/vrcnotifier/blob/main/src/notify.js): `src/notify.js`
- [Avatar Cache](https://github.com/ssldxss/vrcnotifier/blob/main/src/avatar.js): `src/avatar.js`

### Persistence and Logs

- [SQLite Store](https://github.com/ssldxss/vrcnotifier/blob/main/src/db.js): `src/db.js`
- [Data Encryption](https://github.com/ssldxss/vrcnotifier/blob/main/src/crypto.js): `src/crypto.js`
- [Segmented Logs](https://github.com/ssldxss/vrcnotifier/blob/main/src/filelog.js): `src/filelog.js`
- [Live Log Stream](https://github.com/ssldxss/vrcnotifier/blob/main/src/logstream.js): `src/logstream.js`

### Other components

- **Operator**
- **VRChat Services**

## Connections

- Operator → Web Interface: uses
- Web Interface → HTTP API: calls API
- HTTP API → Operator: serves panel
- App Assembly → HTTP API: starts (evidence: `src/index.js`)
- App Assembly → Monitor Orchestrator: assembles (evidence: `src/index.js`)
- App Assembly → WebSocket Pipeline: creates (evidence: `src/index.js`)
- App Assembly → SQLite Store: creates (evidence: `src/index.js`)
- App Assembly → Avatar Cache: creates (evidence: `src/index.js`)
- App Assembly → Health Monitor: starts (evidence: `src/index.js`)
- App Assembly → VRChat Status: creates (evidence: `src/index.js`)
- WebSocket Pipeline → VRChat API Client: gets token (evidence: `src/index.js`)
- WebSocket Pipeline → Monitor Orchestrator: dispatches events
- Monitor Orchestrator → Friend State Machine: applies transitions (evidence: `src/monitor.js`)
- Monitor Orchestrator → SQLite Store: reads and writes (evidence: `src/monitor.js`)
- Monitor Orchestrator → VRChat API Client: reconciles via REST (evidence: `src/monitor.js`)
- VRChat API Client → VRChat Services: calls REST API (evidence: `src/vrcapi.js`)
- Monitor Orchestrator → World Names: resolves names
- Monitor Orchestrator → Notification Templates: dispatches notices
- Notification Templates → QQ Bot Gateway: formats messages (evidence: `src/notify.js`)
- QQ Bot Gateway → QQ Commands: handles commands (evidence: `src/qq.js`)
- QQ Bot Gateway → SQLite Store: reads binding (evidence: `src/qq.js`)
- QQ Bot Gateway → VRChat Services: connects gateway (evidence: `src/qq.js`)
- HTTP API → Login Recovery: handles auth (evidence: `src/server.js`)
- Login Recovery → VRChat API Client: re-authenticates (evidence: `src/server.js`)
- Login Recovery → WebSocket Pipeline: requests reconnect
- HTTP API → Avatar Cache: serves cached images (evidence: `src/avatar.js`)
- HTTP API → Live Log Stream: broadcasts logs (evidence: `src/server.js`)
- Live Log Stream → Log Panel: streams log events
- HTTP API → Web Interface: serves static UI
- Web Interface → Friend Views: shows friends
- Web Interface → Overview: shows overview
- Web Interface → Settings: configures service
- HTTP API → Health Monitor: exposes health
- Health Monitor → Web Interface: streams health
- VRChat Status → Web Interface: provides status
- App Assembly → Segmented Logs: opens log files (evidence: `src/index.js`)
- App Assembly → Live Log Stream: creates stream (evidence: `src/index.js`)
- SQLite Store → Data Encryption: encrypts fields
