Created
August 13, 2025 12:57
-
-
Save CaffTech/3922b6aa1d6ae787a5b9299efe9a78df to your computer and use it in GitHub Desktop.
A command line BASH script post to Memos
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # A BASH script to post memos from the command line. | |
| # It is a conversion of a PowerShell script from: https://www.reddit.com/r/selfhosted/comments/1mohkot/i_love_self_hosting_memos_great_api_for_super/ | |
| # Needs yout own instance of Memos - https://www.usememos.com/ | |
| # Default environment variables | |
| MEMOS_URI="${MEMOS_URI:-https://YOUR_DOMAIN.com}" | |
| MEMOS_TOKEN="${MEMOS_TOKEN:-YOUR_API_TOKEN}" | |
| function memo() { | |
| local content="" | |
| local tags=() | |
| local memo_uri="$MEMOS_URI" | |
| local api_token="$MEMOS_TOKEN" | |
| local verbose=false | |
| # Parse command line arguments | |
| while [[ $# -gt 0 ]]; do | |
| case $1 in | |
| -c|--content) | |
| content="$2" | |
| shift 2 | |
| ;; | |
| -t|--tag|--tags) | |
| IFS=',' read -ra ADDR <<< "$2" | |
| for tag in "${ADDR[@]}"; do | |
| tag=$(echo "$tag" | tr -d ' ') | |
| if [[ -n "$tag" ]]; then | |
| tags+=("$tag") | |
| fi | |
| done | |
| shift 2 | |
| ;; | |
| -u|--uri|--memo-uri) | |
| memo_uri="$2" | |
| shift 2 | |
| ;; | |
| -a|--token|--api-token) | |
| api_token="$2" | |
| shift 2 | |
| ;; | |
| -v|--verbose) | |
| verbose=true | |
| shift | |
| ;; | |
| -h|--help) | |
| echo "Usage: memo [OPTIONS] CONTENT" | |
| echo "Options:" | |
| echo " -c, --content CONTENT Memo content" | |
| echo " -t, --tag, --tags TAGS Comma-separated tags" | |
| echo " -u, --uri URI Memos URI (default: \$MEMOS_URI)" | |
| echo " -a, --token TOKEN API token (default: \$MEMOS_TOKEN)" | |
| echo " -v, --verbose Verbose output" | |
| echo " -h, --help Show this help" | |
| echo "" | |
| echo "Examples:" | |
| echo " memo -c \"Hello world\"" | |
| echo " memo -c \"Meeting notes\" -t \"work,meeting\"" | |
| echo " echo \"Piped content\" | memo" | |
| return 0 | |
| ;; | |
| *) | |
| if [[ -z "$content" ]]; then | |
| content="$1" | |
| fi | |
| shift | |
| ;; | |
| esac | |
| done | |
| # Read from stdin if no content provided | |
| if [[ -z "$content" && -p /dev/stdin ]]; then | |
| content=$(cat) | |
| fi | |
| # Validate required parameters | |
| if [[ -z "$memo_uri" ]]; then | |
| echo "Error: MemoUri is required. Pass --uri or set MEMOS_URI environment variable." >&2 | |
| return 1 | |
| fi | |
| if [[ ! "$memo_uri" =~ ^https?:// ]]; then | |
| memo_uri="https://$memo_uri" | |
| fi | |
| if [[ -z "$api_token" ]]; then | |
| echo "Error: ApiToken is required. Pass --token or set MEMOS_TOKEN environment variable." >&2 | |
| return 1 | |
| fi | |
| if [[ -z "$content" ]]; then | |
| echo "Error: Content is required. Pass --content or provide content as argument." >&2 | |
| return 1 | |
| fi | |
| # Process tags: normalize and ensure leading # | |
| local tag_string="" | |
| if [[ ${#tags[@]} -gt 0 ]]; then | |
| local processed_tags=() | |
| for tag in "${tags[@]}"; do | |
| # Split on whitespace and commas, process each part | |
| IFS=$' \t\n,' read -ra parts <<< "$tag" | |
| for part in "${parts[@]}"; do | |
| part=$(echo "$part" | tr -d ' \t\n') | |
| if [[ -n "$part" ]]; then | |
| if [[ "$part" =~ ^# ]]; then | |
| processed_tags+=("$part") | |
| else | |
| processed_tags+=("#$part") | |
| fi | |
| fi | |
| done | |
| done | |
| if [[ ${#processed_tags[@]} -gt 0 ]]; then | |
| tag_string=$(IFS=' '; echo "${processed_tags[*]}") | |
| fi | |
| fi | |
| # Prepare content with tags | |
| local final_content="$content" | |
| if [[ -n "$tag_string" ]]; then | |
| final_content="$content"$'\n'"$tag_string" | |
| fi | |
| # Create JSON body | |
| local json_body | |
| json_body=$(jq -n --arg content "$final_content" '{content: $content}') | |
| # Make HTTP request | |
| local response | |
| local http_code | |
| response=$(curl -s -w "%{http_code}" \ | |
| -X POST \ | |
| -H "Accept: application/json" \ | |
| -H "Authorization: Bearer $api_token" \ | |
| -H "Content-Type: application/json" \ | |
| -d "$json_body" \ | |
| "${memo_uri%/}/api/v1/memos") | |
| http_code="${response: -3}" | |
| response="${response%???}" | |
| if [[ "$http_code" -ge 200 && "$http_code" -lt 300 ]]; then | |
| if [[ "$verbose" == true ]]; then | |
| echo "$response" | jq . | |
| fi | |
| else | |
| echo "Error: HTTP request failed with status $http_code" >&2 | |
| if [[ -n "$response" ]]; then | |
| echo "Response: $response" >&2 | |
| fi | |
| return 1 | |
| fi | |
| } | |
| # If script is called directly (not sourced), run the function with all arguments | |
| if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then | |
| memo "$@" | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment