diff --git a/packages/doorman-api/functions/api/door/notify.js b/packages/doorman-api/functions/api/door/notify.js index b5e333d..b974660 100644 --- a/packages/doorman-api/functions/api/door/notify.js +++ b/packages/doorman-api/functions/api/door/notify.js @@ -1,25 +1,46 @@ +function jsonMsgSuffix(jsonString) { + if (jsonString === undefined) { + return ""; + } + try { + const fingerprint = JSON.parse(jsonString); + return `\`\`\`# Unlocked by\n${JSON.stringify(fingerprint, null, 4)}\`\`\``; + } catch (e) { + return `\`\`\`# Unlocked by\n# WARN: Unknown or corrupt raw fingerprint:\n ${jsonString}\`\`\``; + } +} + exports.handler = async function(context, event, callback) { const response = new Twilio.Response(); - const discordPath = Runtime.getFunctions()['common/discord'].path; const discord = require(discordPath); - let msg = event.msg; + let users = event.discordUser; + let msgs = event.msg; + let jsons = event.json; + let promises; - if (event.json && event.json != "undefined") { - try { - const fingerprint = JSON.parse(event.json); - msg += `\`\`\`# Unlocked by\n${JSON.stringify(fingerprint, null, 4)}\`\`\``; - } catch (e) { - msg += `\`\`\`# Unlocked by\n# WARN: Unknown or corrupt raw fingerprint:\n ${event.json}\`\`\``; - } + try { + users = JSON.parse(users); + msgs = JSON.parse(msgs); + jsons = JSON.parse(jsons); + + promises = msgs.map((msg, i) => + discord.sendMessageToUser( + context, + users[i], + msg + jsonMsgSuffix(jsons[i]) + ).catch(e => console.error(e)) + ); + } catch (e) { + console.error(e); } - // user must be in "Doorman" server - await discord.sendMessageToUser(context, - event.discordUser, - msg, - ).catch((e) => console.error(e)); + setTimeout(() => { + console.log("Ungraceful finish: running out of time"); + callback(null, response); + }, 5000); + await Promise.all(promises); return callback(null, response); }; diff --git a/packages/doorman-api/functions/common/discord.private.js b/packages/doorman-api/functions/common/discord.private.js index dccdddf..6c1887e 100644 --- a/packages/doorman-api/functions/common/discord.private.js +++ b/packages/doorman-api/functions/common/discord.private.js @@ -11,7 +11,7 @@ exports.getDiscordClient = async (context) => { const client = new Client({ intents: [GatewayIntentBits.DirectMessages], rest: { - timeout: 8_000, // 8s + timeout: 4_000, // 4s } }); diff --git a/packages/doorman-client/functions/buzzer-activated.js b/packages/doorman-client/functions/buzzer-activated.js index f80cfaf..7170772 100644 --- a/packages/doorman-client/functions/buzzer-activated.js +++ b/packages/doorman-client/functions/buzzer-activated.js @@ -14,14 +14,12 @@ async function getConfig(context, buzzer) { function notifyDiscord(context, msg, u, optionalJsonStr) { return fetch(context.DOORMAN_URL + - `/api/door/notify?discordUser=${u}&msg=${encodeURIComponent(msg)}&json=${encodeURIComponent(optionalJsonStr)}`, + `/api/door/notify?discordUser=${encodeURIComponent(JSON.stringify(u))}&msg=${encodeURIComponent(JSON.stringify(msg))}&json=${encodeURIComponent(JSON.stringify(optionalJsonStr))}`, ).catch(err => console.log(err)) } function notifyAllDiscord(context, config, msg, optionalJsonStr) { - return Promise.all(config.discordUsers.map((u) => - notifyDiscord(context, msg, u, optionalJsonStr) - )); + return notifyDiscord(context, config.discordUsers.map(() => msg), config.discordUsers, config.discordUsers.map(() => optionalJsonStr).filter(Boolean)); } function doorOpenTwiml(twiml, config) { @@ -68,11 +66,11 @@ exports.handler = async function(context, event, callback) { // let users know someone is currently buzzing, and allow unlock by discord user let msg = `🔔 Someone is dialing right now @ Door "${config.door}" [Click to unlock](${context.DOORMAN_URL}/api/door/auth?door=${config.door}&key=`; - - // TODO: should we await for one delivery? - Promise.race(config.discordUsers.map((u) => - notifyDiscord(context, msg + u + ')', u) - )); + let msgs = config.discordUsers.map((u) => + msg + u + ')' + ); + + notifyDiscord(context, msgs, config.discordUsers, []); let discordLock = false; let intervals = []; @@ -101,7 +99,7 @@ exports.handler = async function(context, event, callback) { } } }).catch(err => console.log(invokeId, err)); - }, 500)); + }, 750)); }); const gracefulFallbackPromise = new Promise((resolve, reject) => { @@ -118,7 +116,8 @@ exports.handler = async function(context, event, callback) { await notifyAllDiscord( context, config, - `📞 Somebody buzzed the door and it dialed through to fallback phone numbers @ Door "${config.door}"` + `📞 Somebody buzzed the door and it dialed through to fallback phone numbers @ Door "${config.door}"`, + undefined ); resolve(twiml); } else { @@ -137,7 +136,7 @@ exports.handler = async function(context, event, callback) { invokeId, "UngracefulFallbackPromise: Cutting it too close to timeout! Skipping notifying users and calling fallback" ); resolve(twiml); - }, 8000)); + }, 9500)); }); const twiml = await Promise.race([unlockPromise, gracefulFallbackPromise, ungracefulFallbackPromise]);