114 lines
3.2 KiB
Markdown
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.
|