├── images ├── wt-card.png ├── nav-logo.png ├── wrapped.webp └── icons │ ├── icon.png │ ├── icon-72x72.png │ ├── icon-96x96.png │ ├── icon-128x128.png │ ├── icon-144x144.png │ ├── icon-152x152.png │ ├── icon-192x192.png │ ├── icon-384x384.png │ └── icon-512x512.png ├── README.md ├── serviceWorker.js ├── manifest.json ├── css └── style.css ├── index.html └── js └── app.js /images/wt-card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamyajat/WhatsAppThem/HEAD/images/wt-card.png -------------------------------------------------------------------------------- /images/nav-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamyajat/WhatsAppThem/HEAD/images/nav-logo.png -------------------------------------------------------------------------------- /images/wrapped.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamyajat/WhatsAppThem/HEAD/images/wrapped.webp -------------------------------------------------------------------------------- /images/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamyajat/WhatsAppThem/HEAD/images/icons/icon.png -------------------------------------------------------------------------------- /images/icons/icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamyajat/WhatsAppThem/HEAD/images/icons/icon-72x72.png -------------------------------------------------------------------------------- /images/icons/icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamyajat/WhatsAppThem/HEAD/images/icons/icon-96x96.png -------------------------------------------------------------------------------- /images/icons/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamyajat/WhatsAppThem/HEAD/images/icons/icon-128x128.png -------------------------------------------------------------------------------- /images/icons/icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamyajat/WhatsAppThem/HEAD/images/icons/icon-144x144.png -------------------------------------------------------------------------------- /images/icons/icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamyajat/WhatsAppThem/HEAD/images/icons/icon-152x152.png -------------------------------------------------------------------------------- /images/icons/icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamyajat/WhatsAppThem/HEAD/images/icons/icon-192x192.png -------------------------------------------------------------------------------- /images/icons/icon-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamyajat/WhatsAppThem/HEAD/images/icons/icon-384x384.png -------------------------------------------------------------------------------- /images/icons/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamyajat/WhatsAppThem/HEAD/images/icons/icon-512x512.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WhatsAppThem 2 | - A simple PWA which you can use to send WhatsApp messages without saving the number. 3 | - Try it out here -> https://whatsappthem.iamyajat.com/ 4 | -------------------------------------------------------------------------------- /serviceWorker.js: -------------------------------------------------------------------------------- 1 | const staticWAThem = "wathem-site-v1" 2 | const assets = [ 3 | "/", 4 | "/index.html", 5 | "/css/style.css", 6 | "/js/app.js", 7 | "/images/nav-logo.png", 8 | "/images/wrapped.webp", 9 | "/images/wt-card.png" 10 | ] 11 | 12 | self.addEventListener("install", installEvent => { 13 | installEvent.waitUntil( 14 | caches.open(staticWAThem).then(cache => { 15 | cache.addAll(assets) 16 | }) 17 | ) 18 | }) 19 | 20 | self.addEventListener("fetch", fetchEvent => { 21 | fetchEvent.respondWith( 22 | fetch(fetchEvent.request).catch(res =>{ 23 | return caches.match(fetchEvent.request) 24 | }) 25 | ) 26 | }) -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WhatsAppThem", 3 | "short_name": "WhatsAppThem", 4 | "start_url": "./", 5 | "display": "standalone", 6 | "background_color": "#f4e5ff", 7 | "theme_color": "#A53AF7", 8 | "orientation": "portrait-primary", 9 | "icons": [ 10 | { 11 | "src": "/images/icons/icon-72x72.png", 12 | "type": "image/png", 13 | "sizes": "72x72" 14 | }, 15 | { 16 | "src": "/images/icons/icon-96x96.png", 17 | "type": "image/png", 18 | "sizes": "96x96" 19 | }, 20 | { 21 | "src": "/images/icons/icon-128x128.png", 22 | "type": "image/png", 23 | "sizes": "128x128" 24 | }, 25 | { 26 | "src": "/images/icons/icon-144x144.png", 27 | "type": "image/png", 28 | "sizes": "144x144" 29 | }, 30 | { 31 | "src": "/images/icons/icon-152x152.png", 32 | "type": "image/png", 33 | "sizes": "152x152" 34 | }, 35 | { 36 | "src": "/images/icons/icon-192x192.png", 37 | "type": "image/png", 38 | "sizes": "192x192" 39 | }, 40 | { 41 | "src": "/images/icons/icon-384x384.png", 42 | "type": "image/png", 43 | "sizes": "384x384" 44 | }, 45 | { 46 | "src": "/images/icons/icon-512x512.png", 47 | "type": "image/png", 48 | "sizes": "512x512" 49 | } 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+JP&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background: #f4e5ff; 9 | font-family: "Noto Sans JP", sans-serif; 10 | font-size: 1rem; 11 | position: relative; 12 | min-height: 97vh; 13 | } 14 | 15 | main { 16 | max-width: 800px; 17 | margin: auto; 18 | padding: 0.5rem 0.5rem 2.5rem 0.5rem; 19 | } 20 | 21 | nav { 22 | display: flex; 23 | justify-content: space-between; 24 | align-items: center; 25 | } 26 | 27 | ul { 28 | list-style: none; 29 | display: flex; 30 | } 31 | 32 | li { 33 | margin-right: 1rem; 34 | } 35 | 36 | h1 { 37 | color: #a53af7; 38 | margin-bottom: 0.5rem; 39 | } 40 | 41 | input { 42 | background: inherit; 43 | border: 1px solid #ccc; 44 | border-radius: 0.7rem; 45 | margin: 10px 0 3px 0; 46 | padding: 0.75rem; 47 | line-height: 1.25rem; 48 | width: 100%; 49 | } 50 | 51 | input:focus { 52 | border: 1px solid #a53af7; 53 | outline: none; 54 | } 55 | 56 | textarea { 57 | font-family: "Noto Sans JP", sans-serif; 58 | background: inherit; 59 | border: 1px solid #ccc; 60 | border-radius: 0.7rem; 61 | margin: 10px 0 3px 0; 62 | padding: 0.75rem; 63 | line-height: 1.25rem; 64 | width: 100%; 65 | resize: none; 66 | display: none; 67 | } 68 | 69 | textarea:focus { 70 | border: 1px solid #a53af7; 71 | outline: none; 72 | } 73 | 74 | small { 75 | margin-left: 5px; 76 | font-size: 0.75rem; 77 | cursor: pointer; 78 | } 79 | 80 | small:hover { 81 | color: #a53af7; 82 | } 83 | 84 | a { 85 | text-decoration: none; 86 | transition: 0.3s; 87 | color: #000; 88 | } 89 | 90 | a:hover { 91 | color: #a53af7; 92 | } 93 | 94 | img { 95 | height: 50px; 96 | image-rendering: auto; 97 | } 98 | 99 | small, 100 | label, 101 | a, 102 | h1, 103 | h3, 104 | p, 105 | li, 106 | ul, 107 | footer { 108 | -webkit-user-select: none; 109 | -moz-user-select: none; 110 | -ms-user-select: none; 111 | user-select: none; 112 | } 113 | 114 | .nav--link { 115 | padding: 0.1rem 0.3rem; 116 | border-bottom: 1px solid #000; 117 | } 118 | 119 | .nav--link:hover { 120 | border-bottom: 1px solid #a53af7; 121 | } 122 | 123 | .card { 124 | padding: 1rem 1.2rem 1.5rem 1.2rem; 125 | width: 100%; 126 | height: auto; 127 | background: #fff; 128 | box-shadow: 0 5px 10px rgba(0, 0, 0, 0.19), 0 3px 3px rgba(0, 0, 0, 0.23); 129 | border-radius: 10px; 130 | margin: 20px 0 0 0; 131 | overflow: hidden; 132 | transition: 0.5s; 133 | } 134 | 135 | .card:hover { 136 | box-shadow: 0 8px 16px rgba(0, 0, 0, 0.19), 0 5px 5px rgba(0, 0, 0, 0.23); 137 | } 138 | 139 | .card2 { 140 | padding: 0.5rem 1.2rem; 141 | width: 100%; 142 | height: auto; 143 | background: #fff; 144 | box-shadow: 0 5px 10px rgba(0, 0, 0, 0.19), 0 3px 3px rgba(0, 0, 0, 0.23); 145 | border-radius: 10px; 146 | margin: 20px 0 0 0; 147 | overflow: hidden; 148 | transition: 0.5s; 149 | } 150 | 151 | .card2:hover { 152 | box-shadow: 0 8px 16px rgba(0, 0, 0, 0.19), 0 5px 5px rgba(0, 0, 0, 0.23); 153 | } 154 | 155 | .card3 { 156 | width: 100%; 157 | height: auto; 158 | background: #fff; 159 | box-shadow: 0 5px 10px rgba(0, 0, 0, 0.19), 0 3px 3px rgba(0, 0, 0, 0.23); 160 | border-radius: 10px; 161 | margin: 20px 0 0 0; 162 | overflow: hidden; 163 | transition: 0.5s; 164 | } 165 | 166 | .card3:hover { 167 | box-shadow: 0 8px 16px rgba(0, 0, 0, 0.19), 0 5px 5px rgba(0, 0, 0, 0.23); 168 | } 169 | 170 | .card--title { 171 | color: #222; 172 | font-weight: 700; 173 | font-size: 1.1rem; 174 | margin-top: 0.5rem; 175 | margin-bottom: 0; 176 | } 177 | 178 | .card--link { 179 | margin-top: 2rem; 180 | margin-bottom: 100px; 181 | text-decoration: none; 182 | background: #a53af7; 183 | color: #fff; 184 | padding: 0.3rem 1rem; 185 | border-radius: 0.7rem; 186 | border: 1px solid #a53af7; 187 | cursor: pointer; 188 | } 189 | .card--link:hover { 190 | background: #fff; 191 | color: #a53af7; 192 | } 193 | 194 | .list { 195 | padding: 0 20px 0 20px; 196 | } 197 | 198 | .contribute { 199 | border-bottom: 1px solid #000; 200 | } 201 | 202 | .contribute:hover { 203 | border-bottom: 1px solid #a53af7; 204 | } 205 | 206 | .sponsor-btn { 207 | border: 1px solid #000; 208 | border-radius: 0.5rem; 209 | padding: 0.25rem 0.5rem; 210 | margin: 5rem; 211 | cursor: pointer; 212 | transition: 0.3s; 213 | font-size: 0.7rem; 214 | color: #000; 215 | } 216 | 217 | .sponsor-btn:hover { 218 | color: #a53af7; 219 | border: 1px solid #a53af7; 220 | } 221 | 222 | .footer { 223 | padding-top: 30px; 224 | bottom: 0px; 225 | text-align: center; 226 | width: 100%; 227 | } 228 | 229 | .errormessage { 230 | color: red; 231 | font-size: 0.8rem; 232 | margin-left: 0.5rem; 233 | } 234 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 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 | WhatsAppThem - Send WhatsApp Messages Without Saving Numbers 59 | 60 | 61 | 62 |
63 | 69 |
70 | 71 | 72 | + Add message 73 |
74 | 75 |
76 | Send Message 77 | 78 |
79 |
80 |

