feat: Complete match notification service implementation
This commit is contained in:
@@ -4,94 +4,101 @@ const { createMatchRequestEmbed } = require('../utils/embedBuilders');
|
|||||||
const { createMatchActionRow } = require('../utils/componentBuilders');
|
const { createMatchActionRow } = require('../utils/componentBuilders');
|
||||||
|
|
||||||
class NotificationService {
|
class NotificationService {
|
||||||
constructor(bot, supabaseService) {
|
constructor(bot, supabase) {
|
||||||
this.bot = bot;
|
this.bot = bot;
|
||||||
this.supabaseService = supabaseService;
|
this.supabase = supabase;
|
||||||
this.app = express();
|
this.app = express();
|
||||||
this.app.use(express.json());
|
this.app.use(express.json());
|
||||||
this.setupRoutes();
|
this.setupRoutes();
|
||||||
}
|
}
|
||||||
|
|
||||||
setupRoutes() {
|
setupRoutes() {
|
||||||
this.app.post('/api/match-notification', this.handleMatchNotification.bind(this));
|
this.app.post('/api/match-notification', this.handleMatchNotification.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
async start(port = 3000) {
|
async start(port = 3000) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
this.server = this.app.listen(port, () => {
|
this.server = this.app.listen(port, () => {
|
||||||
console.log(`Notification service listening on port ${port}`);
|
console.log(`Notification service listening on port ${port}`);
|
||||||
resolve();
|
resolve();
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} catch (error) {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async stop() {
|
|
||||||
if (this.server) {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
this.server.close(resolve);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
async handleMatchNotification(req, res) {
|
async stop() {
|
||||||
try {
|
if (this.server) {
|
||||||
const authToken = req.headers['x-webhook-token'];
|
return new Promise((resolve) => {
|
||||||
if (authToken !== process.env.WEBHOOK_SECRET) {
|
this.server.close(resolve);
|
||||||
return res.status(401).json({ error: 'Unauthorized' });
|
});
|
||||||
}
|
|
||||||
|
|
||||||
const matchData = req.body;
|
|
||||||
if (!this.validateMatchData(matchData)) {
|
|
||||||
return res.status(400).json({ error: 'Invalid match data' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const subscriptions = await this.supabaseService.getSubscriptions();
|
|
||||||
const relevantSubscriptions = subscriptions.filter(sub => sub.game_name === matchData.game_name);
|
|
||||||
|
|
||||||
for (const subscription of relevantSubscriptions) {
|
|
||||||
try {
|
|
||||||
const channel = await this.bot.client.channels.fetch(subscription.channel_id);
|
|
||||||
const embed = createMatchRequestEmbed(matchData);
|
|
||||||
const actionRow = createMatchActionRow(matchData.game_name);
|
|
||||||
|
|
||||||
await channel.send({
|
|
||||||
embeds: [embed],
|
|
||||||
components: [actionRow]
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Error sending notification to channel ${subscription.channel_id}:`, error);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
res.json({ success: true });
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error handling match notification:', error);
|
|
||||||
res.status(500).json({ error: 'Internal server error' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
validateMatchData(matchData) {
|
|
||||||
if (matchData.type !== 'match_request') {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const requiredFields = [
|
async handleMatchNotification(req, res) {
|
||||||
'game_name',
|
try {
|
||||||
'game_id',
|
const authToken = req.headers['x-webhook-token'];
|
||||||
'team_size',
|
if (authToken !== process.env.WEBHOOK_SECRET) {
|
||||||
'match_type',
|
return res.status(401).json({ error: 'Unauthorized' });
|
||||||
'region',
|
}
|
||||||
'match_date',
|
|
||||||
'match_class',
|
|
||||||
'status'
|
|
||||||
];
|
|
||||||
|
|
||||||
return requiredFields.every(field => matchData[field] !== undefined);
|
const matchData = req.body;
|
||||||
}
|
if (!this.validateMatchData(matchData)) {
|
||||||
|
return res.status(400).json({ error: 'Invalid match data' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data: subscriptions, error } = await this.supabase
|
||||||
|
.from('active_subscriptions')
|
||||||
|
.select('*')
|
||||||
|
.eq('game_name', matchData.game_name);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.error('Error fetching subscriptions:', error);
|
||||||
|
return res.status(500).json({ error: 'Failed to fetch subscriptions' });
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const subscription of (subscriptions || [])) {
|
||||||
|
try {
|
||||||
|
const channel = await this.bot.client.channels.fetch(subscription.notification_channel_id);
|
||||||
|
const embed = createMatchRequestEmbed(matchData);
|
||||||
|
const actionRow = createMatchActionRow(matchData.game_name);
|
||||||
|
|
||||||
|
await channel.send({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [actionRow]
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error sending notification to channel ${subscription.notification_channel_id}:`, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error handling match notification:', error);
|
||||||
|
res.status(500).json({ error: 'Internal server error' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
validateMatchData(matchData) {
|
||||||
|
if (matchData.type !== 'match_request') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const requiredFields = [
|
||||||
|
'game_name',
|
||||||
|
'game_id',
|
||||||
|
'team_size',
|
||||||
|
'match_type',
|
||||||
|
'region',
|
||||||
|
'match_date',
|
||||||
|
'match_class',
|
||||||
|
'status'
|
||||||
|
];
|
||||||
|
|
||||||
|
return requiredFields.every(field => matchData[field] !== undefined);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = NotificationService;
|
module.exports = NotificationService;
|
||||||
Reference in New Issue
Block a user