I'm working on a notification package and am having some trouble on how to new up a function but not simply when it is imported. For example:
I have this as my notification function:
const sendNotification = async (options: SendNotificationTypes) => {
const handleChannel = {
slack: async (options: SlackNotificationTypes) => {
await sendSlack(options);
},
email: async (options: EmailNotificationTypes) => {
await sendEmail(options);
},
sms: async (options: SMSNotificationTypes) => {
await sendSms(options);
}
};
options.channels.forEach(channel => {
switch (channel) {
case CHANNEL_SLACK:
handleChannel.slack(options.slack);
break;
case CHANNEL_EMAIL:
handleChannel.email(options.email);
break;
case CHANNEL_SMS:
handleChannel.sms(options.sms);
break;
}
});
};
My slack notifier looks like this:
const slack = new WebClient(tokenGoesHere)
const sendSlack = async (options: SlackNotificationTypes) => {
try {
await slack.chat.postMessage({
channel: options.channel,
...(options.message && { text: options.message }),
...(options.blocks && { blocks: options.blocks }),
...(options.emoji && { icon_emoji: options.emoji }),
...(options.attachments && {
attachments: options.attachments
})
});
} catch (error) {
throw new Error(`Slack notification failed to send: ${error}`);
}
};
So this works fine but the code fails at points if my environment variables aren't in place (since I'm sourcing the slack token from process.env
).
Instead, I'd like to be able to instantiate the function when I need it and pass in the slack token at that point. Ideally if there's a way to not need a new instance every time I send the notification, I would want to do that.
I'm pretty stuck on this and think I need to perhaps refactor to a class? Any advice welcome!
Just lazily initialise a single instance:
let slack = null; // token not yet available
async function sendSlack(options: SlackNotificationTypes) {
if (!slack) {
slack = new WebClient(tokenGoesHere) // hopefully available now
}
… // rest of the code using `slack` instance
}
However, your environment variables should always be already in place when the process starts, or at least be filled in by something like dotenv
before the modules that use them get loaded.