← back to Wine Finder Next
lib/services/slackNotifier.js
155 lines
const axios = require('axios');
class SlackNotifier {
constructor() {
this.webhookUrl = process.env.SLACK_WEBHOOK_URL;
this.enabled = !!this.webhookUrl;
}
// Check if Slack integration is enabled
isEnabled() {
return this.enabled && this.webhookUrl && this.webhookUrl.startsWith('https://hooks.slack.com');
}
// Send a price spike alert to Slack
async sendPriceSpikeAlert(wineData, oldPrice, newPrice, percentageIncrease) {
try {
if (!this.isEnabled()) {
console.warn('Slack webhook not configured. Skipping notification.');
return { success: false, error: 'Slack not configured' };
}
const message = {
text: `🚨 Wine Price Alert!`,
blocks: [
{
type: 'header',
text: {
type: 'plain_text',
text: '🚨 Wine Price Spike Detected!',
emoji: true
}
},
{
type: 'section',
fields: [
{
type: 'mrkdwn',
text: `*Wine:*\n${wineData.name}`
},
{
type: 'mrkdwn',
text: `*Source:*\n${wineData.source || 'K&L Wine Merchants'}`
}
]
},
{
type: 'section',
fields: [
{
type: 'mrkdwn',
text: `*Previous Price:*\n$${oldPrice.toFixed(2)}`
},
{
type: 'mrkdwn',
text: `*Current Price:*\n$${newPrice.toFixed(2)}`
}
]
},
{
type: 'section',
text: {
type: 'mrkdwn',
text: `*Price Increase:* ${percentageIncrease.toFixed(1)}% 📈`
}
}
]
};
// Add URL if available
if (wineData.url) {
message.blocks.push({
type: 'section',
text: {
type: 'mrkdwn',
text: `<${wineData.url}|View on ${wineData.source}>`
}
});
}
message.blocks.push({
type: 'context',
elements: [
{
type: 'mrkdwn',
text: `🍷 Red Thunder Wine Tracker | ${new Date().toLocaleString()}`
}
]
});
// Send to Slack
await axios.post(this.webhookUrl, message, {
headers: {
'Content-Type': 'application/json'
},
timeout: 10000
});
console.log(`✅ Slack alert sent for ${wineData.name}`);
return { success: true };
} catch (error) {
console.error('Error sending Slack notification:', error.message);
return { success: false, error: error.message };
}
}
// Send a general notification
async sendNotification(message) {
try {
if (!this.isEnabled()) {
console.warn('Slack webhook not configured. Skipping notification.');
return { success: false, error: 'Slack not configured' };
}
const payload = {
text: message,
blocks: [
{
type: 'section',
text: {
type: 'mrkdwn',
text: message
}
},
{
type: 'context',
elements: [
{
type: 'mrkdwn',
text: `🍷 Red Thunder Wine Tracker | ${new Date().toLocaleString()}`
}
]
}
]
};
await axios.post(this.webhookUrl, payload, {
headers: {
'Content-Type': 'application/json'
},
timeout: 10000
});
console.log('✅ Slack notification sent');
return { success: true };
} catch (error) {
console.error('Error sending Slack notification:', error.message);
return { success: false, error: error.message };
}
}
}
module.exports = new SlackNotifier();