# dathabe/mediarelay architecture

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

- Interactive diagram: https://gitdiagram.com/dathabe/mediarelay
- Repository: https://github.com/dathabe/mediarelay

## Overview

MediaRelay accepts supported media URLs from console input or clipboard polling, extracts source-specific media and metadata in a browser, normalizes them into relay payloads, stores the resources, and sends them to configured targets such as Immich. The graph preserves the documented Pixiv, Twitter, and HeyBox branches. Several core implementations were not sampled, so links for those stages follow the README and module boundaries rather than inspected call sites.

Main entry points: [`src/MediaRelay/Content/ContentExtractorFactory.cs`](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/Content/ContentExtractorFactory.cs) (Extractor Factory), [`src/MediaRelay/ContentRelayService.cs`](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/ContentRelayService.cs) (Content Relay), [`src/MediaRelay.Url/UrlRelayService.cs`](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Url/UrlRelayService.cs) (URL Relay Service), [`src/MediaRelay/Messaging/MessageOrchestrator.cs`](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/Messaging/MessageOrchestrator.cs) (Message Orchestrator)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_inputs["URL Inputs"]
  node_console["Console Input"]
  node_clipboard["Clipboard Poller"]
end

subgraph group_urlflow["URL Processing"]
  node_orchestrator["Message Orchestrator"]
  node_urlqueue["URL Message Queue<br/>[UrlMessageQueue.cs]"]
  node_urlconsumer["URL Queue Consumer"]
  node_urlrelay["URL Relay Service<br/>[UrlRelayService.cs]"]
end

subgraph group_sources["Media Sources"]
  node_browser["Playwright Browser"]
  node_pixiv["Pixiv Extractor"]
  node_twitter["Twitter Extractor"]
  node_heybox["HeyBox Extractor"]
end

subgraph group_core["Relay Core"]
  node_extractorfactory["Extractor Factory"]
  node_contentrelay["Content Relay"]
  node_payloadfactory["Payload Factory<br/>[PayloadFactory.cs]"]
  node_payloadrelay["Payload Relay"]
end

subgraph group_storage["Media Storage"]
  node_resource_storage["Resource Storage<br/>[ResourceStorage.cs]"]
  node_media_repository[("Media Repository<br/>[MediaRepository.cs]")]
end

subgraph group_targets["Relay Targets"]
  node_immich["Immich Handler"]
  node_immich_api["Immich API"]
end

node_operator(("User"))

node_operator -->|"enters URL"| node_console
node_operator -->|"copies URL"| node_clipboard
node_console -->|"sends URL message"| node_orchestrator
node_clipboard -->|"sends URL message"| node_orchestrator
node_orchestrator -->|"enqueues message"| node_urlqueue
node_urlqueue -->|"dispatches message"| node_urlconsumer
node_urlconsumer -->|"handles URL"| node_urlrelay
node_urlrelay -->|"requests extraction"| node_extractorfactory
node_extractorfactory -->|"selects extractor"| node_pixiv
node_extractorfactory -->|"selects extractor"| node_twitter
node_extractorfactory -->|"selects extractor"| node_heybox
node_pixiv -->|"extracts via browser"| node_browser
node_twitter -->|"extracts via browser"| node_browser
node_heybox -->|"extracts via browser"| node_browser
node_urlrelay -->|"relays extracted content"| node_contentrelay
node_contentrelay -->|"creates payload"| node_payloadfactory
node_contentrelay -->|"stores resources"| node_resource_storage
node_resource_storage -->|"writes media"| node_media_repository
node_contentrelay -->|"dispatches payload"| node_payloadrelay
node_payloadrelay -->|"handles payload"| node_immich
node_immich -->|"uploads and updates"| node_immich_api

