# dylanpdx/bettertwitfix architecture

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

- Interactive diagram: https://gitdiagram.com/dylanpdx/bettertwitfix
- Repository: https://github.com/dylanpdx/bettertwitfix

## Overview

vxTwitter is a Flask service that turns Twitter/X post links into Discord-friendly embeds and exposes tweet data through an API. The main workflow accepts a post URL, obtains and formats tweet data, then serves an embed or API response. Documented supporting capabilities include configurable caching, image combination, GIF conversion, browser redirection preferences, oEmbed/activity responses, and translation. The excerpts show the Flask entry point and several helpers; some internal call wiring and unsampled route details are omitted, so those links are not inferred.

Main entry points: [`twitfix.py`](https://github.com/dylanpdx/bettertwitfix/blob/main/twitfix.py) (Flask routes), [`twExtract/__init__.py`](https://github.com/dylanpdx/bettertwitfix/blob/main/twExtract/__init__.py) (Tweet extraction), [`cache.py`](https://github.com/dylanpdx/bettertwitfix/blob/main/cache.py) (Link cache), [`static/openInApp.js`](https://github.com/dylanpdx/bettertwitfix/blob/main/static/openInApp.js) (Redirect preferences)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_request["Request handling"]
  node_web["Flask routes<br/>[twitfix.py]"]
  node_configuration["Configuration<br/>[configHandler.py]"]
  node_preferences["Redirect preferences<br/>[openInApp.js]"]
end

subgraph group_tweet["Tweet data"]
  node_extractor["Tweet extraction<br/>[__init__.py]"]
  node_tweet_format["Tweet normalization<br/>[vxApi.py]"]
  node_utilities["Tweet utilities<br/>[utils.py]"]
  node_cache[("Link cache<br/>[cache.py]")]
end

subgraph group_presentation["Embed and presentation"]
  node_embed_templates["Embed templates"]
  node_activity["Activity output<br/>[activity.py]"]
  node_oembed["oEmbed output<br/>[twitfix.py]"]
end

subgraph group_services["Optional services"]
  node_image_combiner["Image combination<br/>[__init__.py]"]
  node_gif_converter["GIF conversion<br/>[__init__.py]"]
  node_translation["Translation<br/>[translation.py]"]
end

node_visitor(("Link visitor"))
node_api_client(("API client"))
node_discord(("Discord"))
node_x(("Twitter/X"))
node_mongo[("MongoDB")]
node_dynamodb[("DynamoDB")]
node_media_host["Twitter media"]

node_visitor -->|"requests post link"| node_web
node_api_client -->|"requests tweet data"| node_web
node_discord -->|"requests embed"| node_web
node_web -->|"reads settings"| node_configuration
node_web -->|"checks cached link"| node_cache
node_web -->|"fetches tweet"| node_extractor
node_extractor -->|"requests tweet data"| node_x
node_extractor -->|"provides tweet response"| node_tweet_format
node_web -->|"formats API data"| node_tweet_format
node_web -->|"uses tweet helpers"| node_utilities
node_web -->|"renders page"| node_embed_templates
node_web -->|"generates activity"| node_activity
node_web -->|"serves oEmbed"| node_oembed
node_web -->|"combines images"| node_image_combiner
node_image_combiner -->|"downloads images"| node_media_host
node_web -.->|"uses GIF conversion"| node_gif_converter
node_gif_converter -->|"downloads video"| node_media_host
node_web -.->|"requests translation"| node_translation
node_cache -.->|"reads and writes"| node_mongo
node_cache -.->|"reads and writes"| node_dynamodb
node_visitor -->|"sets redirect choice"| node_preferences
node_preferences -->|"opens app or frontend"| node_visitor

click node_web "https://github.com/dylanpdx/bettertwitfix/blob/main/twitfix.py"
click node_configuration "https://github.com/dylanpdx/bettertwitfix/blob/main/configHandler.py"
click node_preferences "https://github.com/dylanpdx/bettertwitfix/blob/main/static/openInApp.js"
click node_extractor "https://github.com/dylanpdx/bettertwitfix/blob/main/twExtract/__init__.py"
click node_tweet_format "https://github.com/dylanpdx/bettertwitfix/blob/main/vxApi.py"
click node_utilities "https://github.com/dylanpdx/bettertwitfix/blob/main/utils.py"
click node_cache "https://github.com/dylanpdx/bettertwitfix/blob/main/cache.py"
click node_embed_templates "https://github.com/dylanpdx/bettertwitfix/tree/main/templates"
click node_activity "https://github.com/dylanpdx/bettertwitfix/blob/main/activity.py"
click node_oembed "https://github.com/dylanpdx/bettertwitfix/blob/main/twitfix.py"
click node_image_combiner "https://github.com/dylanpdx/bettertwitfix/blob/main/combineImg/__init__.py"
click node_gif_converter "https://github.com/dylanpdx/bettertwitfix/blob/main/gifConvert/__init__.py"
click node_translation "https://github.com/dylanpdx/bettertwitfix/blob/main/translation.py"

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_web,node_configuration,node_preferences,node_api_client toneBlue
class node_extractor,node_tweet_format,node_utilities,node_cache,node_mongo,node_dynamodb toneAmber
class node_embed_templates,node_activity,node_oembed toneMint
class node_image_combiner,node_gif_converter,node_translation toneRose
class node_visitor,node_discord,node_x,node_media_host toneIndigo
```

## Components

### Request handling

- [Flask routes](https://github.com/dylanpdx/bettertwitfix/blob/main/twitfix.py): `twitfix.py`
- [Configuration](https://github.com/dylanpdx/bettertwitfix/blob/main/configHandler.py): `configHandler.py`
- [Redirect preferences](https://github.com/dylanpdx/bettertwitfix/blob/main/static/openInApp.js): `static/openInApp.js`

### Tweet data

- [Tweet extraction](https://github.com/dylanpdx/bettertwitfix/blob/main/twExtract/__init__.py): `twExtract/__init__.py`
- [Tweet normalization](https://github.com/dylanpdx/bettertwitfix/blob/main/vxApi.py): `vxApi.py`
- [Tweet utilities](https://github.com/dylanpdx/bettertwitfix/blob/main/utils.py): `utils.py`
- [Link cache](https://github.com/dylanpdx/bettertwitfix/blob/main/cache.py): `cache.py`

### Embed and presentation

- [Embed templates](https://github.com/dylanpdx/bettertwitfix/tree/main/templates): `templates`
- [Activity output](https://github.com/dylanpdx/bettertwitfix/blob/main/activity.py): `activity.py`
- [oEmbed output](https://github.com/dylanpdx/bettertwitfix/blob/main/twitfix.py): `twitfix.py`

### Optional services

- [Image combination](https://github.com/dylanpdx/bettertwitfix/blob/main/combineImg/__init__.py): `combineImg/__init__.py`
- [GIF conversion](https://github.com/dylanpdx/bettertwitfix/blob/main/gifConvert/__init__.py): `gifConvert/__init__.py`
- [Translation](https://github.com/dylanpdx/bettertwitfix/blob/main/translation.py): `translation.py`

### Other components

- **Link visitor**
- **API client**
- **Discord**
- **Twitter/X**
- **MongoDB**
- **DynamoDB**
- **Twitter media**

## Connections

- Link visitor → Flask routes: requests post link
- API client → Flask routes: requests tweet data
- Discord → Flask routes: requests embed
- Flask routes → Configuration: reads settings
- Flask routes → Link cache: checks cached link
- Flask routes → Tweet extraction: fetches tweet
- Tweet extraction → Twitter/X: requests tweet data
- Tweet extraction → Tweet normalization: provides tweet response
- Flask routes → Tweet normalization: formats API data
- Flask routes → Tweet utilities: uses tweet helpers
- Flask routes → Embed templates: renders page
- Flask routes → Activity output: generates activity
- Flask routes → oEmbed output: serves oEmbed
- Flask routes → Image combination: combines images
- Image combination → Twitter media: downloads images
- Flask routes → GIF conversion: uses GIF conversion
- GIF conversion → Twitter media: downloads video
- Flask routes → Translation: requests translation
- Link cache → MongoDB: reads and writes
- Link cache → DynamoDB: reads and writes
- Link visitor → Redirect preferences: sets redirect choice
- Redirect preferences → Link visitor: opens app or frontend