What is it?

81 |

A simple app which you can use to send WhatsApp messages without saving the number.

82 |
83 |
84 |

How to use?

85 |
    86 |
  1. Copy the number
  2. 87 |
  3. Paste it here
  4. 88 |
  5. Hit Send Message
  6. 89 |
90 |
91 | 92 | 93 | 94 |
95 |

Want to contribute?

96 |

97 | Feel free to create issues and open PRs on my GitHub Repo, iamyajat/WhatsAppThem. 99 |

100 |
101 | 105 |
106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /js/app.js: -------------------------------------------------------------------------------- 1 | const COUNTRY_PHONE_MAP = { 2 | AD: "376", 3 | AE: "971", 4 | AF: "93", 5 | AG: "1-268", 6 | AI: "1-264", 7 | AL: "355", 8 | AM: "374", 9 | AN: "599", 10 | AO: "244", 11 | AQ: "672", 12 | AR: "54", 13 | AS: "1-684", 14 | AT: "43", 15 | AU: "61", 16 | AW: "297", 17 | AZ: "994", 18 | BA: "387", 19 | BB: "1-246", 20 | BD: "880", 21 | BE: "32", 22 | BF: "226", 23 | BG: "359", 24 | BH: "973", 25 | BI: "257", 26 | BJ: "229", 27 | BL: "590", 28 | BM: "1-441", 29 | BN: "673", 30 | BO: "591", 31 | BR: "55", 32 | BS: "1-242", 33 | BT: "975", 34 | BW: "267", 35 | BY: "375", 36 | BZ: "501", 37 | CA: "1", 38 | CC: "61", 39 | CD: "243", 40 | CF: "236", 41 | CG: "242", 42 | CH: "41", 43 | CI: "225", 44 | CK: "682", 45 | CL: "56", 46 | CM: "237", 47 | CN: "86", 48 | CO: "57", 49 | CR: "506", 50 | CU: "53", 51 | CV: "238", 52 | CW: "599", 53 | CX: "61", 54 | CY: "357", 55 | CZ: "420", 56 | DE: "49", 57 | DJ: "253", 58 | DK: "45", 59 | DM: "1-767", 60 | DO: "1-809, 1-829, 1-849", 61 | DZ: "213", 62 | EC: "593", 63 | EE: "372", 64 | EG: "20", 65 | EH: "212", 66 | ER: "291", 67 | ES: "34", 68 | ET: "251", 69 | FI: "358", 70 | FJ: "679", 71 | FK: "500", 72 | FM: "691", 73 | FO: "298", 74 | FR: "33", 75 | GA: "241", 76 | GB: "44", 77 | GD: "1-473", 78 | GE: "995", 79 | GG: "44-1481", 80 | GH: "233", 81 | GI: "350", 82 | GL: "299", 83 | GM: "220", 84 | GN: "224", 85 | GQ: "240", 86 | GR: "30", 87 | GT: "502", 88 | GU: "1-671", 89 | GW: "245", 90 | GY: "592", 91 | HK: "852", 92 | HN: "504", 93 | HR: "385", 94 | HT: "509", 95 | HU: "36", 96 | ID: "62", 97 | IE: "353", 98 | IL: "972", 99 | IM: "44-1624", 100 | IN: "91", 101 | IO: "246", 102 | IQ: "964", 103 | IR: "98", 104 | IS: "354", 105 | IT: "39", 106 | JE: "44-1534", 107 | JM: "1-876", 108 | JO: "962", 109 | JP: "81", 110 | KE: "254", 111 | KG: "996", 112 | KH: "855", 113 | KI: "686", 114 | KM: "269", 115 | KN: "1-869", 116 | KP: "850", 117 | KR: "82", 118 | KW: "965", 119 | KY: "1-345", 120 | KZ: "7", 121 | LA: "856", 122 | LB: "961", 123 | LC: "1-758", 124 | LI: "423", 125 | LK: "94", 126 | LR: "231", 127 | LS: "266", 128 | LT: "370", 129 | LU: "352", 130 | LV: "371", 131 | LY: "218", 132 | MA: "212", 133 | MC: "377", 134 | MD: "373", 135 | ME: "382", 136 | MF: "590", 137 | MG: "261", 138 | MH: "692", 139 | MK: "389", 140 | ML: "223", 141 | MM: "95", 142 | MN: "976", 143 | MO: "853", 144 | MP: "1-670", 145 | MR: "222", 146 | MS: "1-664", 147 | MT: "356", 148 | MU: "230", 149 | MV: "960", 150 | MW: "265", 151 | MX: "52", 152 | MY: "60", 153 | MZ: "258", 154 | NA: "264", 155 | NC: "687", 156 | NE: "227", 157 | NG: "234", 158 | NI: "505", 159 | NL: "31", 160 | NO: "47", 161 | NP: "977", 162 | NR: "674", 163 | NU: "683", 164 | NZ: "64", 165 | OM: "968", 166 | PA: "507", 167 | PE: "51", 168 | PF: "689", 169 | PG: "675", 170 | PH: "63", 171 | PK: "92", 172 | PL: "48", 173 | PM: "508", 174 | PN: "64", 175 | PR: "1-787, 1-939", 176 | PS: "970", 177 | PT: "351", 178 | PW: "680", 179 | PY: "595", 180 | QA: "974", 181 | RE: "262", 182 | RO: "40", 183 | RS: "381", 184 | RU: "7", 185 | RW: "250", 186 | SA: "966", 187 | SB: "677", 188 | SC: "248", 189 | SD: "249", 190 | SE: "46", 191 | SG: "65", 192 | SH: "290", 193 | SI: "386", 194 | SJ: "47", 195 | SK: "421", 196 | SL: "232", 197 | SM: "378", 198 | SN: "221", 199 | SO: "252", 200 | SR: "597", 201 | SS: "211", 202 | ST: "239", 203 | SV: "503", 204 | SX: "1-721", 205 | SY: "963", 206 | SZ: "268", 207 | TC: "1-649", 208 | TD: "235", 209 | TG: "228", 210 | TH: "66", 211 | TJ: "992", 212 | TK: "690", 213 | TL: "670", 214 | TM: "993", 215 | TN: "216", 216 | TO: "676", 217 | TR: "90", 218 | TT: "1-868", 219 | TV: "688", 220 | TW: "886", 221 | TZ: "255", 222 | UA: "380", 223 | UG: "256", 224 | US: "1", 225 | UY: "598", 226 | UZ: "998", 227 | VA: "379", 228 | VC: "1-784", 229 | VE: "58", 230 | VG: "1-284", 231 | VI: "1-340", 232 | VN: "84", 233 | VU: "678", 234 | WF: "681", 235 | WS: "685", 236 | XK: "383", 237 | YE: "967", 238 | YT: "262", 239 | ZA: "27", 240 | ZM: "260", 241 | ZW: "263", 242 | }; 243 | 244 | if ("serviceWorker" in navigator) { 245 | window.addEventListener("load", function () { 246 | navigator.serviceWorker 247 | .register("/serviceWorker.js") 248 | .then(res => console.log("service worker registered")) 249 | .catch(err => console.log("service worker not registered", err)) 250 | }) 251 | } 252 | 253 | async function getLocalCountry () { 254 | let locationData; 255 | try { 256 | locationData = await fetch("https://geolocation-db.com/json/", { 257 | method: "GET", 258 | }); 259 | locationData = await locationData.json(); 260 | } catch (err) { 261 | throw new Error(err); 262 | } 263 | const countryCode = locationData["country_code"]; 264 | let countryPrefix = COUNTRY_PHONE_MAP[countryCode]; 265 | 266 | return countryPrefix.split(", ")[0]; 267 | } 268 | 269 | async function onClick () { 270 | let phoneNumber = document.getElementById("phone").value.trim(); 271 | phoneNumber = phoneNumber.replace(/( |-)/g, ""); 272 | if (phoneNumber.match(/^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*$/)) { 273 | document.getElementById("errormessage").innerHTML = ""; 274 | let url = "https://wa.me/"; 275 | if (phoneNumber !== "") { 276 | let countryCode = ""; 277 | if (phoneNumber[0] != "+") { 278 | try { 279 | countryCode = await getLocalCountry(); 280 | countryCode = "+" + countryCode; 281 | } catch (err) { 282 | console.log(err); 283 | } 284 | } 285 | url += countryCode + phoneNumber; 286 | let visibility = document.getElementById("messageShowHide").innerHTML; 287 | if (visibility === "- Add message") { 288 | let message = document.getElementById("messageData").value; 289 | message = encodeURIComponent(message); 290 | url += "?text=" + message; 291 | } 292 | window.open(url); 293 | } 294 | } else { 295 | document.getElementById("phone").style.borderColor = "red"; 296 | document.getElementById("errormessage").innerHTML = "Invalid phone number"; 297 | document.getElementById("phone").focus(); 298 | } 299 | } 300 | 301 | document.getElementById("submit").addEventListener("click", onClick) 302 | 303 | function messageShowHide () { 304 | var visibility = document.getElementById("messageShowHide").innerHTML 305 | if (visibility === "+ Add message") { 306 | document.getElementById("messageShowHide").innerHTML = "- Add message"; 307 | document.getElementById("messageData").style.display = "block" 308 | } else { 309 | document.getElementById("messageShowHide").innerHTML = "+ Add message"; 310 | document.getElementById("messageData").style.display = "none" 311 | } 312 | } 313 | 314 | document.getElementById("messageShowHide").addEventListener("click", messageShowHide); 315 | 316 | function checkNumber (e) { 317 | if (e.target.value[0] === "+") { 318 | if (e.target.value.match(/[^\d]/)) { 319 | e.target.value = "+" + e.target.value.substring(1).replace(/[^\d]/g, ""); 320 | } 321 | } else { 322 | if (e.target.value.match(/[^\d]/)) { 323 | e.target.value = e.target.value.replace(/[^\d]/g, ""); 324 | } 325 | } 326 | if (e.key === 'Enter' || e.keyCode === 13) { 327 | onClick(); 328 | } 329 | } 330 | 331 | document.getElementById("phone").addEventListener("keyup", checkNumber); 332 | 333 | 334 | function onClickOutside (e) { 335 | if (!document.getElementById('submit').contains(e.target)) { 336 | document.getElementById("phone").style.borderColor = "#ccc"; 337 | } 338 | } 339 | 340 | window.addEventListener('click', onClickOutside); --------------------------------------------------------------------------------