click node_console "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Console/ConsoleInputUrlBackgroundService.cs"
click node_clipboard "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Clipboard/ClipboardUrlBackgroundService.cs"
click node_orchestrator "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/Messaging/MessageOrchestrator.cs"
click node_urlqueue "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Url/Messaging/Queue/UrlMessageQueue.cs"
click node_urlconsumer "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Url/Messaging/Queue/UrlMessageQueueConsumer.cs"
click node_urlrelay "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Url/UrlRelayService.cs"
click node_browser "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/Browser/ChromiumBrowserService.cs"
click node_pixiv "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Pixiv/Artwork/ArtworkContentExtractor.cs"
click node_twitter "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Twitter/Tweet/TweetContentExtractor.cs"
click node_heybox "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.HeyBox/BbsLink/LinkContentExtractor.cs"
click node_extractorfactory "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/Content/ContentExtractorFactory.cs"
click node_contentrelay "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/ContentRelayService.cs"
click node_payloadfactory "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/Payload/PayloadFactory.cs"
click node_payloadrelay "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/PayloadRelayService.cs"
click node_resource_storage "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/Storage/Resource/ResourceStorage.cs"
click node_media_repository "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/Storage/Media/MediaRepository.cs"
click node_immich "https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Immich/ImmichRelayHandler.cs"

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_console,node_clipboard,node_operator toneBlue
class node_orchestrator,node_urlqueue,node_urlconsumer,node_urlrelay toneAmber
class node_browser,node_pixiv,node_twitter,node_heybox toneMint
class node_extractorfactory,node_contentrelay,node_payloadfactory,node_payloadrelay toneRose
class node_resource_storage,node_media_repository toneIndigo
class node_immich,node_immich_api toneTeal
```

## Components

### URL Inputs

- [Console Input](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Console/ConsoleInputUrlBackgroundService.cs): `src/MediaRelay.Console/ConsoleInputUrlBackgroundService.cs`
- [Clipboard Poller](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Clipboard/ClipboardUrlBackgroundService.cs): `src/MediaRelay.Clipboard/ClipboardUrlBackgroundService.cs`

### URL Processing

- [Message Orchestrator](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/Messaging/MessageOrchestrator.cs): `src/MediaRelay/Messaging/MessageOrchestrator.cs`
- [URL Message Queue](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Url/Messaging/Queue/UrlMessageQueue.cs): `src/MediaRelay.Url/Messaging/Queue/UrlMessageQueue.cs`
- [URL Queue Consumer](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Url/Messaging/Queue/UrlMessageQueueConsumer.cs): `src/MediaRelay.Url/Messaging/Queue/UrlMessageQueueConsumer.cs`
- [URL Relay Service](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Url/UrlRelayService.cs): `src/MediaRelay.Url/UrlRelayService.cs`

### Media Sources

- [Playwright Browser](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/Browser/ChromiumBrowserService.cs): `src/MediaRelay/Browser/ChromiumBrowserService.cs`
- [Pixiv Extractor](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Pixiv/Artwork/ArtworkContentExtractor.cs): `src/MediaRelay.Pixiv/Artwork/ArtworkContentExtractor.cs`
- [Twitter Extractor](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Twitter/Tweet/TweetContentExtractor.cs): `src/MediaRelay.Twitter/Tweet/TweetContentExtractor.cs`
- [HeyBox Extractor](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.HeyBox/BbsLink/LinkContentExtractor.cs): `src/MediaRelay.HeyBox/BbsLink/LinkContentExtractor.cs`

### Relay Core

- [Extractor Factory](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/Content/ContentExtractorFactory.cs): `src/MediaRelay/Content/ContentExtractorFactory.cs`
- [Content Relay](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/ContentRelayService.cs): `src/MediaRelay/ContentRelayService.cs`
- [Payload Factory](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/Payload/PayloadFactory.cs): `src/MediaRelay/Payload/PayloadFactory.cs`
- [Payload Relay](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/PayloadRelayService.cs): `src/MediaRelay/PayloadRelayService.cs`

### Media Storage

- [Resource Storage](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/Storage/Resource/ResourceStorage.cs): `src/MediaRelay/Storage/Resource/ResourceStorage.cs`
- [Media Repository](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay/Storage/Media/MediaRepository.cs): `src/MediaRelay/Storage/Media/MediaRepository.cs`

### Relay Targets

- [Immich Handler](https://github.com/dathabe/mediarelay/blob/master/src/MediaRelay.Immich/ImmichRelayHandler.cs): `src/MediaRelay.Immich/ImmichRelayHandler.cs`
- **Immich API**

### Other components

- **User**

## Connections

- User → Console Input: enters URL
- User → Clipboard Poller: copies URL
- Console Input → Message Orchestrator: sends URL message
- Clipboard Poller → Message Orchestrator: sends URL message
- Message Orchestrator → URL Message Queue: enqueues message
- URL Message Queue → URL Queue Consumer: dispatches message
- URL Queue Consumer → URL Relay Service: handles URL
- URL Relay Service → Extractor Factory: requests extraction
- Extractor Factory → Pixiv Extractor: selects extractor
- Extractor Factory → Twitter Extractor: selects extractor
- Extractor Factory → HeyBox Extractor: selects extractor
- Pixiv Extractor → Playwright Browser: extracts via browser
- Twitter Extractor → Playwright Browser: extracts via browser
- HeyBox Extractor → Playwright Browser: extracts via browser
- URL Relay Service → Content Relay: relays extracted content
- Content Relay → Payload Factory: creates payload
- Content Relay → Resource Storage: stores resources
- Resource Storage → Media Repository: writes media
- Content Relay → Payload Relay: dispatches payload
- Payload Relay → Immich Handler: handles payload
- Immich Handler → Immich API: uploads and updates
