fix
This commit is contained in:
@@ -93,3 +93,10 @@ pm2 reload tssbot-web --update-env
|
|||||||
Only processes listed in `PM2_RESTART_TARGETS` are reloaded. The default is
|
Only processes listed in `PM2_RESTART_TARGETS` are reloaded. The default is
|
||||||
`tssbot-web`, so unrelated PM2 processes are left alone. The webhook exits after
|
`tssbot-web`, so unrelated PM2 processes are left alone. The webhook exits after
|
||||||
24 hours so PM2 restarts it cleanly.
|
24 hours so PM2 restarts it cleanly.
|
||||||
|
|
||||||
|
The webhook listener reads `.env` on startup. To send a Discord notification
|
||||||
|
whenever the listener starts or restarts, set:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
|
||||||
|
```
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ module.exports = {
|
|||||||
WEBHOOK_PORT: process.env.WEBHOOK_PORT || 3011,
|
WEBHOOK_PORT: process.env.WEBHOOK_PORT || 3011,
|
||||||
GITHUB_WEBHOOK_SECRET: process.env.GITHUB_WEBHOOK_SECRET || '',
|
GITHUB_WEBHOOK_SECRET: process.env.GITHUB_WEBHOOK_SECRET || '',
|
||||||
PM2_RESTART_TARGETS: process.env.PM2_RESTART_TARGETS || 'tssbot-web',
|
PM2_RESTART_TARGETS: process.env.PM2_RESTART_TARGETS || 'tssbot-web',
|
||||||
|
DISCORD_WEBHOOK_URL: process.env.DISCORD_WEBHOOK_URL || '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -10,3 +10,4 @@ API_RATE_LIMIT_MAX=120
|
|||||||
WEBHOOK_PORT=3011
|
WEBHOOK_PORT=3011
|
||||||
GITHUB_WEBHOOK_SECRET=change-me
|
GITHUB_WEBHOOK_SECRET=change-me
|
||||||
PM2_RESTART_TARGETS=tssbot-web
|
PM2_RESTART_TARGETS=tssbot-web
|
||||||
|
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
|
||||||
|
|||||||
+99
@@ -1,9 +1,44 @@
|
|||||||
const crypto = require('node:crypto')
|
const crypto = require('node:crypto')
|
||||||
|
const fs = require('node:fs')
|
||||||
const http = require('node:http')
|
const http = require('node:http')
|
||||||
|
const https = require('node:https')
|
||||||
|
const os = require('node:os')
|
||||||
|
const path = require('node:path')
|
||||||
const { spawn } = require('node:child_process')
|
const { spawn } = require('node:child_process')
|
||||||
|
|
||||||
|
function loadEnvFile() {
|
||||||
|
const envPath = path.join(__dirname, '.env')
|
||||||
|
if (!fs.existsSync(envPath)) return
|
||||||
|
|
||||||
|
const lines = fs.readFileSync(envPath, 'utf8').split(/\r?\n/)
|
||||||
|
for (const line of lines) {
|
||||||
|
const trimmed = line.trim()
|
||||||
|
if (!trimmed || trimmed.startsWith('#')) continue
|
||||||
|
|
||||||
|
const separatorIndex = trimmed.indexOf('=')
|
||||||
|
if (separatorIndex === -1) continue
|
||||||
|
|
||||||
|
const key = trimmed.slice(0, separatorIndex).trim()
|
||||||
|
let value = trimmed.slice(separatorIndex + 1).trim()
|
||||||
|
|
||||||
|
if (
|
||||||
|
(value.startsWith('"') && value.endsWith('"')) ||
|
||||||
|
(value.startsWith("'") && value.endsWith("'"))
|
||||||
|
) {
|
||||||
|
value = value.slice(1, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key && (!process.env[key] || process.env[key] === '')) {
|
||||||
|
process.env[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loadEnvFile()
|
||||||
|
|
||||||
const PORT = Number(process.env.WEBHOOK_PORT || 3011)
|
const PORT = Number(process.env.WEBHOOK_PORT || 3011)
|
||||||
const SECRET = process.env.GITHUB_WEBHOOK_SECRET || ''
|
const SECRET = process.env.GITHUB_WEBHOOK_SECRET || ''
|
||||||
|
const DISCORD_WEBHOOK_URL = process.env.DISCORD_WEBHOOK_URL || ''
|
||||||
const RESTART_TARGETS = (process.env.PM2_RESTART_TARGETS || 'tssbot-web')
|
const RESTART_TARGETS = (process.env.PM2_RESTART_TARGETS || 'tssbot-web')
|
||||||
.split(',')
|
.split(',')
|
||||||
.map((target) => target.trim())
|
.map((target) => target.trim())
|
||||||
@@ -47,6 +82,69 @@ function run(command, args) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function postDiscordWebhook(payload) {
|
||||||
|
if (!DISCORD_WEBHOOK_URL) return Promise.resolve()
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
let url
|
||||||
|
try {
|
||||||
|
url = new URL(DISCORD_WEBHOOK_URL)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Discord restart webhook URL is invalid:', error.message)
|
||||||
|
resolve()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = Buffer.from(JSON.stringify(payload))
|
||||||
|
const client = url.protocol === 'http:' ? http : https
|
||||||
|
const req = client.request(
|
||||||
|
url,
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/json',
|
||||||
|
'content-length': body.length,
|
||||||
|
'user-agent': 'tssbot-webhook',
|
||||||
|
},
|
||||||
|
timeout: 5000,
|
||||||
|
},
|
||||||
|
(res) => {
|
||||||
|
res.resume()
|
||||||
|
res.on('end', resolve)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
req.on('timeout', () => {
|
||||||
|
req.destroy(new Error('Discord restart webhook timed out'))
|
||||||
|
})
|
||||||
|
req.on('error', (error) => {
|
||||||
|
console.error('Discord restart webhook failed:', error.message)
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
req.end(body)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function notifyDiscordRestart() {
|
||||||
|
const startedAt = new Date()
|
||||||
|
|
||||||
|
postDiscordWebhook({
|
||||||
|
username: 'tssbot webhook',
|
||||||
|
embeds: [
|
||||||
|
{
|
||||||
|
title: 'Webhook listener restarted',
|
||||||
|
color: 0x00f2ff,
|
||||||
|
fields: [
|
||||||
|
{ name: 'Host', value: os.hostname(), inline: true },
|
||||||
|
{ name: 'Port', value: String(PORT), inline: true },
|
||||||
|
{ name: 'Restart targets', value: RESTART_TARGETS.join(', ') || 'none', inline: false },
|
||||||
|
],
|
||||||
|
timestamp: startedAt.toISOString(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async function deploy() {
|
async function deploy() {
|
||||||
await run('git', ['pull', '--ff-only'])
|
await run('git', ['pull', '--ff-only'])
|
||||||
await run('npm', ['install'])
|
await run('npm', ['install'])
|
||||||
@@ -103,6 +201,7 @@ http
|
|||||||
.listen(PORT, '0.0.0.0', () => {
|
.listen(PORT, '0.0.0.0', () => {
|
||||||
console.log(`tssbot webhook listening on http://localhost:${PORT}/github`)
|
console.log(`tssbot webhook listening on http://localhost:${PORT}/github`)
|
||||||
console.log(`restart targets: ${RESTART_TARGETS.join(', ')}`)
|
console.log(`restart targets: ${RESTART_TARGETS.join(', ')}`)
|
||||||
|
notifyDiscordRestart()
|
||||||
})
|
})
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user