Files
2026-05-08 17:59:37 +02:00

114 lines
3.2 KiB
Markdown

# medium-proxy
Transparent HTTPS proxy that sits between [Postiz](https://postiz.com) and `api.medium.com`.
When Postiz publishes a post to Medium it sends raw Markdown. This proxy intercepts the request and applies two fixes before forwarding to Medium's real API:
| Problem | Fix |
|---------|-----|
| Tables render as plain text with `\|` | Converts Markdown → HTML (`contentFormat: 'html'`) |
| Stories show a pattern thumbnail instead of a real image | Moves the first `<img>` to the top of the content |
Everything else (authentication, tags, canonical URL, publish status) is forwarded unchanged.
---
## How it works
```
Postiz container
│ fetch("https://api.medium.com/v1/users/.../posts")
│ [extra_hosts redirects api.medium.com → 172.19.0.100]
medium-proxy:443 (self-signed cert for api.medium.com, trusted via NODE_EXTRA_CA_CERTS)
│ - markdown → HTML
│ - featured image to top
api.medium.com (real Medium API)
```
---
## First-time deployment
**On the Postiz LXC (192.168.1.90):**
```bash
# 1. Clone this repo
cd /root
git clone https://gitea.alexandre-vazquez.cloud/alexandrev/medium-proxy.git
cd medium-proxy
# 2. Generate TLS certs, build image, start container
chmod +x setup.sh
./setup.sh
# 3. Apply the snippet printed by setup.sh to /root/postiz/docker-compose.yaml
# (adds extra_hosts, NODE_EXTRA_CA_CERTS, and volume mount for the CA cert)
# 4. Restart only the postiz service
cd /root/postiz && docker compose up -d postiz
```
### Postiz docker-compose.yaml patch
Add the following inside the `postiz` service block:
```yaml
extra_hosts:
- "api.medium.com:172.19.0.100"
environment:
NODE_EXTRA_CA_CERTS: /certs/ca.crt
volumes:
- /root/medium-proxy/certs/ca.crt:/certs/ca.crt:ro
```
---
## Updating
```bash
cd /root/medium-proxy
git pull
docker compose up -d --build
```
No need to touch the Postiz docker-compose again — certs are reused.
---
## Redeploying from scratch (e.g. after losing the LXC)
```bash
cd /root
git clone https://gitea.alexandre-vazquez.cloud/alexandrev/medium-proxy.git
cd medium-proxy
./setup.sh # generates new certs
# Apply the printed snippet to /root/postiz/docker-compose.yaml
# Restart postiz
```
> **Note:** New certs mean a new CA. Don't forget to restart the postiz container after updating the CA cert mount so Node.js picks it up (`NODE_EXTRA_CA_CERTS` is read at startup).
---
## Verifying it works
```bash
# Check proxy is running
docker logs medium-proxy
# Send a test publish from Postiz and look for the conversion log line:
# INFO POST /v1/users/.../posts | contentFormat: markdown → html
docker logs -f medium-proxy
```
---
## Limitations
- **Paywall**: Medium's public API (v1) has no endpoint to toggle the Partner Program paywall. Enable it manually for each story from the Medium web editor.
- **Featured image from WordPress**: The proxy moves the first image already present in the article body. If the WordPress featured image is not embedded in the article content (only stored as a post thumbnail), the proxy has no way to retrieve it — the story will still show the pattern thumbnail.
- **Post updates**: Medium's v1 API is create-only. Already-published stories with broken tables or missing images must be fixed manually via the Medium web editor.