reviewbot

Source code for the is-a.dev r...
Log | Files | Refs | README | LICENSE

index.js (8383B)


      1 import * as Sentry from '@sentry/node';
      2 import fs from 'fs';
      3 import path from 'path';
      4 import dotenv from 'dotenv';
      5 import middie from '@fastify/middie';
      6 import Fastify from 'fastify';
      7 import Database from 'better-sqlite3';
      8 
      9 import { App } from 'octokit';
     10 import { createNodeMiddleware } from '@octokit/webhooks';
     11 import { CronJob } from 'cron';
     12 
     13 import { getNumberOfDays } from './tools/numberofdays.js';
     14 
     15 import { unlabeled } from './webhooks/unlabeled.js';
     16 import { opened } from './webhooks/opened.js';
     17 import { closed } from './webhooks/closed.js';
     18 import { labeled } from './webhooks/labeled.js';
     19 
     20 // Load environment variables from .env file
     21 dotenv.config();
     22 
     23 // Set configured values
     24 const sentryDsn = process.env.SENTRY;
     25 const appId = process.env.APP_ID;
     26 const installationId = process.env.INSTALLATION_ID;
     27 const privateKey = fs.readFileSync(
     28     path.resolve(process.env.PRIVATE_KEY_PATH),
     29     'utf8'
     30 );
     31 const secret = process.env.WEBHOOK_SECRET;
     32 export const numberOfDays = 3;
     33 
     34 Sentry.init({
     35     dsn: sentryDsn,
     36     // Tracing
     37     tracesSampleRate: 1.0, // Capture 100% of the transactions
     38     // Enable logs to be sent to Sentry
     39     enableLogs: true,
     40 });
     41 
     42 // Database
     43 
     44 export const db = new Database(process.env.DB_PATH);
     45 
     46 /*db.exec(`
     47   CREATE TABLE LIST (
     48     username TEXT NOT NULL,
     49     prnumber TEXT NOT NULL,
     50     time TEXT NOT NULL,
     51     repoowner TEXT NOT NULL,
     52     repo TEXT NOT NULL
     53   );
     54 `);*/
     55 
     56 // Create an authenticated Octokit client authenticated as a GitHub App
     57 const app = new App({
     58     appId,
     59     privateKey,
     60     webhooks: {
     61         secret,
     62     },
     63 });
     64 
     65 const appOctokit = await app.getInstallationOctokit(installationId);
     66 
     67 /*
     68 saving this for incase
     69 
     70 const installationOctokit = new Octokit({
     71     authStrategy: createAppAuth,
     72     auth: {
     73         appId,
     74         privateKey,
     75         installationId,
     76     },
     77 });
     78 */
     79 
     80 // Get & log the authenticated app's name
     81 const { data } = await app.octokit.request('/app');
     82 
     83 // https://github.com/octokit/core.js#logging
     84 app.octokit.log.debug(`Authenticated as '${data.name}'`);
     85 
     86 // Check if a low priority pull request has been in the database for over 3 days
     87 let job = new CronJob(
     88     '0 * * * *', // cronTime 0 * * * *
     89     async function () {
     90         let date = new Date();
     91         try {
     92             let res = await db.prepare(`SELECT * FROM LIST`).all();
     93             let resJson = JSON.stringify(res);
     94             if (resJson !== '[]') {
     95                 let parsed = JSON.parse(resJson);
     96                 for (let i in parsed) {
     97                     if (getNumberOfDays(parsed[i].time, date) >= numberOfDays) {
     98                         await db
     99                             .prepare(`DELETE FROM LIST WHERE time = ?`)
    100                             .run(parsed[i].time);
    101                         await appOctokit.request(
    102                             'DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels/{name}',
    103                             {
    104                                 owner: parsed[i].repoowner,
    105                                 repo: parsed[i].repo,
    106                                 issue_number: parsed[i].prnumber,
    107                                 name: 'status: low priority',
    108                             }
    109                         );
    110                         console.log(
    111                             `Removed #${parsed[i].prnumber} from the database since it has existed for 3 or more days.`
    112                         );
    113                     }
    114                 }
    115             } else if (resJson === '[]') {
    116                 return;
    117             }
    118         } catch (error) {
    119             Sentry.captureException(error);
    120             fastify.log.error(error);
    121             if (error.response) {
    122                 console.error(
    123                     `Error! Status: ${error.response.status}. Message: ${error.response.data.message}`
    124                 );
    125             } else {
    126                 console.error(error);
    127             }
    128         }
    129     }, // onTick
    130     null, // onComplete
    131     true, // start
    132     'Europe/Bucharest' // timeZone
    133 );
    134 
    135 app.webhooks.on('pull_request.opened', async ({ payload }) => {
    136     try {
    137         await opened(
    138             appOctokit,
    139             payload.repository.owner.login,
    140             payload.repository.name,
    141             payload.repository.full_name,
    142             payload.pull_request.number,
    143             payload.pull_request.updated_at,
    144             payload.pull_request.user.login,
    145             payload.pull_request.draft
    146         );
    147     } catch (error) {
    148         Sentry.captureException(error);
    149         fastify.log.error(error);
    150         if (error.response) {
    151             console.error(
    152                 `Error! Status: ${error.response.status}. Message: ${error.response.data.message}`
    153             );
    154         } else {
    155             console.error(error);
    156         }
    157     }
    158 });
    159 
    160 // https://github.com/octokit/webhooks.js/?tab=readme-ov-file#webhook-events
    161 app.webhooks.on('pull_request.closed', async ({ payload }) => {
    162     console.log(
    163         `Received a closed pull request event for #${payload.pull_request.number} on https://github.com/${payload.repository.full_name}`
    164     );
    165     try {
    166         await closed(
    167             appOctokit,
    168             payload.pull_request.merged,
    169             payload.repository.owner.login,
    170             payload.repository.name,
    171             payload.repository.full_name,
    172             payload.pull_request.number,
    173             payload.pull_request.user.login,
    174             payload.sender.login
    175         );
    176     } catch (error) {
    177         Sentry.captureException(error);
    178         fastify.log.error(error);
    179         if (error.response) {
    180             console.error(
    181                 `Error! Status: ${error.response.status}. Message: ${error.response.data.message}`
    182             );
    183         } else {
    184             console.error(error);
    185         }
    186     }
    187 });
    188 
    189 // Label system
    190 app.webhooks.on('pull_request.labeled', async ({ payload }) => {
    191     try {
    192         await labeled(
    193             appOctokit,
    194             payload.label.name,
    195             payload.repository.owner.login,
    196             payload.repository.name,
    197             payload.repository.full_name,
    198             payload.pull_request.number,
    199             payload.pull_request.updated_at,
    200             payload.pull_request.user.login
    201         );
    202     } catch (error) {
    203         Sentry.captureException(error);
    204         fastify.log.error(error);
    205         if (error.response) {
    206             console.error(
    207                 `Error! Status: ${error.response.status}. Message: ${error.response.data.message}`
    208             );
    209         } else {
    210             console.error(error);
    211         }
    212     }
    213 });
    214 
    215 app.webhooks.on('pull_request.unlabeled', async ({ payload }) => {
    216     try {
    217         await unlabeled(
    218             payload.label.name,
    219             payload.pull_request.user.login,
    220             payload.pull_request.number,
    221             payload.repository.full_name
    222         );
    223     } catch (error) {
    224         Sentry.captureException(error);
    225         fastify.log.error(error);
    226         if (error.response) {
    227             console.error(
    228                 `Error! Status: ${error.response.status}. Message: ${error.response.data.message}`
    229             );
    230         } else {
    231             console.error(error);
    232         }
    233     }
    234 });
    235 
    236 // Handle errors
    237 app.webhooks.onError((error) => {
    238     Sentry.captureException(error);
    239     fastify.log.error(error);
    240     if (error.name === 'AggregateError') {
    241         // Log Secret verification errors
    242         console.log(`Error processing request: ${error.event}`);
    243     } else {
    244         console.log(error);
    245     }
    246 });
    247 
    248 // Launch a web server to listen for GitHub webhooks
    249 const port = process.env.PORT || 3000;
    250 const host = process.env.NODE_ENV === 'production' ? '0.0.0.0' : 'localhost';
    251 const webhookPath = '/api/webhook';
    252 const localWebhookUrl = `http://${host}:${port}${webhookPath}`;
    253 
    254 // https://github.com/octokit/webhooks.js/#createnodemiddleware
    255 const middleware = createNodeMiddleware(app.webhooks, { path: webhookPath });
    256 
    257 const fastify = Fastify({
    258     logger: false,
    259 });
    260 await fastify.register(middie);
    261 fastify.use(middleware);
    262 
    263 await fastify.listen({ port, host });
    264 
    265 console.log(`Server is listening for events at: ${localWebhookUrl}`);
    266 console.log('Press Ctrl + C to quit.');
    267 
    268 /*
    269 Standard node http server (use "import http from 'http' if you want to use this instead of Fastify")
    270 
    271 http.createServer(middleware).listen(port, () => {
    272   console.log(`Server is listening for events at: ${localWebhookUrl}`)
    273   console.log('Press Ctrl + C to quit.')
    274 })
    275 */
© notamitgamer • Site Built: 2026-07-21 13:58:23 UTC • git-mirror commit: 1037f62 [view raw info]
Originally created with stagit • modified by notamitgamer
Forked from github.com/notamitgamer/git-mirror