├── README.md └── term-mail /README.md: -------------------------------------------------------------------------------- 1 | # shell-email 2 | `GET EMAILS DIRECTLY TO YOUR TERMINAL TO A TEMPORARY EMAIL ` 3 | 4 | ## Installing Dependencies 5 | - `sudo apt install w3m` 6 | - `sudo apt install curl` 7 | - `sudo apt install jq` 8 | 9 | ## Usage 10 | ```console 11 | $ shell-mail 12 | -g, --generate [ADDRESS] 13 | Generate a new email address, either the specified ADDRESS, or 14 | randomly create one 15 | 16 | -r, --recent 17 | View the most recent email message 18 | -t, --text 19 | View the email as raw text, where all the HTML tags are removed. 20 | Without this option, HTML is used. 21 | --version 22 | Show version 23 | ``` 24 | 25 | ### Examples 26 | Create random email 27 | ```console 28 | $ shell-mail --generate 29 | xoithrjagpx@1secmail.net 30 | ``` 31 | -------------------------------------------------------------------------------- /term-mail: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # 3 | # 4 | # 5 | # Dependencies: jq, curl, w3m 6 | # 7 | 8 | 9 | 10 | # By default 'tmpmail' uses 'w3m' as it's web browser to render 11 | # the HTML of the email 12 | browser="w3m" 13 | 14 | # If the value is set to 'true' tmpmail will convert the HTML email 15 | # to raw text and send that to stdout 16 | raw_text=false 17 | 18 | # Everything related to 'tmpmail' will be stored in /tmp/tmpmail 19 | # so that the old emails and email addresses get cleared after 20 | # restarting the computer 21 | tmpmail_dir="/tmp/tmpmail" 22 | 23 | # tmpmail_email_address is where we store the temporary email address 24 | # that gets generated. This prevents the user from providing 25 | # the email address everytime they run tmpmail 26 | tmpmail_email_address="$tmpmail_dir/email_address" 27 | 28 | # tmpmail.html is where the email gets stored. 29 | # Even though the file ends with a .html extension, the raw text version of 30 | # the email will also be stored in this file so that w3m and other browsers 31 | # are able to open this file 32 | tmpmail_html_email="$tmpmail_dir/tmpmail.html" 33 | 34 | # Default 1secmail API URL 35 | tmpmail_api_url="https://www.1secmail.com/api/v1/" 36 | 37 | usage() { 38 | # Using 'cat << EOF' we can easily output a multiline text. This is much 39 | # better than using 'echo' for each line or using '\n' to create a new line. 40 | cat <"$tmpmail_email_address" 131 | 132 | # If this function was called because the user wanted to generate a new 133 | # email address, show them the email address 134 | [ "$externally" = true ] && cat "$tmpmail_email_address" && printf "\n" 135 | } 136 | 137 | get_email_address() { 138 | # This function is only called once and that is when this script 139 | # get executed. The output of this function gets stored in $email_address 140 | # 141 | # If the file that contains the email address is empty, 142 | # that means we do not have an email address, so generate one. 143 | [ ! -s "$tmpmail_email_address" ] && generate_email_address 144 | 145 | # Output the email address by getting the first line of $tmpmail_email 146 | head -n 1 "$tmpmail_email_address" 147 | } 148 | 149 | list_emails() { 150 | # List all the received emails in a nicely formatted order 151 | # 152 | # Fetch the email data using 1secmail's API 153 | data=$(curl -sL "$tmpmail_api_url?action=getMessages&login=$username&domain=$domain") 154 | 155 | # Using 'jq' we get the length of the JSON data. From this we can determine whether or not 156 | # the email address has gotten any emails 157 | data_length=$(printf %s "$data" | jq length) 158 | 159 | # We are showing what email address is currently being used 160 | # in case the user has forgotten what the email address was. 161 | printf "[ Inbox for %s ]\n\n" "$email_address" 162 | 163 | # If the length of the data we got is 0, that means the email address 164 | # has not received any emails yet. 165 | [ "$data_length" -eq 0 ] && echo "No new mail" && exit 166 | 167 | # This is where we store all of our emails, which is then 168 | # displayed using 'column' 169 | inbox="" 170 | 171 | # Go through each mail that has been received 172 | index=1 173 | while [ $index -le "${data_length}" ]; do 174 | # Since arrays in JSON data start at 0, we must subtract 175 | # the value of $index by 1 so that we dont miss one of the 176 | # emails in the array 177 | mail_data=$(printf %s "$data" | jq -r ".[$index-1]") 178 | id=$(printf %s "$mail_data" | jq -r ".id") 179 | from=$(printf %s "$mail_data" | jq -r ".from") 180 | subject=$(printf %s "$mail_data" | jq -r ".subject") 181 | 182 | # The '||' are used as a divideder for 'column'. 'column' will use this divider as 183 | # a point of reference to create the division. By default 'column' uses a blank space 184 | # but that would not work in our case as the email subject could have multiple white spaces 185 | # and 'column' would split the words that are seperated by white space, in different columns. 186 | inbox="$inbox$id ||$from ||$subject\n" 187 | index=$((index + 1)) 188 | done 189 | 190 | # Show the emails cleanly 191 | printf "%b" "$inbox" | column -t -s "||" 192 | } 193 | 194 | randomize() { 195 | # We could use 'shuf' and 'sort -R' but they are not a part of POSIX 196 | awk 'BEGIN {srand();} {print rand(), $0}' | \ 197 | sort -n -k1 | cut -d' ' -f2 198 | } 199 | 200 | view_email() { 201 | # View an email by providing it's ID 202 | # 203 | # The first argument provided to this function will be the ID of the email 204 | # that has been received 205 | email_id="$1" 206 | data=$(curl -sL "$tmpmail_api_url?action=readMessage&login=$username&domain=$domain&id=$email_id") 207 | 208 | # After the data is retrieved using the API, we have to check if we got any emails. 209 | # Luckily 1secmail's API is not complicated and returns 'Message not found' as plain text 210 | # if our email address as not received any emails. 211 | # If we received the error message from the API just quit because there is nothing to do 212 | [ "$data" = "Message not found" ] && print_error "Message not found" 213 | 214 | # We pass the $data to 'jq' which extracts the values 215 | from=$(printf %s "$data" | jq -r ".from") 216 | subject=$(printf %s "$data" | jq -r ".subject") 217 | html_body=$(printf %s "$data" | jq -r ".htmlBody") 218 | attachments=$(printf %s "$data" | jq -r ".attachments | length") 219 | 220 | # If you get an email that is in pure text, the .htmlBody field will be empty and 221 | # we will need to get the content from .textBody instead 222 | [ -z "$html_body" ] && html_body="
$(printf %s "$data" | jq -r ".textBody")
" 223 | 224 | # Create the HTML with all the information that is relevant and then 225 | # assigning that HTML to the variable html_mail. This is the best method 226 | # to create a multiline variable 227 | html_mail=$(cat <To: $email_address 229 | From: $from 230 | Subject: $subject 231 | $html_body 232 | 233 | EOF 234 | ) 235 | 236 | if [ ! "$attachments" = "0" ]; then 237 | html_mail="$html_mail
[Attachments]
" 238 | 239 | index=1 240 | while [ "$index" -le "$attachments" ]; do 241 | filename=$(printf %s "$data" | jq -r ".attachments | .[$index-1] | .filename") 242 | link="$tmpmail_api_url?action=download&login=$username&domain=$domain&id=$email_id&file=$filename" 243 | html_link="$filename
" 244 | 245 | if [ "$raw_text" = true ]; then 246 | # The actual url is way too long and does not look so nice in STDOUT. 247 | # Therefore we will shortening it using is.gd so that it looks nicer. 248 | link=$(curl -s -F"url=$link" "https://is.gd/create.php?format=simple") 249 | html_mail="$html_mail$link [$filename]
" 250 | else 251 | html_mail="$html_mail$html_link" 252 | fi 253 | 254 | index=$((index + 1)) 255 | done 256 | fi 257 | 258 | # Save the $html_mail into $tmpmail_html_email 259 | printf %s "$html_mail" >"$tmpmail_html_email" 260 | 261 | # If the '--text' flag is used, then use 'w3m' to convert the HTML of 262 | # the email to pure text by removing all the HTML tags 263 | [ "$raw_text" = true ] && w3m -dump "$tmpmail_html_email" && exit 264 | 265 | # Open up the HTML file using $browser. By default, 266 | # this will be 'w3m'. 267 | $browser "$tmpmail_html_email" 268 | } 269 | 270 | 271 | view_recent_email() { 272 | # View the most recent email. 273 | # 274 | # This is done by listing all the received email like you 275 | # normally see on the terminal when running 'tmpmail'. 276 | # We then grab the ID of the most recent 277 | # email, which the first line. 278 | mail_id=$(list_emails | head -3 | tail -1 | cut -d' ' -f 1) 279 | view_email "$mail_id" 280 | } 281 | 282 | print_error() { 283 | # Print error message 284 | # 285 | # The first argument provided to this function will be the error message. 286 | # Script will exit after printing the error message. 287 | printf "%b\n" "Error: $1" >&2 288 | exit 1 289 | } 290 | 291 | main() { 292 | # Iterate of the array of dependencies and check if the user has them installed. 293 | # We are checking if $browser is installed instead of checking for 'w3m'. By doing 294 | # this, it allows the user to not have to install 'w3m' if they are using another 295 | # browser to view the HTML 296 | for dependency in jq $browser curl; do 297 | if ! command -v "$dependency" >/dev/null 2>&1; then 298 | print_error "Could not find '$dependency', is it installed?" 299 | fi 300 | done 301 | 302 | # Create the $tmpmail_dir directory and dont throw any errors 303 | # if it already exists 304 | mkdir -p "$tmpmail_dir" 305 | 306 | # Get the email address and save the value to the email_address variable 307 | email_address="$(get_email_address)" 308 | 309 | # ${VAR#PATTERN} Removes shortest match of pattern from start of a string. 310 | # In this case, it takes the email_address and removed everything after 311 | # the '@' symbol which gives us the username. 312 | username=${email_address%@*} 313 | 314 | # ${VAR%PATTERN} Remove shortest match of pattern from end of a string. 315 | # In this case, it takes the email_address and removes everything until the 316 | # period '.' which gives us the domain 317 | domain=${email_address#*@} 318 | 319 | # If no arguments are provided just the emails 320 | [ $# -eq 0 ] && list_emails && exit 321 | 322 | while [ "$1" ]; do 323 | case "$1" in 324 | --help | -h) usage && exit ;; 325 | --generate | -g) generate_email_address true "$2" && exit ;; 326 | --browser | -b) browser="$2" ;; 327 | --text | -t) raw_text=true ;; 328 | --version) echo "$version" && exit ;; 329 | --recent | -r) view_recent_email && exit ;; 330 | *[0-9]*) 331 | # If the user provides number as an argument, 332 | # assume its the ID of an email and try getting 333 | # the email that belongs to the ID 334 | view_email "$1" && exit 335 | ;; 336 | -*) print_error "option '$1' does not exist" ;; 337 | esac 338 | shift 339 | done 340 | } 341 | 342 | main "$@" 343 | --------------------------------------------------------------------------------