gh2tg/api/webhook.js

107 lines
3.4 KiB
JavaScript
Raw Permalink Normal View History

2025-02-18 21:10:44 +00:00
const { handleGitea } = require('./gitea')
const { handleGithub } = require('./github')
2025-02-18 21:12:06 +00:00
2025-02-18 21:10:44 +00:00
// Store for already reported commit hashes (in-memory, resets on restart)
const reportedCommits = new Set();
const commitTimestamps = new Map();
// TTL constants (used in cleanup)
const COMMIT_TTL = 30 * 24 * 60 * 60 * 1000; // 30 days
/**
* Cleanup old commits (called by Vercel Cron)
* @param {Object} req - Express request object
* @param {Object} res - Express response object
*/
const cleanup = (req, res) => {
2025-02-18 23:20:42 +00:00
console.log('🧹 Starting cleanup')
2025-02-18 21:10:44 +00:00
const now = Date.now();
let cleaned = 0;
for (const [hash, timestamp] of commitTimestamps.entries()) {
if (now - timestamp > COMMIT_TTL) {
commitTimestamps.delete(hash);
reportedCommits.delete(hash);
cleaned++;
}
}
2025-02-18 23:20:42 +00:00
console.log('🧹 Cleanup completed:', {
cleaned,
remaining: reportedCommits.size
})
2025-02-18 21:10:44 +00:00
res.status(200).json({ cleaned });
};
/**
* Webhook handler that supports both JSON and x-www-form-urlencoded formats
* @param {Object} req - Express request object
* @param {Object} res - Express response object
*/
const webhook = async (req, res) => {
try {
2025-02-18 23:20:42 +00:00
console.log('🎯 Webhook received:', {
headers: req.headers,
method: req.method,
path: req.path
})
2025-02-18 21:10:44 +00:00
const payload = typeof req.body === 'string' ? JSON.parse(req.body) : req.body
2025-02-18 23:20:42 +00:00
console.log('📦 Payload type:', {
isGitea: !!payload?.repository?.owner?.username,
hasCommits: Array.isArray(payload?.commits),
repoName: payload?.repository?.full_name,
eventType: req.headers['x-github-event'] || req.headers['x-gitea-event'] || 'unknown'
})
2025-02-18 21:10:44 +00:00
if (!payload || !payload.repository) {
2025-02-18 23:20:42 +00:00
console.warn('❌ Invalid payload:', payload)
2025-02-18 21:10:44 +00:00
return res.status(400).send('Invalid webhook payload')
}
// Determine webhook type and handle accordingly
const message = payload.repository.owner?.username // Gitea specific field
? handleGitea(payload, reportedCommits, commitTimestamps)
: handleGithub(payload, reportedCommits, commitTimestamps)
if (!message) {
2025-02-18 23:20:42 +00:00
console.log('⏭️ No new commits to report')
2025-02-18 21:10:44 +00:00
return res.status(200).send('No new commits to report')
}
2025-02-18 23:20:42 +00:00
console.log('📨 Sending message to Telegram:', message)
2025-02-18 21:10:44 +00:00
// Send to Telegram
const telegramUrl = `https://api.telegram.org/bot${process.env.TELEGRAM_BOT_TOKEN}/sendMessage`
2025-02-18 23:20:42 +00:00
const response = await fetch(telegramUrl, {
2025-02-18 21:10:44 +00:00
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
chat_id: `-100${process.env.TELEGRAM_CHAT_ID}`,
text: message,
parse_mode: 'Markdown',
disable_web_page_preview: true
})
})
2025-02-18 23:20:42 +00:00
const telegramResult = await response.json()
console.log('✅ Telegram response:', telegramResult)
2025-02-18 21:10:44 +00:00
res.status(200).send('ok')
} catch (error) {
2025-02-18 23:20:42 +00:00
console.error('💥 Error processing webhook:', error, {
body: req.body,
headers: req.headers
})
2025-02-18 21:10:44 +00:00
res.status(500).send(`Error: ${error.message}`)
}
}
// Export both handlers
module.exports = {
webhook,
cleanup
};