Blame
|
1 | # Email-to-Obsidian-Sync |
||||||
| 2 | ||||||||
|
3 | ## Purpose |
||||||
| 4 | This script paired with an IOS shortcut that sends a link to my email server when I find something lets me easily save content that I may find useful later. ETOS uses fabric to summarize and generates a markdown file that is then sent to the obsidian rest api. |
|||||||
| 5 | ||||||||
| 6 | Theres some crap missing here I still need to add |
|||||||
| 7 | - Fabric Prompt |
|||||||
| 8 | - Directions for REST API |
|||||||
| 9 | - Obsidian Docker Container |
|||||||
| 10 | - Directions for fetchmail setup |
|||||||
|
11 | - IOS Shortcut |
||||||
|
12 | |||||||
|
13 | ```bash |
||||||
| 14 | #!/bin/bash |
|||||||
| 15 | # Define log levels and output functions |
|||||||
| 16 | LOG_LEVEL=INFO |
|||||||
| 17 | MAX_LOG_LINES=1000 |
|||||||
| 18 | log_debug() { [ "$LOG_LEVEL" = "DEBUG" ] && echo "$(date +"%Y%m%d_%H%M%S") - DEBUG: $@"; } |
|||||||
| 19 | log_info() { echo "$(date +"%Y%m%d_%H%M%S") - INFO: $@"; } |
|||||||
| 20 | log_warn() { echo "$(date +"%Y%m%d_%H%M%S") - WARN: $@" >&2; } |
|||||||
| 21 | log_error() { echo "$(date +"%Y%m%d_%H%M%S") - ERROR: $@" >&2; } |
|||||||
| 22 | ||||||||
| 23 | # Configuration for Obsidian REST API |
|||||||
| 24 | OBSIDIAN_API_URL="http://127.0.0.1:27123" |
|||||||
| 25 | OBSIDIAN_API_KEY="APIKEY" # Replace with your actual API key |
|||||||
| 26 | ||||||||
| 27 | # Step 1: Add date and time stamp to the fetched email file name |
|||||||
| 28 | TIMESTAMP=$(date +"%Y%m%d_%H%M%S") |
|||||||
| 29 | FETCHED_EMAIL_FILE="/home/etos/fetched_email_${TIMESTAMP}.txt" |
|||||||
| 30 | LOG_FILE="/var/log/etos_cron.log" |
|||||||
| 31 | touch $FETCHED_EMAIL_FILE |
|||||||
| 32 | ||||||||
| 33 | # Add a visual separator |
|||||||
| 34 | log_info "-------------------------- $(date) --------------------------" |
|||||||
| 35 | ||||||||
| 36 | # Log FETCH operation |
|||||||
| 37 | log_info "Fetching emails..." |
|||||||
| 38 | if [ "$LOG_LEVEL" = "DEBUG" ]; then |
|||||||
| 39 | fetchmail -v --mda "cat > $FETCHED_EMAIL_FILE" --keep --fetchlimit 1 # add --fetchall to get emails that have been fetched before |
|||||||
| 40 | else |
|||||||
| 41 | fetchmail -s --mda "cat > $FETCHED_EMAIL_FILE" --keep --fetchlimit 1 # add --fetchall to get emails that have been fetched before |
|||||||
| 42 | fi |
|||||||
| 43 | ||||||||
| 44 | # Step 2: Extract the first URL from the email body |
|||||||
| 45 | EMAIL_URL=$(sed -n 's/.*\(http[s]:\/\/[^ ]*\).*/\1/p' "$FETCHED_EMAIL_FILE" | head -n 1) |
|||||||
| 46 | if [ "$LOG_LEVEL" = "DEBUG" ]; then |
|||||||
| 47 | log_debug "Extracted URL: $EMAIL_URL" |
|||||||
| 48 | fi |
|||||||
| 49 | ||||||||
| 50 | # Step 3: Verify that the URL is not empty and is a valid URL format |
|||||||
| 51 | if [[ "$EMAIL_URL" =~ ^http[s]?:\/\/[a-zA-Z0-9.-]+\/?.*$ ]]; then |
|||||||
| 52 | # Log successful extraction |
|||||||
| 53 | log_info "Extracted URL: $EMAIL_URL" |
|||||||
| 54 | ||||||||
| 55 | # Step 4: Use fabric to process the URL |
|||||||
| 56 | FABRIC_OUTPUT=$(mktemp) |
|||||||
| 57 | ||||||||
| 58 | # Run the fabric command with the extracted URL |
|||||||
| 59 | /usr/local/bin/fabric --pattern explain_docs --output="$FABRIC_OUTPUT" --scrape_url="$EMAIL_URL" |
|||||||
| 60 | ||||||||
| 61 | if [ $? -ne 0 ]; then |
|||||||
| 62 | log_error "Fabric execution failed!" |
|||||||
| 63 | rm "$FABRIC_OUTPUT" |
|||||||
| 64 | exit 1 |
|||||||
| 65 | else |
|||||||
| 66 | log_info "Fabric execution successful!" |
|||||||
| 67 | fi |
|||||||
| 68 | ||||||||
| 69 | # Step 5: Extract the title for naming the note - only get the first line matching title pattern |
|||||||
| 70 | TITLE=$(head -n 10 "$FABRIC_OUTPUT" | grep -E '^(# |Title: )' | head -n 1 | sed -E 's/^# //;s/^Title: //') |
|||||||
| 71 | ||||||||
| 72 | if [ -z "$TITLE" ]; then |
|||||||
| 73 | # If no title found, use a default name with timestamp |
|||||||
| 74 | TITLE="New_${TIMESTAMP}" |
|||||||
| 75 | log_debug "No title found in the first 10 lines of the file, using default: $TITLE" |
|||||||
| 76 | else |
|||||||
| 77 | # Clean up the title by removing unwanted characters |
|||||||
| 78 | TITLE=$(echo "$TITLE" | sed -E 's/^(# |Title: )//; s/[ ]+/_/g; s/[^[:alnum:]_.-]//g; s/__+/_/g') |
|||||||
| 79 | log_debug "Using extracted title: $TITLE" |
|||||||
| 80 | fi |
|||||||
| 81 | ||||||||
| 82 | # Step 6: Prepare content for API |
|||||||
| 83 | TEMP_CONTENT_FILE=$(mktemp) |
|||||||
| 84 | echo -e "URL: $EMAIL_URL\n\n$(cat "$FABRIC_OUTPUT")" > "$TEMP_CONTENT_FILE" |
|||||||
| 85 | ||||||||
| 86 | # Test API connectivity before making the call |
|||||||
| 87 | log_debug "Testing Obsidian API connectivity..." |
|||||||
| 88 | test_response=$(curl -s -o /dev/null -w "%{http_code}" "${OBSIDIAN_API_URL}/") |
|||||||
| 89 | if [ "$test_response" = "200" ]; then |
|||||||
| 90 | log_debug "Obsidian API is accessible" |
|||||||
| 91 | else |
|||||||
| 92 | log_error "Obsidian API is not accessible, received code: $test_response" |
|||||||
| 93 | fi |
|||||||
| 94 | ||||||||
| 95 | # URL encode the title for the API path |
|||||||
| 96 | ENCODED_TITLE=$(echo "$TITLE" | sed 's/ /%20/g') |
|||||||
| 97 | ||||||||
| 98 | # Step 7: Send the content to Obsidian via REST API |
|||||||
| 99 | log_info "Sending content to Obsidian via REST API..." |
|||||||
| 100 | ||||||||
| 101 | curl_output=$(curl -s -X PUT \ |
|||||||
| 102 | "${OBSIDIAN_API_URL}/vault/New/${ENCODED_TITLE}.md" \ |
|||||||
| 103 | -H "Authorization: Bearer ${OBSIDIAN_API_KEY}" \ |
|||||||
| 104 | -H "Content-Type: text/markdown" \ |
|||||||
| 105 | --data-binary @"$TEMP_CONTENT_FILE" \ |
|||||||
| 106 | --write-out "%{http_code}" \ |
|||||||
| 107 | -o /dev/null) |
|||||||
| 108 | ||||||||
| 109 | CURL_EXIT_CODE=$? |
|||||||
| 110 | HTTP_CODE=$curl_output |
|||||||
| 111 | ||||||||
| 112 | if [ $CURL_EXIT_CODE -ne 0 ]; then |
|||||||
| 113 | log_error "Failed to send content to Obsidian API. CURL exit code: $CURL_EXIT_CODE" |
|||||||
| 114 | elif [ "$HTTP_CODE" -ge 400 ]; then |
|||||||
| 115 | log_error "Obsidian API returned error code: $HTTP_CODE" |
|||||||
| 116 | else |
|||||||
| 117 | log_info "Successfully sent content to Obsidian API. Note created: $TITLE.md" |
|||||||
| 118 | fi |
|||||||
| 119 | ||||||||
| 120 | # Clean up temporary files |
|||||||
| 121 | rm "$TEMP_CONTENT_FILE" |
|||||||
| 122 | rm "$FABRIC_OUTPUT" |
|||||||
| 123 | else |
|||||||
| 124 | # Log invalid URL |
|||||||
| 125 | log_info "No valid URL found in the email: $EMAIL_URL or no new email." |
|||||||
| 126 | fi |
|||||||
| 127 | ||||||||
| 128 | # Cleanup Home Directory |
|||||||
| 129 | log_info "Cleaning Home Directory" |
|||||||
| 130 | rm -rf /home/etos/fetched_email_*.txt |
|||||||
| 131 | log_info "Finished" |
|||||||
| 132 | ``` |
|||||||