# 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 `` 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.