From e3b47b69eaf65ada025b5f834ea058f49d5a3b55 Mon Sep 17 00:00:00 2001 From: OpenClaw Bot Date: Thu, 26 Feb 2026 15:50:36 -0600 Subject: [PATCH] Add CLI script for blog-backup API operations --- scripts/blog.sh | 296 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100755 scripts/blog.sh diff --git a/scripts/blog.sh b/scripts/blog.sh new file mode 100755 index 0000000..993ad3d --- /dev/null +++ b/scripts/blog.sh @@ -0,0 +1,296 @@ +#!/bin/bash +# Blog Backup CLI - Main Entry Point +# Usage: ./blog.sh [args] +# +# Commands: +# post Create a new digest post +# list List digests +# get Get a specific digest by ID +# delete Delete a digest +# search Search digests by content +# status Check if digest exists for a date +# health Check API health +# +# Environment: +# BLOG_API_URL Blog Backup API URL (default: https://blog-backup-two.vercel.app/api) +# BLOG_MACHINE_TOKEN Machine token for API auth (required) + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Set default API URL +export BLOG_API_URL="${BLOG_API_URL:-https://blog-backup-two.vercel.app/api}" + +# Check for machine token +if [[ -z "${BLOG_MACHINE_TOKEN:-}" ]]; then + # Try to load from .env.local + if [[ -f "$PROJECT_ROOT/.env.local" ]]; then + source "$PROJECT_ROOT/.env.local" + fi + + # Check if CRON_API_KEY is available + if [[ -n "${CRON_API_KEY:-}" ]]; then + export BLOG_MACHINE_TOKEN="$CRON_API_KEY" + fi +fi + +# Source the skill library +source "${HOME}/.agents/skills/blog-backup/lib/blog.sh" + +# Show usage +usage() { + cat << 'EOF' +Blog Backup CLI + +Usage: ./blog.sh [args] + +Commands: + post [args] Create a new digest post + --date YYYY-MM-DD Date for the digest (required) + --content "..." Content in markdown (required) + --tags '["tag1","tag2"]' Tags as JSON array (default: ["daily-digest"]) + + list [args] List digests + --limit N Max results (default: 20) + --since YYYY-MM-DD Filter by date + --json Output as JSON + + get Get a specific digest by ID + + delete Delete a digest by ID + + search Search digests by content + --limit N Max results (default: 20) + + status Check if digest exists for a date (YYYY-MM-DD) + + health Check API health + +Examples: + ./blog.sh post --date 2026-02-26 --content "# Daily Digest" --tags '["AI", "iOS"]' + ./blog.sh list --limit 10 + ./blog.sh get 1234567890 + ./blog.sh search "OpenClaw" + ./blog.sh status 2026-02-26 + +Environment Variables: + BLOG_API_URL Blog Backup API URL + BLOG_MACHINE_TOKEN Machine token for API auth + +EOF +} + +# Post command +handle_post() { + local DATE="" + local CONTENT="" + local TAGS='["daily-digest"]' + + # Parse arguments + while [[ $# -gt 0 ]]; do + case "$1" in + --date) + DATE="$2" + shift 2 + ;; + --content) + CONTENT="$2" + shift 2 + ;; + --tags) + TAGS="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" >&2 + shift + ;; + esac + done + + # Validate required fields + if [[ -z "$DATE" ]]; then + echo "Usage: ./blog.sh post --date --content [--tags ]" >&2 + exit 1 + fi + + if [[ -z "$CONTENT" ]]; then + echo "Error: --content is required" >&2 + exit 1 + fi + + # Create the digest + local DIGEST_ID + DIGEST_ID=$(blog_post_create --date "$DATE" --content "$CONTENT" --tags "$TAGS") + + if [[ $? -eq 0 ]]; then + echo "✅ Digest created: $DIGEST_ID" + echo "URL: https://blog-backup-two.vercel.app" + else + echo "❌ Failed to create digest" >&2 + exit 1 + fi +} + +# List command +handle_list() { + local LIMIT=20 + local SINCE="" + local JSON_OUTPUT=false + + # Parse arguments + while [[ $# -gt 0 ]]; do + case "$1" in + --limit) + LIMIT="$2" + shift 2 + ;; + --since) + SINCE="$2" + shift 2 + ;; + --json) + JSON_OUTPUT=true + shift + ;; + *) + shift + ;; + esac + done + + if [[ "$JSON_OUTPUT" == "true" ]]; then + blog_post_list --limit "$LIMIT" ${SINCE:+--since "$SINCE"} --json | jq . + else + echo "=== Recent Digests ===" + blog_post_list --limit "$LIMIT" ${SINCE:+--since "$SINCE"} + fi +} + +# Get command +handle_get() { + local ID="${1:-}" + + if [[ -z "$ID" ]]; then + echo "Usage: ./blog.sh get " >&2 + exit 1 + fi + + local RESULT + RESULT=$(blog_post_get "$ID") + + if [[ -n "$RESULT" ]]; then + echo "$RESULT" | jq . + else + echo "❌ Digest not found: $ID" >&2 + exit 1 + fi +} + +# Delete command +handle_delete() { + local ID="${1:-}" + + if [[ -z "$ID" ]]; then + echo "Usage: ./blog.sh delete " >&2 + exit 1 + fi + + blog_post_delete "$ID" +} + +# Search command +handle_search() { + local QUERY="${1:-}" + local LIMIT=20 + + if [[ -z "$QUERY" ]]; then + echo "Usage: ./blog.sh search [--limit N]" >&2 + exit 1 + fi + + # Check for --limit flag + if [[ "$2" == "--limit" && -n "${3:-}" ]]; then + LIMIT="$3" + fi + + echo "=== Search Results for '$QUERY' ===" + blog_post_search "$QUERY" --limit "$LIMIT" | jq -r '.[] | "\(.id) | \(.date) | \(.content | .[0:50])..."' +} + +# Status command +handle_status() { + local DATE="${1:-}" + + if [[ -z "$DATE" ]]; then + echo "Usage: ./blog.sh status " >&2 + exit 1 + fi + + if blog_post_status "$DATE"; then + echo "✅ Digest exists for $DATE" + else + echo "❌ No digest found for $DATE" + fi +} + +# Health command +handle_health() { + echo "=== API Health Check ===" + local RESULT + RESULT=$(blog_health) + + if [[ -n "$RESULT" ]]; then + echo "✅ API is accessible" + echo "$RESULT" | jq . 2>/dev/null || echo "$RESULT" + else + echo "❌ API is not responding" >&2 + exit 1 + fi +} + +# Main command dispatcher +main() { + local cmd="${1:-}" + shift || true + + case "$cmd" in + post) + handle_post "$@" + ;; + list) + handle_list "$@" + ;; + get) + handle_get "$@" + ;; + delete) + handle_delete "$@" + ;; + search) + handle_search "$@" + ;; + status) + handle_status "$@" + ;; + health) + handle_health + ;; + help|--help|-h) + usage + ;; + *) + if [[ -z "$cmd" ]]; then + usage + exit 1 + fi + echo "Unknown command: $cmd" >&2 + usage + exit 1 + ;; + esac +} + +main "$@"