Created
November 1, 2023 10:49
-
-
Save dleshem/aba9f255a17a2ed287947336cdc35c3f to your computer and use it in GitHub Desktop.
Tampermonkey userscript to send WhatsApp texts triggered by alarms in Israel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name WhatsAppAlarms | |
// @namespace http://tampermonkey.net/ | |
// @version 1.0 | |
// @description WhatsApp texts triggered by alarms in Israel | |
// @author Danny Leshem | |
// @match https://web.whatsapp.com/ | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=whatsapp.com | |
// @grant GM_xmlhttpRequest | |
// @connect www.oref.org.il | |
// @connect github.com | |
// ==/UserScript== | |
// Setup: add rules below, load to Tampermonkey, grant permissions when asked | |
// | |
// We use GM_xmlhttpRequest to poll for alerts, as oref.org.il fails requests with | |
// incorrect {Referer, X-Requested-With} HTTP headers. | |
// | |
// This means our script is sandboxed, so we must explicitly fetch and load wppconnect-wa.js | |
// instead of using @require | |
// | |
// | |
// | |
// Config | |
// | |
const pollMs = 1000 * 10; // How often should oref.org.il be polled for alerts (default: 10 seconds) | |
const throttleMs = 1000 * 60 * 15; // How long to Wait before a rule is triggered again (default: 15 minutes) | |
// | |
// { | |
// area: 'תל אביב - מרכז העיר', // an oref.org.il area (or '' for all areas) | |
// chatId: '[email protected]', // chat ID, can be individual chat or group chat (see wppconnect-wa.js) | |
// texts: [ // list of texts to sample from | |
// 'message #1', | |
// 'message #2', | |
// 'message #3' | |
// ], | |
// lastTriggered: null | |
// } | |
// | |
const rules = []; | |
// | |
// Utils | |
// | |
const sleep = ms => new Promise(r => setTimeout(r, ms)); | |
const sample = array => array[Math.floor(Math.random() * array.length)]; | |
const fetch = async (url, headers = {}) => { | |
return new Promise((resolve, reject) => { | |
GM_xmlhttpRequest({ | |
anonymous: true, | |
headers, | |
method: 'GET', | |
onload: (res) => { | |
if (res.status >= 200 && res.status < 300) { | |
resolve(res.response); | |
} else { | |
reject({ | |
status: res.status, | |
statusText: res.statusText | |
}); | |
} | |
}, | |
onerror: (res) => { | |
reject({ | |
status: res.status, | |
statusText: res.statusText | |
}); | |
}, | |
url | |
}); | |
}); | |
}; | |
// | |
// Alerts API | |
// | |
const fetchCurrentAlerts = async () => { | |
const responseText = await fetch('https://www.oref.org.il/WarningMessages/alert/alerts.json', { | |
'Referer': 'https://www.oref.org.il/12481-he/Pakar.aspx', | |
'X-Requested-With': 'XMLHttpRequest' | |
}); | |
const responseJson = responseText.replaceAll('\r\n', ''); | |
return responseJson ? JSON.parse(responseJson) : null; | |
}; | |
const includesArea = (alerts, area) => { | |
for (let i = 0; i < alerts.data.length; ++i) { | |
if (alerts.data[i].includes(area)) { | |
return true; | |
} | |
} | |
return false; | |
}; | |
// | |
// Whatsapp API | |
// | |
const loadWppConnect = async () => { | |
console.log('Fetching wppconnect-wa.js'); | |
const responseText = await fetch('https://github.com/wppconnect-team/wa-js/releases/download/nightly/wppconnect-wa.js'); | |
console.log(`Fetched wppconnect-wa.js (${responseText.length} bytes)`); | |
const e = document.createElement('script'); | |
e.innerText = responseText; | |
document.head.appendChild(e); | |
console.log('Loaded wppconnect-wa.js'); | |
}; | |
// | |
// Logic | |
// | |
const main = async () => { | |
while (true) { | |
try { | |
const alerts = await fetchCurrentAlerts(); | |
console.log(new Date().toLocaleString(), alerts); | |
if (alerts) { | |
rules.forEach(rule => { | |
if (includesArea(alerts, rule.area)) { | |
console.log(`Alarm in '${rule.area}'`); | |
const lastTriggered = rule.lastTriggered || 0; | |
const now = new Date().getTime(); | |
if (now - lastTriggered > throttleMs) { | |
rule.lastTriggered = now; | |
WPP.chat.sendTextMessage(rule.chatId, sample(rule.texts)); | |
} | |
} | |
}); | |
} | |
} catch (e) { | |
console.log(e); | |
} | |
await sleep(pollMs); | |
} | |
}; | |
(async () => { | |
'use strict'; | |
await loadWppConnect(); | |
WPP.webpack.onReady(() => { | |
console.log('WPP.webpack.onReady'); | |
}); | |
WPP.webpack.onFullReady(async () => { | |
console.log('WPP.webpack.onFullReady'); | |
main(); | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment