-
-
Notifications
You must be signed in to change notification settings - Fork 44
/
tmpsms
executable file
·216 lines (177 loc) · 8.27 KB
/
tmpsms
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#!/usr/bin/env sh
#
# by Siddharth Dushantha
#
VERSION="1.0.0"
# Everything related to 'tmpsms' will be stored in this directory. Once the
# computer get restarted, this directory gets deleted.
TMPSMS_DIR="/tmp/tmpsms"
# The phone number that the user has selected gets stored in this file so that
# the do not have reselect at ever run.
TMPSMS_PHONE_NUMBER="$TMPSMS_DIR/phonenumber.txt"
# 'fzf' is used to allow the user to select a phone number. This variable
# stores extra arguments which the user might to provide, so that 'fzf'
# behaves to their liking.
FZF_ARGUMENTS=""
# The temporary SMS service is provided by Upmasked
API="https://upmasked.com"
usage(){
# Using 'cat << EOF' we can easily output a multiline text. This is much
# better than using 'echo' for each line or using '\n' to create a new line.
cat <<EOF
tmpsms [--count <count>]
tmpsms init [--fzf <arguments>]
tmpsms -h | --version
When called with no options or commands, tmpsms lists
the 3 newest messages.
Options
-h, --help Show this help message
-c, --count Only show the <count> newest messages
--version Show version
Commands
init Initialize a new phone number by selecting one
from the available ones using 'fzf'
--fzf Extra arguments to use for 'fzf'
EOF
}
print_error(){
# Print error message
#
# The first argument provided to this function will be the error message.
# Script will exit after printing the error message.
printf "%s\n" "Error: $1" >&2
exit 1
}
select_phone_number(){
# There are 2 ways which this function is called in this script.
# [1] The user wants to initilize a new phone number by running 'tmpsms init'
# [2] The user runs 'tmpsms' to check for new messages, but $TMPSMS_PHONE_NUMBER
# does't exist. Therefore they have to select phone number before we can
# show them the messages.
#
# When the function 'select_phone_number()' is called with the argument 'true'
# that means this function was called becaues the user ran 'tmpsms init'
#
# We need this variable so we can know whether or not we need to show the user
# the phone number they have selected. If they ran 'tmpsms init', then we will
# show them the phone number they selected. This is so that they can easily
# copy and paste it to whatever site that needs the phone number.
EXTERNALLY=${1:-false}
# Fetch the available phone numbers
DATA=$(curl -s "$API/api/sms/numbers")
# Using 'jq' we are able to get the length of the JSON data retreived from
# API. The length indicates the the total number of phone numbers available.
DATA_LENGTH=$(printf %s "$DATA" | jq length)
# This is where we store the phone numbers which then gets shown to the user
# through 'fzf' so that they can select one.
PHONE_NUMBERS=""
index=1
while [ $index -le "$DATA_LENGTH" ]; do
# Since arrays in JSON data start at 0, we must subtract
# the value of $index by 1 so that we dont miss one of the
# phone numbers in the array
PHONE_NUMBER_INFO=$(printf %s "$DATA" | jq -r ".[$index-1]")
PHONE_NUMBER=$(printf %s "$PHONE_NUMBER_INFO" | jq -r ".number")
COUNTRY_CODE=$(printf %s "$PHONE_NUMBER_INFO" | jq -r ".country")
PHONE_NUMBERS="$PHONE_NUMBERS$COUNTRY_CODE +$PHONE_NUMBER\n"
index=$((index+1))
done
# By default we use 'fzf' without any arguments in order to display the
# phone numbers they can use. If the '--fzf' argument is passed along with
# 'fzf' arguments, 'tmpsms' will make sure to use them.
FZF_COMMAND="fzf"
[ -n "$FZF_ARGUMENTS" ] && FZF_COMMAND="fzf $FZF_ARGUMENTS"
# If the user did not select a phone number then quit 'tmpsms' as the
# user might have just wanted to check if there were any new number
# that they could use.
SELECTION=$(printf %b "$PHONE_NUMBERS" | $FZF_COMMAND)
[ -z "$SELECTION" ] && print_error "Phone number was not selected"
# Store the selected phone number in $TMPSMS_PHONE_NUMBER for later use
printf %s "$SELECTION" > "$TMPSMS_PHONE_NUMBER"
# If the user ran 'tmpsms init', then show them their selection
[ "$EXTERNALLY" = true ] && printf "%s\n" "$SELECTION"
}
list_messages(){
# By default, the 3 newest messages are shown. But if the user would like
# to see more of the messages, they can provide how many they want to see
# by using the '--count' option.
COUNT="${1:-3}"
# The provided value to '--count' must be an interger. We can verify that it is
# an integer by checking if $COUNT matches the regex.
REGEX='^[0-9]+$'
if ! printf %s "$COUNT" | grep -Eq "$REGEX";then
print_error "'$COUNT' is not an integer"
fi
# If /tmp/tmpsms/phonenumber.txt does not exist or is empty that means that
# the user has not initialized a phone number yet.
[ ! -s "$TMPSMS_PHONE_NUMBER" ] && print_error "A phone number must be initilzied in order to view the messages"
# The country code is needed because it gets displayed to the user. It may
# be useful for the user to know which country the phone number is from
# so that they dont have to guess by looking at the area code.
COUNTRY_CODE=$(awk -F" " '{print $1}' < $TMPSMS_PHONE_NUMBER)
PHONE_NUMBER=$(awk -F"+" '{print $2}' < $TMPSMS_PHONE_NUMBER)
DATA=$(curl -s "$API/api/sms/messages/$PHONE_NUMBER")
# Even though we are using the phone numbers that are available on
# upmasked.com, there is a chance that they might remove one of the numbers.
# The checking needs to be done in case the phone number that is stored in
# $TMPSMS_PHONE_NUMBER has been removed.
if printf %s "$DATA" | grep -Eq "Not Found"; then
print_error "Looks like the phone number '+$PHONE_NUMBER' no longer exists. Initialize a new one and try again."
fi
DATA_LENGTH=$(printf %s "$DATA" | jq length)
# If the number of messages the user wants to view is greater than the
# number of messages that are available, then make sure to show
# all the messages that are available.
[ "$COUNT" -gt "$DATA_LENGTH" ] && COUNT="$DATA_LENGTH"
# Show a nice little header before showing the messages
printf "%s\n\n" "[ Messages for +$PHONE_NUMBER ($COUNTRY_CODE) ]"
# All the messages get stored in here
MESSAGES=""
index=1
while [ $index -le "$COUNT" ]; do
# Since arrays in JSON data start at 0, we must subtract
# the value of $index by 1 so that we dont miss one of the
# messages in the array
MESSAGE_DATA=$(printf %s "$DATA" | jq -r ".[$index-1]")
BODY=$(printf %s "$MESSAGE_DATA" | jq -r ".body" | tr "\n" " ")
SENDER=$(printf %s "$MESSAGE_DATA" | jq -r ".originator")
# The '||' is used as a divider for 'column'. 'column' will use this
# divider as a point of reference to create the division. By default
# 'column' uses a blank space but that would not work in our case as the
# message could have multiple white spaces and 'column' would
# split the words that are seperated by white space, in different columns.
MESSAGES="$MESSAGES$SENDER ||$BODY\n"
index=$((index+1))
done
# Show the messages cleanly
printf "%b" "$MESSAGES" | column -t -s "||"
}
main(){
# Iterate the array of dependencies and check if the user has them installed.
for dependency in jq curl fzf; do
if ! command -v "$dependency" >/dev/null 2>&1; then
print_error "Could not find '$dependency', is it installed?"
fi
done
# Create the $TMPSMS_DIR directory and dont throw any errors
# if it already exists
mkdir -p "$TMPSMS_DIR"
# If no arguments are provided just show the messages
[ $# -eq 0 ] && list_messages && exit 0
while [ "$1" ]; do
case "$1" in
init)
case "$2" in
--fzf) FZF_ARGUMENTS="$3" && select_phone_number true ;;
"") select_phone_number true ;;
esac ;;
--help | -h) usage && exit ;;
--count | -c) list_messages "$2" && shift 2;;
--version) printf %s "$VERSION" && exit ;;
-*) print_error "option '$1' does not exist" ;;
*) print_error "command '$1' does not exist" ;;
esac
shift
done
}
main "$@"