do multiple discord calls in one
All checks were successful
Build and push image for doorman-homeassistant / docker (push) Successful in 38s
Build and push Doorman UI / API / docker (push) Successful in 1m21s
Build and push image for doorman-homeassistant / deploy-gitainer (push) Successful in 8s

This commit is contained in:
Martin Dimitrov 2024-10-27 19:45:08 -07:00
parent aeb936938e
commit 29a839aef8
3 changed files with 47 additions and 27 deletions

View File

@ -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) { exports.handler = async function(context, event, callback) {
const response = new Twilio.Response(); const response = new Twilio.Response();
const discordPath = Runtime.getFunctions()['common/discord'].path; const discordPath = Runtime.getFunctions()['common/discord'].path;
const discord = require(discordPath); 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 {
try { users = JSON.parse(users);
const fingerprint = JSON.parse(event.json); msgs = JSON.parse(msgs);
msg += `\`\`\`# Unlocked by\n${JSON.stringify(fingerprint, null, 4)}\`\`\``; jsons = JSON.parse(jsons);
} catch (e) {
msg += `\`\`\`# Unlocked by\n# WARN: Unknown or corrupt raw fingerprint:\n ${event.json}\`\`\``; 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 setTimeout(() => {
await discord.sendMessageToUser(context, console.log("Ungraceful finish: running out of time");
event.discordUser, callback(null, response);
msg, }, 5000);
).catch((e) => console.error(e));
await Promise.all(promises);
return callback(null, response); return callback(null, response);
}; };

View File

@ -11,7 +11,7 @@ exports.getDiscordClient = async (context) => {
const client = new Client({ const client = new Client({
intents: [GatewayIntentBits.DirectMessages], intents: [GatewayIntentBits.DirectMessages],
rest: { rest: {
timeout: 8_000, // 8s timeout: 4_000, // 4s
} }
}); });

View File

@ -14,14 +14,12 @@ async function getConfig(context, buzzer) {
function notifyDiscord(context, msg, u, optionalJsonStr) { function notifyDiscord(context, msg, u, optionalJsonStr) {
return fetch(context.DOORMAN_URL + 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)) ).catch(err => console.log(err))
} }
function notifyAllDiscord(context, config, msg, optionalJsonStr) { function notifyAllDiscord(context, config, msg, optionalJsonStr) {
return Promise.all(config.discordUsers.map((u) => return notifyDiscord(context, config.discordUsers.map(() => msg), config.discordUsers, config.discordUsers.map(() => optionalJsonStr).filter(Boolean));
notifyDiscord(context, msg, u, optionalJsonStr)
));
} }
function doorOpenTwiml(twiml, config) { 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 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=`; let msg = `🔔 Someone is dialing right now @ Door "${config.door}" [Click to unlock](${context.DOORMAN_URL}/api/door/auth?door=${config.door}&key=`;
let msgs = config.discordUsers.map((u) =>
msg + u + ')'
);
// TODO: should we await for one delivery? notifyDiscord(context, msgs, config.discordUsers, []);
Promise.race(config.discordUsers.map((u) =>
notifyDiscord(context, msg + u + ')', u)
));
let discordLock = false; let discordLock = false;
let intervals = []; let intervals = [];
@ -101,7 +99,7 @@ exports.handler = async function(context, event, callback) {
} }
} }
}).catch(err => console.log(invokeId, err)); }).catch(err => console.log(invokeId, err));
}, 500)); }, 750));
}); });
const gracefulFallbackPromise = new Promise((resolve, reject) => { const gracefulFallbackPromise = new Promise((resolve, reject) => {
@ -118,7 +116,8 @@ exports.handler = async function(context, event, callback) {
await notifyAllDiscord( await notifyAllDiscord(
context, context,
config, 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); resolve(twiml);
} else { } 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" invokeId, "UngracefulFallbackPromise: Cutting it too close to timeout! Skipping notifying users and calling fallback"
); );
resolve(twiml); resolve(twiml);
}, 8000)); }, 9500));
}); });
const twiml = await Promise.race([unlockPromise, gracefulFallbackPromise, ungracefulFallbackPromise]); const twiml = await Promise.race([unlockPromise, gracefulFallbackPromise, ungracefulFallbackPromise]);