This repository has been archived by the owner on Dec 12, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
signal-daemon
executable file
·104 lines (94 loc) · 3.95 KB
/
signal-daemon
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/usr/bin/env bash
shopt -s extglob
# Starts `signal-cli` in daemon mode and creates notifications for incoming messages using
# `notify-send`. I only tested it with the [dunst(1) notification daemon][1].
#
# [1]: https://github.com/dunst-project/dunst
source "${XDG_CONFIG_HOME:-$HOME/.config}/signal/init.bash"
[[ ! $signal_cli ]] && signal_cli='signal-cli'
declare -i debug=0
# http://mywiki.wooledge.org/BashFAQ/035#getopts
# http://wiki.bash-hackers.org/howto/getopts_tutorial
while getopts ':hsd' opt; do
case $opt in
d)
(( ++debug ))
;;
esac
done
shift "$((OPTIND-1))" # Shift off the options and optional --.
start-daemon() {
"$signal_cli" -u "$user" daemon
}
notify() {
# Replace consecutive newlines with null ('\0'). The use of `fflush()` is essential.
# It forces gawk to flush stdout. Without it, gawk buffers its output. See
# <http://mywiki.wooledge.org/BashFAQ/009>.
gawk -v RS='\n\n' -v ORS='\0' '{ print; fflush(stdout) }' |
# This method (`RS=`) doesn't work with gawk, but should with Plan 9 awk:
# /opt/plan9/bin/awk -v RS= -v ORS='\0' '{ print; fflush() }' |
while IFS= read -r -d '' message; do
(( debug )) && echo "$message"$'\n'
# Remove any empty lines at the start of the message. These may exist when the
# previous messages body had a trailing empty line (or several).
message=${message##*($'\n')}
if [[ ${message%%$'\n'*} == *${user}* ]]; then
# The first line of the message contains the users phone number; i.e., it's from
# the user. Don't do anything with it.
continue
fi
# The message body extends to the end of the message or until we encounter an
# "Attachments: " or "Group info:" section.
pattern=$'*\nBody: *'
[[ $message != $pattern ]] && continue
body=${message#*$'\nBody: '}
body=${body%$'\nAttachments: \n'*}
body=${body%$'\nGroup info:\n'*}
attachment=
if [[ $message =~ $'\nAttachments: \n- ' ]]; then
file=${message##*$'\n' Stored plaintext in: }
# Check if a prefix string was removed by comparing string lengths.
if (( ${#file} != ${#message} )); then
attachment=" (file://$file)"
fi
fi
timestamp=${message##*$'\n'Message timestamp: }
# The (Unix time) timestamps used have 13 digits. The last 3 are milliseconds.
timestamp=${timestamp:0:13}
# The format `date` expects is '@1234567890.123'.
timestamp=$(date -d "@${timestamp:0:10}.${timestamp:11}" '+%H:%M')
# Remove a single trailing space if there is one.
body=${body/% }
# Remove `”` and everything following it.
sender=${message%%”*}
if [[ $sender != "$message" ]]; then
# It worked: some substring was removed by the parameter expansion. TODO: is
# there a better way to check this?
sender=${sender#Envelope from: “}
else
# The message didn't contain a name: use the phone number.
sender=${sender#Envelope from: }
# Remove everything following the first space character.
sender=${sender%% *}
fi
[[ ! $sender ]] && continue
group_name=
pattern=$'*\nGroup info:\n Id: *\n Name: '
if [[ $message == $pattern* ]]; then
group_name=${message##$pattern}
group_name=${group_name%%$'\n'*}
fi
notification="<b>$timestamp</b> ${sender}"
notification+="${group_name:+ ($group_name)}:${body:+ $body}$attachment"
if [[ $group_name ]]; then
notify-send -a 'signal-cli' -u low "$notification"
else
notify-send -a 'signal-cli' -h 'string:bgcolor:#d70087' "$notification"
fi
done
}
# If there are more positional parameters, assume they name test input files and pipe
# their contents into `notify`. Normally, start `signal-cli` in daemon mode and pipe its
# output into `notify`.
if [[ $1 ]]; then cat "$@" -; else start-daemon; fi | notify
# vim: tw=90 sts=-1 sw=3 et