Cross-post your content to dev.to, Hashnode, Medium, and more
Project description
Crier
Cross-post your content to dev.to, Ghost, WordPress, Hashnode, Medium, Bluesky, Mastodon, Threads, Telegram, Discord, and more.
Like a town crier announcing your content to the world.
Installation
pip install crier
Quick Start
# Configure your API keys
crier config set devto.api_key YOUR_API_KEY
crier config set bluesky.api_key "handle.bsky.social:app-password"
crier config set mastodon.api_key "mastodon.social:access-token"
# Publish a markdown file
crier publish post.md --to devto
# Publish to multiple platforms at once
crier publish post.md --to devto --to bluesky --to mastodon
# List your articles
crier list devto
# Update an existing article
crier update devto 12345 --file updated-post.md
Supported Platforms
| Platform | API Key Format | Notes |
|---|---|---|
| dev.to | api_key |
Full article support |
| Hashnode | token or token:publication_id |
Full article support |
| Medium | integration_token |
Publish only (no edit/list) |
| Ghost | https://site.com:key_id:key_secret |
Full article support |
| WordPress | site.wordpress.com:token or https://site.com:user:app_pass |
Full article support |
| Buttondown | api_key |
Newsletter publishing |
| Bluesky | handle:app_password |
Short posts with link cards |
| Mastodon | instance:access_token |
Toots with hashtags |
| Threads | user_id:access_token |
Short posts (no edit support) |
| Telegram | bot_token:chat_id |
Channel/group posts |
| Discord | webhook_url |
Server announcements |
access_token |
Requires API access | |
| Twitter/X | any (copy-paste mode) |
Generates tweet for manual posting |
Platform Notes
Blog Platforms (dev.to, Hashnode, Medium, Ghost, WordPress):
- Full markdown article publishing
- Preserves front matter (title, description, tags, canonical_url)
- Best for long-form content
Newsletter Platforms (Buttondown):
- Publishes to email subscribers
- Full markdown support
- Great for content repurposing
Social Platforms (Bluesky, Mastodon, LinkedIn, Twitter, Threads):
- Creates short posts with link to canonical URL
- Uses title + description + hashtags from tags
- Best for announcing new content
Announcement Channels (Telegram, Discord):
- Posts to channels/servers
- Good for community announcements
- Discord uses webhook embeds
Configuration
API keys can be set via:
-
Config file (
~/.config/crier/config.yaml):platforms: devto: api_key: your_key_here bluesky: api_key: "handle.bsky.social:app-password" mastodon: api_key: "mastodon.social:access-token"
-
Environment variables:
export CRIER_DEVTO_API_KEY=your_key_here export CRIER_BLUESKY_API_KEY="handle.bsky.social:app-password"
Markdown Format
Crier reads standard markdown with YAML front matter:
---
title: "My Amazing Post"
description: "A brief description"
tags: [python, programming]
canonical_url: https://myblog.com/my-post
published: true
---
Your content here...
Commands
crier publish FILE [--to PLATFORM]... # Publish to platform(s)
crier update PLATFORM ID --file FILE # Update existing article
crier list PLATFORM # List your articles
crier config set KEY VALUE # Set configuration
crier config show # Show configuration
crier platforms # List available platforms
Getting API Keys
dev.to
- Go to https://dev.to/settings/extensions
- Generate API key
Hashnode
- Go to https://hashnode.com/settings/developer
- Generate Personal Access Token
Medium
- Go to https://medium.com/me/settings/security
- Generate Integration Token
Bluesky
- Go to Settings → App Passwords
- Create an app password
- Use format:
yourhandle.bsky.social:xxxx-xxxx-xxxx-xxxx
Mastodon
- Go to Settings → Development → New Application
- Create app with
write:statusesscope - Use format:
instance.social:your-access-token
Twitter/X
Uses copy-paste mode - generates formatted tweet text for manual posting. No API setup required. Just set any placeholder value:
crier config set twitter.api_key manual
Ghost
- Go to Settings → Integrations → Add custom integration
- Copy the Admin API Key (format:
key_id:key_secret) - Use format:
https://yourblog.com:key_id:key_secret
WordPress
WordPress.com:
- Go to https://developer.wordpress.com/apps/
- Create an app and get OAuth token
- Use format:
yoursite.wordpress.com:access_token
Self-hosted WordPress:
- Go to Users → Profile → Application Passwords
- Create a new application password
- Use format:
https://yoursite.com:username:app_password
Buttondown
- Go to https://buttondown.email/settings/programming
- Copy your API key
- Use format:
api_key
Threads
- Create a Meta Developer account at https://developers.facebook.com/
- Create an app with Threads API access
- Get your user_id and access_token
- Use format:
user_id:access_token
Telegram
- Message @BotFather to create a bot and get the bot token
- Add your bot as admin to your channel
- Get your channel's chat_id (e.g.,
@yourchannelor numeric ID) - Use format:
bot_token:chat_id
Discord
- Go to Server Settings → Integrations → Webhooks
- Create a new webhook for your announcement channel
- Copy the webhook URL
- Use the full URL as the API key
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file crier-0.3.0.tar.gz.
File metadata
- Download URL: crier-0.3.0.tar.gz
- Upload date:
- Size: 37.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f33b8ca10294793b0ecfade1df30abe74a5983b3e97a7a1ced6d5ea78c87627
|
|
| MD5 |
c0607363d95f49cf983e38147c5ba04b
|
|
| BLAKE2b-256 |
c516d346119453bcaf2e1d9cfdb5412d6fdda6f353230e66cd446f5f0f1e52ca
|
File details
Details for the file crier-0.3.0-py3-none-any.whl.
File metadata
- Download URL: crier-0.3.0-py3-none-any.whl
- Upload date:
- Size: 39.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
56b5c648df1f57b20d7a9302061f403e1baf2b0db4f3c64141c37139ca8d2671
|
|
| MD5 |
809b424d385c4dff1239a971d0530d59
|
|
| BLAKE2b-256 |
0b800f5690dcfc436f4d6ae8378054e40622b0a8cefd58bf451661886ab7b007
|