Comprehensive guide to automating Statuz with URL schemes, MCP, and external tools. Build powerful workflows that save time and streamline your social media management.
Statuz offers two powerful automation APIs:
Best for:
open "statuz://compose?text=Automated%20post"
Learn more about URL Scheme API →
Best for:
"Schedule a post about our launch for tomorrow at 2pm"
Learn more about MCP Integration →
Schedule a good morning post every day:
#!/bin/bash
# morning-post.sh
TOMORROW=$(date -v+1d -u +"%Y-%m-%dT14:00:00Z") # 9 AM EST
TEXT="Good morning! ☀️ Have a productive day!"
ENCODED=$(printf %s "$TEXT" | jq -sRr @uri)
open "statuz://schedule?text=$ENCODED&date=$TOMORROW&status=queued"Add to crontab:
0 20 * * * /path/to/morning-post.sh # Run at 8 PM daily
Quick screenshot sharing:
#!/bin/bash
# screenshot.sh
screencapture -i /tmp/screenshot.png
if [ -f /tmp/screenshot.png ]; then
open "statuz://compose?media=file:///tmp/screenshot.png"
rm /tmp/screenshot.png
fiAssign to a keyboard shortcut in System Settings or Keyboard Maestro.
Post whatever's in your clipboard:
#!/bin/bash
# clipboard-post.sh
CONTENT=$(pbpaste)
ENCODED=$(printf %s "$CONTENT" | jq -sRr @uri)
open "statuz://compose?text=$ENCODED"Announce commits automatically:
#!/bin/bash
# .git/hooks/post-commit
COMMIT=$(git log -1 --pretty=%B)
HASH=$(git log -1 --pretty=%h)
TEXT="🚀 New commit: $COMMIT ($HASH)"
ENCODED=$(printf %s "$TEXT" | jq -sRr @uri)
open "statuz://compose?text=$ENCODED&draft=true"Create post-to-statuz.sh:
#!/bin/bash
# @raycast.schemaVersion 1
# @raycast.title Post to Statuz
# @raycast.mode silent
# @raycast.packageName Statuz
# @raycast.argument1 { "type": "text", "placeholder": "Your post" }
TEXT="$1"
ENCODED=$(printf %s "$TEXT" | jq -sRr @uri)
open "statuz://compose?text=$ENCODED"Create schedule-to-statuz.sh:
#!/bin/bash
# @raycast.schemaVersion 1
# @raycast.title Schedule to Statuz
# @raycast.mode silent
# @raycast.packageName Statuz
# @raycast.argument1 { "type": "text", "placeholder": "Post text" }
# @raycast.argument2 { "type": "text", "placeholder": "When (e.g., '2pm tomorrow')" }
TEXT="$1"
# Parse date with natural language tool of your choice
DATE="2025-01-20T14:00:00Z" # Replace with actual parsing
ENCODED=$(printf %s "$TEXT" | jq -sRr @uri)
open "statuz://schedule?text=$ENCODED&date=$DATE&status=queued"Keyword: post {query}
Script:
query="{query}"
encoded=$(printf %s "$query" | jq -sRr @uri)
open "statuz://compose?text=$encoded"Keyword: schedule {query}
Script:
query="{query}"
# Split query into text and date
encoded=$(printf %s "$query" | jq -sRr @uri)
open "statuz://schedule?text=$encoded&status=queued"Keyword: switch work / switch personal
Script (work):
open "statuz://accounts?action=set-default&platform=x&nickname=Work%20X"
open "statuz://accounts?action=set-default&platform=bluesky&nickname=Work%20BS"
osascript -e 'display notification "Switched to work accounts" with title "Statuz"'Script (personal):
open "statuz://accounts?action=set-default&platform=x&nickname=Personal%20X"
open "statuz://accounts?action=set-default&platform=bluesky&nickname=Personal%20BS"
osascript -e 'display notification "Switched to personal accounts" with title "Statuz"'Trigger: ⌃⌥⇧S
Actions:
if [ -f /tmp/km-screenshot.png ]; then
open "statuz://compose?media=file:///tmp/km-screenshot.png"
fiTrigger: ⌃⌥⇧P
Actions:
SELECTED="$KMVAR_Selected_Text"
ENCODED=$(printf %s "$SELECTED" | jq -sRr @uri)
open "statuz://compose?text=$ENCODED"Trigger: Every day at 8 PM
Actions:
#!/bin/bash
TOMORROW=$(date -v+1d -u +"%Y-%m-%dT14:00:00Z")
TEXT="Daily check-in: $(date +%Y-%m-%d)
Today's progress:
- [Add your updates here]
Tomorrow's goals:
- [Add your plans]"
ENCODED=$(printf %s "$TEXT" | jq -sRr @uri)
open "statuz://compose?text=$ENCODED&draft=true"Folder: ~/Desktop/To Post/
Conditions:
Actions:
#!/bin/bash
FILE="$1"
BASENAME=$(basename "$FILE")
TEXT="Latest screenshot: $BASENAME"
ENCODED_TEXT=$(printf %s "$TEXT" | jq -sRr @uri)
ENCODED_FILE=$(printf %s "file://$FILE" | jq -sRr @uri)
open "statuz://compose?text=$ENCODED_TEXT&media=$ENCODED_FILE"
# Move to processed folder
mkdir -p ~/Desktop/Posted
mv "$FILE" ~/Desktop/Posted/Folder: ~/Sites/blog/_posts/
Conditions:
Actions:
#!/bin/bash
FILE="$1"
# Extract title from frontmatter
TITLE=$(grep "^title:" "$FILE" | cut -d: -f2- | xargs)
SLUG=$(basename "$FILE" .md)
TEXT="📝 New blog post: $TITLE
Read more: https://example.com/blog/$SLUG"
ENCODED=$(printf %s "$TEXT" | jq -sRr @uri)
open "statuz://compose?text=$ENCODED&draft=true"#!/usr/bin/env python3
"""
Generate and post daily reports
"""
import subprocess
from datetime import datetime, timedelta
from urllib.parse import quote
def generate_daily_report():
# Fetch metrics from your systems
metrics = {
'users': 1250,
'revenue': 5400,
'signups': 23
}
text = f"""📊 Daily Report - {datetime.now().strftime('%Y-%m-%d')}
👥 Active Users: {metrics['users']:,}
💰 Revenue: ${metrics['revenue']:,}
✨ New Signups: {metrics['signups']}
Keep up the great work! 🚀"""
# Schedule for tomorrow at 9 AM
tomorrow = datetime.now() + timedelta(days=1)
schedule_time = tomorrow.replace(hour=9, minute=0, second=0)
iso_time = schedule_time.strftime('%Y-%m-%dT%H:%M:%S')
encoded = quote(text)
url = f"statuz://schedule?text={encoded}&date={iso_time}&timezone=America/New_York&status=queued"
subprocess.run(['open', url])
print(f"Report scheduled for {schedule_time}")
if __name__ == "__main__":
generate_daily_report()#!/usr/bin/env python3
"""
Monitor RSS feed and post new items
"""
import feedparser
import subprocess
from urllib.parse import quote
import json
import os
FEED_URL = "https://example.com/feed.xml"
STATE_FILE = os.path.expanduser("~/.statuz-feed-state.json")
def load_state():
if os.path.exists(STATE_FILE):
with open(STATE_FILE, 'r') as f:
return json.load(f)
return {'seen_ids': []}
def save_state(state):
with open(STATE_FILE, 'w') as f:
json.dump(state, f)
def check_feed():
state = load_state()
feed = feedparser.parse(FEED_URL)
for entry in feed.entries[:5]: # Check last 5
if entry.id not in state['seen_ids']:
text = f"📰 {entry.title}\n\n{entry.summary[:150]}...\n\n{entry.link}"
encoded = quote(text)
subprocess.run(['open', f"statuz://compose?text={encoded}&draft=true"])
state['seen_ids'].append(entry.id)
save_state(state)
break # Post one at a time
if __name__ == "__main__":
check_feed()Run with cron:
*/15 * * * * /path/to/rss-monitor.py # Check every 15 minutes
#!/usr/bin/env node
/**
* Slack webhook handler to post announcements
*/
const express = require('express');
const { exec } = require('child_process');
const { promisify } = require('util');
const execAsync = promisify(exec);
const app = express();
app.use(express.json());
app.post('/webhook', async (req, res) => {
const { text, channel } = req.body;
// Only post from #announcements channel
if (channel !== 'announcements') {
return res.sendStatus(200);
}
const encoded = encodeURIComponent(text);
await execAsync(`open "statuz://compose?text=${encoded}&draft=true"`);
res.sendStatus(200);
});
app.listen(3000, () => {
console.log('Slack to Statuz bridge running on port 3000');
});#!/usr/bin/env node
/**
* Post deployment notifications
*/
const { exec } = require('child_process');
const ENVIRONMENT = process.env.ENVIRONMENT || 'production';
const VERSION = process.env.VERSION || 'unknown';
const text = `✅ Deployment Complete
Environment: ${ENVIRONMENT}
Version: ${VERSION}
Time: ${new Date().toLocaleString()}
All systems operational! 🎉`;
const encoded = encodeURIComponent(text);
exec(`open "statuz://compose?text=${encoded}"`);Add to your CI/CD pipeline (e.g., GitHub Actions):
- name: Announce Deployment
run: |
export VERSION=${{ github.ref_name }}
export ENVIRONMENT=production
node announce-deploy.js#!/bin/bash
# distribute-content.sh - Post to all platforms with platform-specific formatting
BASE_TEXT="🚀 Exciting news!"
# Platform-specific variations
X_TEXT="$BASE_TEXT
Full details in the thread below 👇"
BLUESKY_TEXT="$BASE_TEXT
Check out what we've been building! 🛠️"
MASTODON_TEXT="$BASE_TEXT
More info on our blog: https://example.com/blog"
# Post to each platform
X_ENCODED=$(printf %s "$X_TEXT" | jq -sRr @uri)
BS_ENCODED=$(printf %s "$BLUESKY_TEXT" | jq -sRr @uri)
MASTO_ENCODED=$(printf %s "$MASTODON_TEXT" | jq -sRr @uri)
open "statuz://compose?text=$X_ENCODED&platforms=x"
sleep 1
open "statuz://compose?text=$BS_ENCODED&platforms=bluesky"
sleep 1
open "statuz://compose?text=$MASTO_ENCODED&platforms=mastodon"#!/bin/bash
# populate-calendar.sh - Bulk schedule posts for the week
declare -A schedule=(
["2025-01-20T09:00:00Z"]="Monday motivation: Start the week strong! 💪"
["2025-01-21T14:00:00Z"]="Tuesday tip: Stay focused on your goals 🎯"
["2025-01-22T10:00:00Z"]="Wednesday wisdom: Progress over perfection 📈"
["2025-01-23T15:00:00Z"]="Thursday thoughts: Keep pushing forward 🚀"
["2025-01-24T16:00:00Z"]="Friday feels: Weekend is almost here! 🎉"
)
for date in "${!schedule[@]}"; do
text="${schedule[$date]}"
encoded=$(printf %s "$text" | jq -sRr @uri)
open "statuz://schedule?text=$encoded&date=$date&status=queued"
echo "Scheduled: $text"
sleep 1
done
echo "Content calendar populated!"Always encode text parameters:
# ✅ Correct
ENCODED=$(printf %s "$TEXT" | jq -sRr @uri)
# ❌ Wrong (special characters will break)
ENCODED="$TEXT"Add robust error handling:
#!/bin/bash
set -euo pipefail # Exit on error, undefined vars, pipe failures
# Check dependencies
if ! command -v jq &> /dev/null; then
echo "Error: jq is required. Install with: brew install jq"
exit 1
fi
# Validate input
if [ -z "${TEXT:-}" ]; then
echo "Error: TEXT variable is empty"
exit 1
fiAvoid overwhelming Statuz with rapid requests:
# Add delays between bulk operations
for item in "${items[@]}"; do
# ... process item ...
sleep 1 # Wait 1 second
doneLog automation activities:
#!/bin/bash
LOG_FILE="$HOME/.statuz-automation.log"
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
log "Starting automation..."
# ... automation logic ...
log "Completed successfully"Track what's been processed:
import json
import os
STATE_FILE = os.path.expanduser("~/.my-automation-state.json")
def load_state():
if os.path.exists(STATE_FILE):
with open(STATE_FILE, 'r') as f:
return json.load(f)
return {}
def save_state(state):
with open(STATE_FILE, 'w') as f:
json.dump(state, f, indent=2)# Check if Statuz is installed
if [ ! -d "/Applications/Statuz.app" ]; then
echo "Error: Statuz not found in /Applications"
exit 1
fi
# Try opening manually
open -a Statuz "statuz://compose?text=Test"# Test encoding
TEXT="Hello 👋 World!"
ENCODED=$(printf %s "$TEXT" | jq -sRr @uri)
echo "Encoded: $ENCODED"
# Decode to verify
DECODED=$(printf '%b' "$(echo "$ENCODED" | sed 's/+/ /g; s/%/\\x/g')")
echo "Decoded: $DECODED"# Check file exists and is readable
if [ ! -r "$FILE" ]; then
echo "Error: Cannot read file: $FILE"
exit 1
fi
# Use absolute paths
FILE=$(realpath "$FILE")Share your automation scripts with the community:
Need help with automation?