forked from indymedia/epicyon
				
			
		
			
				
	
	
		
			277 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
			
		
		
	
	
			277 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
#!/bin/bash
 | 
						|
#
 | 
						|
# This can be called from a crontab entry to send notifications
 | 
						|
# when Epicyon events occur. You will need to have
 | 
						|
# sendxmpp+prosody or Synapse (matrix) installed.
 | 
						|
#
 | 
						|
# Something like:
 | 
						|
#
 | 
						|
# */1 * * * * root /usr/local/bin/epicyon-notification --epicyon yes
 | 
						|
#
 | 
						|
# License
 | 
						|
# =======
 | 
						|
#
 | 
						|
# Copyright (C) 2020 Bob Mottram <bob@freedombone.net>
 | 
						|
#
 | 
						|
# This program is free software: you can redistribute it and/or modify
 | 
						|
# it under the terms of the GNU Affero General Public License as published by
 | 
						|
# the Free Software Foundation, either version 3 of the License, or
 | 
						|
# (at your option) any later version.
 | 
						|
#
 | 
						|
# This program is distributed in the hope that it will be useful,
 | 
						|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
# GNU Affero General Public License for more details.
 | 
						|
#
 | 
						|
# You should have received a copy of the GNU Affero General Public License
 | 
						|
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
						|
 | 
						|
PROJECT_NAME=epicyon
 | 
						|
epicyonInstallDir=/opt/${PROJECT_NAME}
 | 
						|
 | 
						|
local_domain=$HOSTNAME
 | 
						|
if [ -f /var/lib/tor/hidden_service_epicyon/hostname ]; then
 | 
						|
    local_domain=$(cat /var/lib/tor/hidden_service_epicyon/hostname)
 | 
						|
fi
 | 
						|
 | 
						|
 | 
						|
function notification_translate_text {
 | 
						|
    text="$1"
 | 
						|
    if ! grep -q '"language":' "${epicyonInstallDir}/config.json"; then
 | 
						|
	echo "$text"
 | 
						|
	return
 | 
						|
    fi
 | 
						|
    language=$(cat "${epicyonInstallDir}/config.json" | awk -F '"language":' '{print $2}' | awk -F '"' '{print $2}')
 | 
						|
    translationsFilename="${epicyonInstallDir}/translations/${language}.json"
 | 
						|
    if [ ! -f "$translationsFilename" ]; then
 | 
						|
	echo "$text"
 | 
						|
	return
 | 
						|
    fi
 | 
						|
    if ! grep -q "\"$text\":" "$translationsFilename"; then
 | 
						|
	echo "$text"
 | 
						|
	return
 | 
						|
    fi
 | 
						|
    grep "\"$text\":" "$translationsFilename" | awk -F '"' '{print $4}'
 | 
						|
}
 | 
						|
 | 
						|
