Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Post to Bluesky #212

Open
random-robbie opened this issue Dec 7, 2024 · 1 comment
Open

Feature Request: Post to Bluesky #212

random-robbie opened this issue Dec 7, 2024 · 1 comment
Assignees
Labels
enhancement New feature or request

Comments

@random-robbie
Copy link

Hey,

With twitter being dead these days i thought posts to bluesky would be an idea and have taken the masterdon script and changed it.

Environment Variables needed. I don't have Vessels set up at the moment to confirm it's working but it should work.

BLUESKY_HANDLE="your.handle.bsky.social"
BLUESKY_APP_PASSWORD="your-app-password"

For Review

#!/command/with-contenv bash
#shellcheck shell=bash disable=SC2015,SC2164,SC1090,SC1091
#---------------------------------------------------------------------------------------------
# Copyright (C) 2022-2024, Ramon F. Kolb (kx1t)
# Modified for Bluesky support
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#---------------------------------------------------------------------------------------------
# This script sends a Bluesky notification (post)

# redirect stderr to stdout so it's picked up in the docker logs
exec 2>&1
# all errors will show a line number and the command used to produce the error
SCRIPT_PATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd)/$(basename "$0")"
trap 'echo -e "[$(date)][$APPNAME][ERROR] $SCRIPT_PATH in line $LINENO when executing: $BASH_COMMAND returned ${?}"' ERR

APPNAME="$(hostname)/send-bluesky"

[[ -z "${VESSELDBFILE}" ]] && VESSELDBFILE="/data/vessel.db" || true
IMAGECACHE="${VESSELDBFILE%/*}/imagecache"
BLUESKY_API="https://bsky.social/xrpc"

# Check for required environment variables
[[ -z "${BLUESKY_HANDLE}" ]] && echo "[$(date)][$APPNAME] Error: BLUESKY_HANDLE not defined" && exit 1
[[ -z "${BLUESKY_APP_PASSWORD}" ]] && echo "[$(date)][$APPNAME] Error: BLUESKY_APP_PASSWORD not defined" && exit 1

source "$VESSELDBFILE"

if [[ -z "$1" ]]; then
    echo "$0 - send a Bluesky notification for a specific MMSI"
    echo "Usage: $0 mmsi"
    exit 1
else
    echo "[$(date)][$APPNAME] Attempting Bluesky notification for $1 (${VESSELS[$1:shipname]})"
fi

# First get an auth token
auth_response=$(curl -s -X POST "$BLUESKY_API/com.atproto.server.createSession" \
    -H "Content-Type: application/json" \
    -d "{\"identifier\":\"$BLUESKY_HANDLE\",\"password\":\"$BLUESKY_APP_PASSWORD\"}")

access_jwt=$(echo "$auth_response" | jq -r '.accessJwt')
did=$(echo "$auth_response" | jq -r '.did')

if [[ -z "$access_jwt" || "$access_jwt" == "null" ]]; then
    echo "[$(date)][$APPNAME] Error: Failed to authenticate with Bluesky"
    exit 1
fi

# Clean up vessel data
[[ -n "${VESSELS[$1:shipname]}" ]] && VESSELS[$1:shipname]="$(sed -e ':a;s/^\(\([^"]*[,.]\?\|"[^",.]*"[,.]\?\)*"[^",.]*\)[,.]/\1 /;ta' -e 's|["'\''.]||g' -e 's|[^A-Z0-9,\.\-]\+|_|g' -e 's|_,|,|g' <<< "${VESSELS[$1:shipname]}")"
[[ -n "${VESSELS[$1:destination]}" ]] && VESSELS[$1:destination]="$(sed -e ':a;s/^\(\([^"]*[,.]\?\|"[^",.]*"[,.]\?\)*"[^",.]*\)[,.]/\1 /;ta' -e 's|["'\''.]||g' -e 's|[^A-Z0-9,\.\-]\+|_|g' -e 's|_,|,|g' <<< "${VESSELS[$1:destination]}")"

# Build the message
links=""
[[ -n "$BLUESKY_LINK_SHIPXPLORER" ]] && links+="https://www.shipxplorer.com/data/vessels/IMO-MMSI-${VESSELS[$1:mmsi]}\n" || true
[[ -n "$BLUESKY_LINK_MARINETRAFFIC" ]] && links+="https://www.marinetraffic.com/en/ais/details/ships/${VESSELS[$1:mmsi]}\n" || true
[[ -n "$BLUESKY_LINK_VESSELFINDER" ]] && links+="https://www.vesselfinder.com/vessels/details/${VESSELS[$1:mmsi]}\n" || true

