├── .github └── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_suggestion.yml ├── LICENSE ├── README.md └── Workflow ├── icon.png ├── images └── about │ └── tmpmail.png ├── info.plist └── notificator /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: File a bug report 3 | body: 4 | - type: input 5 | attributes: 6 | label: Workflow version 7 | description: Open the Workflow in Alfred Preferences and find it at the top, near the description 8 | validations: 9 | required: true 10 | - type: input 11 | attributes: 12 | label: Alfred version 13 | description: In the top left corner of Alfred Preferences → General 14 | validations: 15 | required: true 16 | - type: input 17 | attributes: 18 | label: macOS version 19 | description: Click  on the menubar → About This Mac 20 | validations: 21 | required: true 22 | - type: textarea 23 | attributes: 24 | label: Debugger output 25 | description: Perform the failing action with [the debugger](https://www.alfredapp.com/help/workflows/advanced/debugger/) open 26 | render: alfred_debugger 27 | validations: 28 | required: true 29 | - type: textarea 30 | attributes: 31 | label: More details 32 | description: Explain what you did, what happened, and what you expected to happen 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_suggestion.yml: -------------------------------------------------------------------------------- 1 | name: Feature Suggestion 2 | description: Suggest a new feature 3 | body: 4 | - type: textarea 5 | attributes: 6 | label: Feature details 7 | description: Explain the feature idea 8 | validations: 9 | required: true 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2022, Vítor Galvão 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # icon Temporary Email Alfred Workflow 2 | 3 | Generate disposable email inboxes 4 | 5 | [⤓ Install on the Alfred Gallery](https://alfred.app/workflows/vitor/temporary-email) 6 | 7 | ## Usage 8 | 9 | Create a temporary email address via the `tmpmail` keyword. A random inbox name is used unless you type one. 10 | 11 | ![Creating a temporary email](Workflow/images/about/tmpmail.png) 12 | 13 | On supported web browsers, the email inbox will open in a background tab and the address pasted to the current input field. 14 | -------------------------------------------------------------------------------- /Workflow/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitorgalvao/temporary-email-workflow/2806ddd231df2e2908724d100f586cb14c3ca20c/Workflow/icon.png -------------------------------------------------------------------------------- /Workflow/images/about/tmpmail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitorgalvao/temporary-email-workflow/2806ddd231df2e2908724d100f586cb14c3ca20c/Workflow/images/about/tmpmail.png -------------------------------------------------------------------------------- /Workflow/info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | bundleid 6 | com.vitorgalvao.alfred.temporaryemail 7 | connections 8 | 9 | 1BFF14FC-DF72-4BC9-807B-3D38432CF08D 10 | 11 | 12 | destinationuid 13 | 736622BA-E278-42DF-8121-265EDBBADFBA 14 | modifiers 15 | 0 16 | modifiersubtext 17 | 18 | vitoclose 19 | 20 | 21 | 22 | 9066A3FA-E9D2-44AF-BB72-A54ABBEB3A3D 23 | 24 | 25 | destinationuid 26 | A62BDC1B-6EF0-4884-8225-DED4378FC038 27 | modifiers 28 | 0 29 | modifiersubtext 30 | 31 | vitoclose 32 | 33 | 34 | 35 | A62BDC1B-6EF0-4884-8225-DED4378FC038 36 | 37 | 38 | destinationuid 39 | E9B13513-9247-4498-8320-6E24CF7DBDB5 40 | modifiers 41 | 0 42 | modifiersubtext 43 | 44 | sourceoutputuid 45 | 8174851A-74D2-4634-B71B-9BCC7064C9F5 46 | vitoclose 47 | 48 | 49 | 50 | destinationuid 51 | 1BFF14FC-DF72-4BC9-807B-3D38432CF08D 52 | modifiers 53 | 0 54 | modifiersubtext 55 | 56 | vitoclose 57 | 58 | 59 | 60 | E9B13513-9247-4498-8320-6E24CF7DBDB5 61 | 62 | 63 | destinationuid 64 | 1BFF14FC-DF72-4BC9-807B-3D38432CF08D 65 | modifiers 66 | 0 67 | modifiersubtext 68 | 69 | vitoclose 70 | 71 | 72 | 73 | 74 | createdby 75 | Vítor Galvão 76 | description 77 | Generate disposable email inboxes 78 | disabled 79 | 80 | name 81 | Temporary Email 82 | objects 83 | 84 | 85 | config 86 | 87 | concurrently 88 | 89 | escaping 90 | 102 91 | script 92 | function notification { 93 | ./notificator --message "${1}" --title "${alfred_workflow_name}" 94 | } 95 | 96 | readonly email_name="${1//[^[:alnum:]]}" 97 | readonly email="${email_name}@${email_service}" 98 | 99 | if [[ "${email_service}" == 'maildrop.cc' ]]; then 100 | readonly url="https://${email_service}/inbox/?mailbox=${email_name}" 101 | else 102 | readonly url="https://${email_service}/inbox/${email_name}" 103 | fi 104 | 105 | echo -n "${email}" 106 | notification 'Temporary email address copied to clipboard' 107 | 108 | # Use AppleScript instead of JXA because the latter cannot create tabs at specific indexes 109 | # Call it via the shell because otherwise the code is complicated by "using terms from" 110 | # which requires a specific browser to be installed 111 | readonly front_browser="$(osascript -e 'tell application "System Events" to return name of first process whose frontmost is true')" 112 | 113 | if [[ "${front_browser}" == 'Safari'* || "${front_browser}" == 'Webkit'* ]]; then 114 | osascript -e " 115 | tell application \"${front_browser}\" to tell front window 116 | set tabIndex to index of current tab make new tab at after tab tabIndex with properties {URL:\"${url}\"} 117 | end tell 118 | " > /dev/null # Ignore stdout, otherwise tab info is printed 119 | elif [[ "${front_browser}" == 'Google Chrome'* || "${front_browser}" == 'Chromium'* || "${front_browser}" == 'Opera'* || "${front_browser}" == 'Vivaldi'* || "${front_browser}" == 'Brave Browser'* || "${front_browser}" == 'Microsoft Edge'* ]]; then 120 | osascript -e " 121 | tell application \"${front_browser}\" to tell front window 122 | set tabIndex to active tab index 123 | make new tab at after tab tabIndex with properties {URL:\"${url}\"} 124 | set active tab index to tabIndex 125 | end tell 126 | " 127 | # As of Orion 0.99 (127.2) and Arc 1.40.1 (49250), neither exposes tab indexes via AppleScript 128 | elif [[ "${front_browser}" == 'Orion' || "${front_browser}" == 'Arc' ]]; then 129 | osascript -e " 130 | tell application \"${front_browser}\" to tell front window 131 | make new tab with properties {URL:\"${url}\"} 132 | end tell 133 | " > /dev/null # Ignore stdout, otherwise tab info is printed 134 | # Browser without AppleScript support, such as Firefox 135 | else 136 | open "${url}" 137 | fi 138 | scriptargtype 139 | 1 140 | scriptfile 141 | 142 | type 143 | 11 144 | 145 | type 146 | alfred.workflow.action.script 147 | uid 148 | 1BFF14FC-DF72-4BC9-807B-3D38432CF08D 149 | version 150 | 2 151 | 152 | 153 | config 154 | 155 | autopaste 156 | 157 | clipboardtext 158 | {query} 159 | ignoredynamicplaceholders 160 | 161 | transient 162 | 163 | 164 | type 165 | alfred.workflow.output.clipboard 166 | uid 167 | 736622BA-E278-42DF-8121-265EDBBADFBA 168 | version 169 | 3 170 | 171 | 172 | config 173 | 174 | argumenttype 175 | 1 176 | keyword 177 | {var:email_keyword} 178 | skipuniversalaction 179 | 180 | subtext 181 | Instant disposable email 182 | text 183 | Temporary Email 184 | withspace 185 | 186 | 187 | type 188 | alfred.workflow.input.keyword 189 | uid 190 | 9066A3FA-E9D2-44AF-BB72-A54ABBEB3A3D 191 | version 192 | 1 193 | 194 | 195 | config 196 | 197 | type 198 | 0 199 | 200 | type 201 | alfred.workflow.utility.random 202 | uid 203 | E9B13513-9247-4498-8320-6E24CF7DBDB5 204 | version 205 | 1 206 | 207 | 208 | config 209 | 210 | conditions 211 | 212 | 213 | inputstring 214 | 215 | matchcasesensitive 216 | 217 | matchmode 218 | 0 219 | matchstring 220 | 221 | outputlabel 222 | Random 223 | uid 224 | 8174851A-74D2-4634-B71B-9BCC7064C9F5 225 | 226 | 227 | elselabel 228 | Specific 229 | hideelse 230 | 231 | 232 | type 233 | alfred.workflow.utility.conditional 234 | uid 235 | A62BDC1B-6EF0-4884-8225-DED4378FC038 236 | version 237 | 1 238 | 239 | 240 | readme 241 | ## Usage 242 | 243 | Create a temporary email address via the `tmpmail` keyword. A random inbox name is used unless you type one. 244 | 245 | ![Creating a temporary email](images/about/tmpmail.png) 246 | 247 | On supported web browsers, the email inbox will open in a background tab and the address pasted to the current input field. 248 | uidata 249 | 250 | 1BFF14FC-DF72-4BC9-807B-3D38432CF08D 251 | 252 | xpos 253 | 390 254 | ypos 255 | 25 256 | 257 | 736622BA-E278-42DF-8121-265EDBBADFBA 258 | 259 | xpos 260 | 565 261 | ypos 262 | 25 263 | 264 | 9066A3FA-E9D2-44AF-BB72-A54ABBEB3A3D 265 | 266 | xpos 267 | 30 268 | ypos 269 | 25 270 | 271 | A62BDC1B-6EF0-4884-8225-DED4378FC038 272 | 273 | xpos 274 | 185 275 | ypos 276 | 45 277 | 278 | E9B13513-9247-4498-8320-6E24CF7DBDB5 279 | 280 | xpos 281 | 295 282 | ypos 283 | 25 284 | 285 | 286 | userconfigurationconfig 287 | 288 | 289 | config 290 | 291 | default 292 | tmpmail 293 | placeholder 294 | 295 | required 296 | 297 | trim 298 | 299 | 300 | description 301 | 302 | label 303 | Email Keyword 304 | type 305 | textfield 306 | variable 307 | email_keyword 308 | 309 | 310 | config 311 | 312 | default 313 | sharklasers.com 314 | pairs 315 | 316 | 317 | Maildrop 318 | maildrop.cc 319 | 320 | 321 | Harakirimail 322 | harakirimail.com 323 | 324 | 325 | Shark Lasers 326 | sharklasers.com 327 | 328 | 329 | 330 | description 331 | 332 | label 333 | Email Service 334 | type 335 | popupbutton 336 | variable 337 | email_service 338 | 339 | 340 | version 341 | 2024.2 342 | webaddress 343 | https://github.com/vitorgalvao/temporary-email-workflow/ 344 | 345 | 346 | -------------------------------------------------------------------------------- /Workflow/notificator: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | 3 | #################################################### 4 | ### Created by Vítor Galvão ### 5 | ### Find the latest version at: ### 6 | ### https://github.com/vitorgalvao/notificator ### 7 | #################################################### 8 | 9 | readonly program="$(basename "${0}")" 10 | 11 | # Helpers 12 | function show_notification { 13 | /usr/bin/open "${app}" --args "${notificator_message}" "${notificator_title}" "${notificator_subtitle}" "${notificator_sound}" 14 | } 15 | 16 | function make_icns { 17 | # Setup 18 | local -r file="${1}" 19 | local -r tmp_dir="$(/usr/bin/mktemp -d)" 20 | local -r icon="${tmp_dir}/icon.icns" 21 | local -r iconset="${tmp_dir}/icon.iconset" 22 | /bin/mkdir "${iconset}" 23 | 24 | # Create iconset 25 | for size in {16,32,64,128,256,512} 26 | do 27 | /usr/bin/sips --resampleHeightWidth "${size}" "${size}" "${file}" --out "${iconset}/icon_${size}x${size}.png" &> /dev/null 28 | /usr/bin/sips --resampleHeightWidth "$((size * 2))" "$((size * 2))" "${file}" --out "${iconset}/icon_${size}x${size}@2x.png" &> /dev/null 29 | done 30 | 31 | # Convert to icns 32 | /usr/bin/iconutil --convert icns "${iconset}" --output "${icon}" 33 | 34 | # Clean up and return path to icns 35 | /bin/rm -rf "${iconset}" 36 | echo "${icon}" 37 | } 38 | 39 | function usage { 40 | echo " 41 | Trigger macOS notifications from Alfred, using the Workflow icon 42 | 43 | Usage: 44 | ${program} --message [options] 45 | 46 | Options: 47 | -m, --message Message text 48 | -t, --title Title text 49 | -s, --subtitle Subtitle text 50 | -p, --sound Sound name (from /System/Library/Sounds) 51 | -h, --help Show this help 52 | " | sed -E 's/^ {4}//' 53 | } 54 | 55 | # Options 56 | args=() 57 | while [[ "${1}" ]] 58 | do 59 | case "${1}" in 60 | -h | --help) 61 | usage 62 | exit 0 63 | ;; 64 | -m | --message) 65 | readonly notificator_message="${2}" 66 | shift 67 | ;; 68 | -t | --title) 69 | readonly notificator_title="${2}" 70 | shift 71 | ;; 72 | -s | --subtitle) 73 | readonly notificator_subtitle="${2}" 74 | shift 75 | ;; 76 | -p | --sound) 77 | readonly notificator_sound="${2}" 78 | shift 79 | ;; 80 | --) 81 | shift 82 | args+=("${@}") 83 | break 84 | ;; 85 | -*) 86 | echo "Unrecognised option: ${1}" 87 | exit 1 88 | ;; 89 | *) 90 | args+=("${1}") 91 | ;; 92 | esac 93 | shift 94 | done 95 | set -- "${args[@]}" 96 | 97 | # Check for required arguments 98 | if [[ -z "${notificator_message}" ]] 99 | then 100 | echo 'A message is mandatory! Aborting…' >&2 101 | exit 1 102 | fi 103 | 104 | readonly bundle_id="$(/usr/bin/tr -cd '[:alnum:]._-' <<< "${alfred_workflow_bundleid}")" 105 | readonly name="$(/usr/bin/tr -cd '[:alnum:]._- ' <<< "${alfred_workflow_name}")" 106 | readonly icon="${alfred_preferences}/workflows/${alfred_workflow_uid}/icon.png" 107 | readonly app="${alfred_workflow_cache}/Notificator for ${name}.app" 108 | readonly plist="${app}/Contents/Info.plist" 109 | 110 | # Exit early if Notificator exists and was modified fewer than 30 days ago 111 | if [[ -d "${app}" && "$(/bin/date -r "${app}" +%s)" -gt "$(/bin/date -v -30d +%s)" ]] 112 | then 113 | show_notification 114 | exit 0 115 | fi 116 | 117 | # Pre-build checks 118 | if [[ -z "${bundle_id}" ]] 119 | then 120 | echo "Workflow is missing the bundle identifier! Aborting…" >&2 121 | exit 1 122 | fi 123 | 124 | if [[ -z "${name}" ]] 125 | then 126 | echo "Workflow is missing the name! Aborting…" >&2 127 | exit 1 128 | fi 129 | 130 | if [[ ! -f "${icon}" ]] 131 | then 132 | echo "Workflow is missing the icon! Aborting…" >&2 133 | exit 1 134 | fi 135 | 136 | # Build Notificator 137 | readonly jxa_script=' 138 | const argv = $.NSProcessInfo.processInfo.arguments.js.map(arg => arg.js) 139 | const app = Application.currentApplication() 140 | app.includeStandardAdditions = true 141 | 142 | if (argv.length < 2) { // We use "2" because the script will always see at least one argument: the applet itself 143 | argv[1] = "Opening usage instructions…" 144 | argv[2] = "Notificator is a command-line app" 145 | argv[4] = "Funk" 146 | 147 | app.openLocation("https://github.com/vitorgalvao/notificator#usage") 148 | } 149 | 150 | const message = argv[1] 151 | const title = argv[2] 152 | const subtitle = argv[3] 153 | const sound = argv[4] 154 | 155 | const options = {} 156 | if (title) options.withTitle = title 157 | if (subtitle) options.subtitle = subtitle 158 | if (sound) options.soundName = sound 159 | 160 | app.displayNotification(message, options) 161 | ' 162 | 163 | [[ -d "${app}" ]] && /bin/rm -r "${app}" 164 | /bin/mkdir -p "${alfred_workflow_cache}" 165 | /usr/bin/osacompile -l JavaScript -o "${app}" -e "${jxa_script}" 2> /dev/null 166 | 167 | # Modify Notificator 168 | /usr/libexec/PlistBuddy -c "add :CFBundleIdentifier string ${bundle_id}.notificator" "${plist}" 169 | /usr/libexec/PlistBuddy -c 'add :LSUIElement string 1' "${plist}" 170 | /bin/mv "$(make_icns "${icon}")" "${app}/Contents/Resources/applet.icns" 171 | 172 | # Redo signature 173 | /usr/bin/codesign --remove-signature "${app}" 174 | /usr/bin/codesign --sign - "${app}" 175 | 176 | show_notification 177 | --------------------------------------------------------------------------------