function kill_sendxmpp_process {
 | 
						|
    # Sometimes the process can get stuck, so ensure that
 | 
						|
    # it gets killed if necessary
 | 
						|
    # shellcheck disable=SC2009
 | 
						|
    sendxmpp_pid=$(ps ax | grep /usr/bin/sendxmpp | grep -v grep | awk -F ' ' '{print $1}')
 | 
						|
    if [ "$sendxmpp_pid" ]; then
 | 
						|
        kill -9 "$sendxmpp_pid"
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
function matrix_server_message {
 | 
						|
    admin_username="$1"
 | 
						|
    notifications_username="$2"
 | 
						|
    message="$3"
 | 
						|
 | 
						|
    MATRIX_DATA_DIR='/var/lib/matrix'
 | 
						|
    homeserver_config="${MATRIX_DATA_DIR}/homeserver.yaml"
 | 
						|
    
 | 
						|
    # shellcheck disable=SC2002
 | 
						|
    MATRIX_DOMAIN_NAME=$(cat "$homeserver_config" | grep "server_name:" | head -n 1 | awk -F '"' '{print $2}')
 | 
						|
    if [ ! "$MATRIX_DOMAIN_NAME" ]; then
 | 
						|
        return
 | 
						|
    fi
 | 
						|
 | 
						|
    # get the curl command and domain to send to
 | 
						|
    curl_command='curl'
 | 
						|
    homebase="https://$MATRIX_DOMAIN_NAME"
 | 
						|
    if [ -f /var/lib/tor/hidden_service_matrix/hostname ]; then
 | 
						|
        curl_command='torsocks curl'
 | 
						|
        homebase="http://$(cat /var/lib/tor/hidden_service_matrix/hostname)"
 | 
						|
    fi
 | 
						|
 | 
						|
    # get the token for the matrix admin user
 | 
						|
    MATRIXADMIN="@${admin_username}:$MATRIX_DOMAIN_NAME"
 | 
						|
    MATRIXUSER="@${notifications_username}:$MATRIX_DOMAIN_NAME"
 | 
						|
    cd "$MATRIX_DATA_DIR" || return
 | 
						|
    TOKEN=$(sqlite3 homeserver.db "select token from access_tokens where user_id like '$MATRIXADMIN' order by id desc limit 1;")
 | 
						|
    if [ ! "$TOKEN" ]; then
 | 
						|
        admin_username="${notifications_username}"
 | 
						|
        TOKEN=$(sqlite3 homeserver.db "select token from access_tokens where user_id like '$MATRIXUSER' order by id desc limit 1;")
 | 
						|
        if [ ! "$TOKEN" ]; then
 | 
						|
            echo "No matrix token for $MATRIXADMIN"
 | 
						|
            return
 | 
						|
        fi
 | 
						|
    fi
 | 
						|
    # send server notice
 | 
						|
    MATRIXPOST="${homebase}/_synapse/admin/v1/send_server_notice?access_token=${TOKEN}"
 | 
						|
    MATRIXMESSAGE="{\"user_id\": \"${MATRIXUSER}\",\"content\": { \"msgtype\": \"m.text\",\"body\": \"${message}\" }}"
 | 
						|
    # shellcheck disable=SC2086
 | 
						|
    ${curl_command} --request POST --silent --header "Content-Type: application/json" --data "${MATRIXMESSAGE}" ${MATRIXPOST} > /dev/null
 | 
						|
}
 | 
						|
 | 
						|
function sendNotification {
 | 
						|
    USERNAME="$1"
 | 
						|
    SUBJECT="$2"
 | 
						|
    MESSAGE="$3"
 | 
						|
    
 | 
						|
    if [ -d /etc/prosody ]; then
 | 
						|
        if [ -f /usr/bin/sendxmpp ]; then
 | 
						|
            notification_user_password=$(openssl rand -base64 32 | tr -dc A-Za-z0-9 | head -c 30 ; echo -n '')
 | 
						|
            if prosodyctl register "notification" "$local_domain" "$notification_user_password"; then
 | 
						|
                if [[ "$SUBJECT" == *' Tor '* ]]; then
 | 
						|
                    MESSAGE="$SUBJECT"
 | 
						|
                fi
 | 
						|
 | 
						|
                if [ -f /usr/bin/sendxmpp ]; then
 | 
						|
                    kill_sendxmpp_process
 | 
						|
                    echo "${MESSAGE}" | /usr/bin/sendxmpp -u notification -p "${notification_user_password}" -j localhost -o ${local_domain} --message-type=headline -n -t -s ${PROJECT_NAME} ${USERNAME}@${local_domain}
 | 
						|
                fi
 | 
						|
            fi
 | 
						|
            prosodyctl deluser "notification@$local_domain"
 | 
						|
        fi
 | 
						|
    fi
 | 
						|
 | 
						|
    if [ -d /etc/matrix ]; then
 | 
						|
        matrix_server_message "${USERNAME}" "${USERNAME}" "$MESSAGE"
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
function notifications {
 | 
						|
    # checks if DMs or replies have arrived and sends notifications to users
 | 
						|
    if [ ! -f "$epicyonInstallDir/config.json" ]; then
 | 
						|
        return
 | 
						|
    fi
 | 
						|
 | 
						|
    if [ ! -f "${epicyonInstallDir}/config.json" ]; then
 | 
						|
	return
 | 
						|
    fi
 | 
						|
 | 
						|
    # shellcheck disable=SC2002
 | 
						|
    EPICYON_DOMAIN_NAME=$(cat "${epicyonInstallDir}/config.json" | awk -F '"domain":' '{print $2}' | awk -F '"' '{print $2}')
 | 
						|
    for d in ${epicyonInstallDir}/accounts/*/ ; do
 | 
						|
	if [[ "$d" != *'@'* ]]; then
 | 
						|
	    continue
 | 
						|
	fi
 | 
						|
	epicyonDir="${d::-1}"
 | 
						|
	USERNAME=$(echo "$epicyonDir" | awk -F '/' '{print $5}' | awk -F '@' '{print $1}')
 | 
						|
 | 
						|
        # send notifications for calendar events to XMPP/email users
 | 
						|
        epicyonCalendarfile="$epicyonDir/.newCalendar"
 | 
						|
        if [ -f "$epicyonCalendarfile" ]; then
 | 
						|
            if ! grep -q "##sent##" "$epicyonCalendarfile"; then
 | 
						|
                epicyonCalendarmessage=$(notification_translate_text 'New calendar event')
 | 
						|
                epicyonCalendarfileContent=$(echo "$epicyonCalendarmessage")" "$(cat "$epicyonCalendarfile")
 | 
						|
                if [[ "$epicyonCalendarfileContent" == '/calendar'* ]]; then
 | 
						|
                    epicyonCalendarmessage="Epicyon: ${EPICYON_DOMAIN_NAME}/users/${USERNAME}${epicyonCalendarfileContent}"
 | 
						|
                fi
 | 
						|
		sendNotification "$USERNAME" "Epicyon" "$epicyonCalendarmessage"
 | 
						|
                echo "##sent##" >> "$epicyonCalendarfile"
 | 
						|
                chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonCalendarfile"
 | 
						|
            fi
 | 
						|
        fi
 | 
						|
 | 
						|
        # send notifications for DMs to XMPP/email users
 | 
						|
        epicyonDMfile="$epicyonDir/.newDM"
 | 
						|
        if [ -f "$epicyonDMfile" ]; then
 | 
						|
            if ! grep -q "##sent##" "$epicyonDMfile"; then
 | 
						|
                epicyonDMmessage=$(notification_translate_text 'New direct message')
 | 
						|
                epicyonDMfileContent=$(echo "$epicyonDMmessage")" "$(cat "$epicyonDMfile")
 | 
						|
                if [[ "$epicyonDMfileContent" == *':'* ]]; then
 | 
						|
                    epicyonDMmessage="Epicyon: $epicyonDMfileContent"
 | 
						|
                fi
 | 
						|
		sendNotification "$USERNAME" "Epicyon" "$epicyonDMmessage"
 | 
						|
                echo "##sent##" > "$epicyonDMfile"
 | 
						|
                chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonDMfile"
 | 
						|
            fi
 | 
						|
        fi
 | 
						|
 | 
						|
        # send notifications for likes to XMPP/email users
 | 
						|
        epicyonLikeFile="$epicyonDir/.newLike"
 | 
						|
        if [ -f "$epicyonLikeFile" ]; then
 | 
						|
            if ! grep -q "##sent##" "$epicyonLikeFile"; then
 | 
						|
                epicyonLikeMessage=$(notification_translate_text 'liked your post')
 | 
						|
                epicyonLikeFileContent=$(cat "$epicyonLikeFile" | awk -F ' ' '{print $1}')" "$(echo "$epicyonLikeMessage")" "$(cat "$epicyonLikeFile" | awk -F ' ' '{print $2}')
 | 
						|
                if [[ "$epicyonLikeFileContent" == *':'* ]]; then
 | 
						|
                    epicyonLikeMessage="Epicyon: $epicyonLikeFileContent"
 | 
						|
                fi
 | 
						|
                "${PROJECT_NAME}-notification" -u "$USERNAME" -s "Epicyon" -m "$epicyonLikeMessage" --sensitive yes
 | 
						|
                echo "##sent##" > "$epicyonLikeFile"
 | 
						|
                chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonLkeFile"
 | 
						|
            fi
 | 
						|
        fi
 | 
						|
 | 
						|
        # send notifications for replies to XMPP/email users
 | 
						|
        epicyonReplyFile="$epicyonDir/.newReply"
 | 
						|
        if [ -f "$epicyonReplyFile" ]; then
 | 
						|
            if ! grep -q "##sent##" "$epicyonReplyFile"; then
 | 
						|
                epicyonReplyMessage=$(notification_translate_text 'New reply')
 | 
						|
                epicyonReplyFileContent=$(echo "$epicyonReplyMessage")" "$(cat "$epicyonReplyFile")
 | 
						|
                if [[ "$epicyonReplyFileContent" == *':'* ]]; then
 | 
						|
                    epicyonReplyMessage="Epicyon: $epicyonReplyFileContent"
 | 
						|
                fi
 | 
						|
		sendNotification "$USERNAME" "Epicyon" "$epicyonReplyMessage"
 | 
						|
                echo "##sent##" > "$epicyonReplyFile"
 | 
						|
                chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonReplyFile"
 | 
						|
            fi
 | 
						|
        fi
 | 
						|
 | 
						|
        # send notifications for git patches to XMPP/email users
 | 
						|
        epicyonPatchFile="$epicyonDir/.newPatch"
 | 
						|
        if [ -f "$epicyonPatchFile" ]; then
 | 
						|
            if [ -f "${epicyonPatchFile}Content" ]; then
 | 
						|
		if ! grep -q "##sent##" "$epicyonPatchFile"; then
 | 
						|
		    epicyonPatchMessage=$(cat "$epicyonPatchFile")
 | 
						|
		    if [ "$epicyonPatchMessage" ]; then
 | 
						|
			# notify the member
 | 
						|
			sendNotification "$USERNAME" "Epicyon" "$epicyonPatchMessage"
 | 
						|
			echo "##sent##" > "$epicyonPatchFile"
 | 
						|
			chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonPatchFile"
 | 
						|
			# send the patch to them by email
 | 
						|
			cat "${epicyonPatchFile}Content" | mail -s "[Epicyon] $epicyonPatchMessage" "${USERNAME}@${HOSTNAME}"
 | 
						|
			rm "${epicyonPatchFile}Content"
 | 
						|
		    fi
 | 
						|
		fi
 | 
						|
            fi
 | 
						|
        fi
 | 
						|
 | 
						|
        # send notifications for new shared items to XMPP/email users
 | 
						|
        epicyonShareFile="$epicyonDir/.newShare"
 | 
						|
        if [ -f "$epicyonShareFile" ]; then
 | 
						|
            if ! grep -q "##sent##" "$epicyonShareFile"; then
 | 
						|
                epicyonShareMessage=$(notification_translate_text 'New shared item')
 | 
						|
                epicyonShareFileContent=$(echo "$epicyonShareMessage")" "$(cat "$epicyonShareFile")
 | 
						|
                if [[ "$epicyonShareFileContent" == *':'* ]]; then
 | 
						|
                    epicyonShareMessage="Epicyon: $epicyonShareFileContent"
 | 
						|
                fi
 | 
						|
		sendNotification "$USERNAME" "Epicyon" "$epicyonShareMessage"
 | 
						|
                echo "##sent##" > "$epicyonShareFile"
 | 
						|
                chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonShareFile"
 | 
						|
            fi
 | 
						|
        fi
 | 
						|
 | 
						|
        # send notifications for follow requests to XMPP/email users
 | 
						|
        epicyonFollowFile="$epicyonDir/followrequests.txt"
 | 
						|
        epicyonFollowNotificationsFile="$epicyonDir/follownotifications.txt"
 | 
						|
        if [ -f "$epicyonFollowFile" ]; then
 | 
						|
            if [ -s "$epicyonFollowFile" ]; then
 | 
						|
                epicyonNotify=
 | 
						|
                if [ -f "$epicyonFollowNotificationsFile" ]; then
 | 
						|
                    hash1=$(sha256sum "$epicyonFollowFile" | awk -F ' ' '{print $1}')
 | 
						|
                    hash2=$(sha256sum "$epicyonFollowNotificationsFile" | awk -F ' ' '{print $1}')
 | 
						|
                    if [[ "$hash1" != "$hash2" ]]; then
 | 
						|
                        epicyonNotify=1
 | 
						|
                    fi
 | 
						|
                else
 | 
						|
                    epicyonNotify=1
 | 
						|
                fi
 | 
						|
                if [ $epicyonNotify ]; then
 | 
						|
                    cp "$epicyonFollowFile" "$epicyonFollowNotificationsFile"
 | 
						|
                    chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonFollowNotificationsFile"
 | 
						|
                    
 | 
						|
                    epicyonFollowMessage=$(notification_translate_text "New follow request")" ${EPICYON_DOMAIN_NAME}/users/${USERNAME}/followers"
 | 
						|
		    sendNotification "$USERNAME" "Epicyon" "$epicyonFollowMessage"
 | 
						|
                fi
 | 
						|
            fi
 | 
						|
        fi
 | 
						|
    done    
 | 
						|
}
 | 
						|
 | 
						|
notifications
 |