post_text="🚢 #VesselAlert #Ship #Vessel #AIS"
[[ -z "${VESSELS[$1:notification:last]}" ]] && post_text+=" #NEW #FIRST"
[[ "${notify_distance}" == "true" ]] && post_text+=" #OnTheMove"
post_text+="\n\n"
[[ -n "${VESSELS[$1:shipname]}" ]] && post_text+="Name: #${VESSELS[$1:shipname]} "
[[ -n "${VESSELS[$1:mmsi]}" ]] && post_text+="MMSI: #${VESSELS[$1:mmsi]}\n"
[[ -n "${VESSELS[$1:callsign]}" ]] && post_text+="Callsign: #${VESSELS[$1:callsign]} "
[[ -n "${VESSELS[$1:shiptype]}" ]] && [[ -n "${SHIPTYPE[${VESSELS[$1:shiptype]}]}" ]] && post_text+="Type: ${SHIPTYPE[${VESSELS[$1:shiptype]}]}"
post_text+="\n\n"

[[ -n "${VESSELS[$1:country]}" ]] && post_text+="Flag: #${COUNTRY[${VESSELS[$1:country]}]} "
post_text+="Messages: ${VESSELS[$1:count]}\n"
post_text+="Last seen: $(date -d @$(( $(date +%s) - ${VESSELS[$1:last_signal]} )) +"%d-%b-%Y %H:%M:%S %Z")\n\n"

[[ -n "${VESSELS[$1:status]}" ]] && [[ -n "${SHIPSTATUS[${VESSELS[$1:status]}]}" ]] && post_text+="Status: ${SHIPSTATUS[${VESSELS[$1:status]}]}\n"
[[ -n "${VESSELS[$1:speed]}" ]] && [[ "${VESSELS[$1:speed]}" != "0" ]] && [[ "${VESSELS[$1:speed]}" != "null" ]] && post_text+="Speed: $(printf "%.1f" "${VESSELS[$1:speed]}") kts "
[[ -n "${VESSELS[$1:heading]}" ]] && [[ "${VESSELS[$1:heading]}" != "0" ]] && [[ "${VESSELS[$1:heading]}" != "null" ]]&& post_text+="Heading: ${VESSELS[$1:heading]}° "
[[ -n "${VESSELS[$1:destination]}" ]] && post_text+="\nDestination: ${VESSELS[$1:destination]}"

post_text+="\n\nSignal RSSI: $(printf "%.1f dBFS" "${VESSELS[$1:level]}")"
[[ -n "${links}" ]] && post_text+="\n\n${links}"

[[ -n "${NOTIFICATION_MAPURL}" ]] && [[ "${NOTIFICATION_MAPURL:0:4}" != "http" ]] && post_text+="\n\nLocation: ${AIS_URL}?mmsi=${VESSELS[$1:mmsi]}"
[[ -n "${NOTIFICATION_MAPURL}" ]] && [[ "${NOTIFICATION_MAPURL:0:4}" == "http" ]] && post_text+="\n\nLocation: ${NOTIFICATION_MAPURL}?mmsi=${VESSELS[$1:mmsi]}"

# Clean up the text
post_text="$(sed -e 's|\\n|\n|g' <<< "$post_text")"

# Prepare the post data
post_data="{
    \"repo\": \"$did\",
    \"collection\": \"app.bsky.feed.post\",
    \"record\": {
        \"\$type\": \"app.bsky.feed.post\",
        \"text\": \"$post_text\",
        \"createdAt\": \"$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")\"
    }
}"

# Send the post to Bluesky
response=$(curl -s -X POST "$BLUESKY_API/com.atproto.repo.createRecord" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $access_jwt" \
    -d "$post_data")

if [[ "$(echo "$response" | jq -r '.uri')" != "null" ]]; then
    echo "[$(date)][$APPNAME] Bluesky post for ${VESSELS[$1:mmsi]} (${VESSELS[$1:shipname]}) created successfully"
    
    # Update the Assoc Array with the latest values:
    VESSELS[$1:notification:lat]="${VESSELS[$1:lat]}"
    VESSELS[$1:notification:lon]="${VESSELS[$1:lon]}"
    VESSELS[$1:notification:last]="$(date +%s)"

    source /usr/share/vesselalert/save_databases
else
    echo "[$(date)][$APPNAME] Bluesky post error for ${VESSELS[$1:mmsi]} (${VESSELS[$1:shipname]}). Error: $response"
fi
@kx1t
Copy link
Member

kx1t commented Dec 17, 2024

Great idea, but wrong file. In reality, I don’t know how the vesselalert related file made its way into the repo, as it isn’t used here.

I’ll take a look at how you did this, and I’ll try adding the corresponding code at the right spots. May take me a few weeks…

@kx1t kx1t self-assigned this Dec 17, 2024
@kx1t kx1t added the enhancement New feature or request label Dec 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants