From 0ee9ef176b60c401c4e0d90a015aad5b4c98e8b6 Mon Sep 17 00:00:00 2001 From: Shiv Bhonde Date: Mon, 23 Dec 2024 11:02:37 +0530 Subject: [PATCH 1/2] make request to telegram webhook --- packages/nextjs/.env.example | 8 +++++ packages/nextjs/app/api/grants/new/route.ts | 7 ++++ packages/nextjs/app/api/stages/new/route.ts | 6 ++++ .../nextjs/services/notifications/telegram.ts | 35 +++++++++++++++++++ 4 files changed, 56 insertions(+) create mode 100644 packages/nextjs/services/notifications/telegram.ts diff --git a/packages/nextjs/.env.example b/packages/nextjs/.env.example index fad3dac..968f6e0 100644 --- a/packages/nextjs/.env.example +++ b/packages/nextjs/.env.example @@ -13,3 +13,11 @@ NEXT_PUBLIC_ALCHEMY_API_KEY= NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID= # will be used in production NEXT_PUBLIC_PONDER_URL= + + +POSTGRES_URL="postgresql://postgres:mysecretpassword@localhost:5432/postgres" +NEXTAUTH_URL=http://localhost:3000 +NEXTAUTH_SECRET=somereallysecretsecret + +TELEGRAM_BOT_URL=http://localhost:8080 +TELEGRAM_WEBHOOK_SECRET=your_secret_here diff --git a/packages/nextjs/app/api/grants/new/route.ts b/packages/nextjs/app/api/grants/new/route.ts index d9ef2af..1eed461 100644 --- a/packages/nextjs/app/api/grants/new/route.ts +++ b/packages/nextjs/app/api/grants/new/route.ts @@ -4,6 +4,7 @@ import { parseEther } from "viem"; import { applyFormSchema } from "~~/app/apply/schema"; import { GrantInsert, createGrant } from "~~/services/database/repositories/grants"; import { createStage } from "~~/services/database/repositories/stages"; +import { notifyTelegramBot } from "~~/services/notifications/telegram"; import { authOptions } from "~~/utils/auth"; export type CreateNewGrantReqBody = Omit & { @@ -36,6 +37,12 @@ export async function POST(req: Request) { grantId: createdGrant.id, }); + await notifyTelegramBot("grant", { + id: createdGrant.id, + ...body, + builderAddress, + }); + return NextResponse.json({ grantId: createdGrant.id, stageId: createdStage.id }, { status: 201 }); } catch (error) { console.error(error); diff --git a/packages/nextjs/app/api/stages/new/route.ts b/packages/nextjs/app/api/stages/new/route.ts index 20658f9..915f129 100644 --- a/packages/nextjs/app/api/stages/new/route.ts +++ b/packages/nextjs/app/api/stages/new/route.ts @@ -6,6 +6,7 @@ import deployedContracts from "~~/contracts/deployedContracts"; import scaffoldConfig from "~~/scaffold.config"; import { getGrantById } from "~~/services/database/repositories/grants"; import { StageInsert, createStage, updateStageStatusToCompleted } from "~~/services/database/repositories/stages"; +import { notifyTelegramBot } from "~~/services/notifications/telegram"; import { authOptions } from "~~/utils/auth"; import { EIP_712_DOMAIN, EIP_712_TYPES__APPLY_FOR_STAGE } from "~~/utils/eip712"; import { getAlchemyHttpUrl } from "~~/utils/scaffold-eth"; @@ -93,6 +94,11 @@ export async function POST(req: Request) { stageNumber: latestStage.stageNumber + 1, }); + await notifyTelegramBot("stage", { + newStage: body, + grant: grant, + }); + return NextResponse.json({ grantId: newStage.grantId, stageId: createdStage.id }, { status: 201 }); } catch (error) { console.error(error); diff --git a/packages/nextjs/services/notifications/telegram.ts b/packages/nextjs/services/notifications/telegram.ts new file mode 100644 index 0000000..4938fd4 --- /dev/null +++ b/packages/nextjs/services/notifications/telegram.ts @@ -0,0 +1,35 @@ +const TELEGRAM_BOT_URL = process.env.TELEGRAM_BOT_URL; +const TELEGRAM_WEBHOOK_SECRET = process.env.TELEGRAM_WEBHOOK_SECRET; + +export async function notifyTelegramBot(endpoint: "grant" | "stage", data: unknown) { + if (!TELEGRAM_BOT_URL || !TELEGRAM_WEBHOOK_SECRET) { + if (!TELEGRAM_BOT_URL) { + console.warn("TELEGRAM_BOT_URL is not set. Telegram notifications will be disabled."); + } + + if (!TELEGRAM_WEBHOOK_SECRET) { + console.warn("TELEGRAM_WEBHOOK_SECRET is not set. Telegram notifications will be disabled."); + } + return; + } + + try { + const response = await fetch(`${TELEGRAM_BOT_URL}/webhook/${endpoint}`, { + method: "POST", + headers: { + "Content-Type": "application/json", + "X-Webhook-Secret": TELEGRAM_WEBHOOK_SECRET, + }, + body: JSON.stringify(data), + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + return response.json(); + } catch (error) { + // We don't throw here to prevent the main flow from failing if notifications fail + console.error(`Error notifying Telegram bot (${endpoint}):`, error); + } +} From e17197fc541d503c1d0dae8fa5eeedcf730e9413 Mon Sep 17 00:00:00 2001 From: Shiv Bhonde Date: Mon, 23 Dec 2024 11:59:40 +0530 Subject: [PATCH 2/2] make notifyTelegram func type safe --- .../nextjs/services/notifications/telegram.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/nextjs/services/notifications/telegram.ts b/packages/nextjs/services/notifications/telegram.ts index 4938fd4..dcff723 100644 --- a/packages/nextjs/services/notifications/telegram.ts +++ b/packages/nextjs/services/notifications/telegram.ts @@ -1,7 +1,21 @@ +import { CreateNewGrantReqBody } from "~~/app/api/grants/new/route"; +import { CreateNewStageReqBody } from "~~/app/api/stages/new/route"; +import { GrantWithStages } from "~~/app/grants/[grantId]/page"; + const TELEGRAM_BOT_URL = process.env.TELEGRAM_BOT_URL; const TELEGRAM_WEBHOOK_SECRET = process.env.TELEGRAM_WEBHOOK_SECRET; -export async function notifyTelegramBot(endpoint: "grant" | "stage", data: unknown) { +type StageData = { + newStage: CreateNewStageReqBody; + grant: GrantWithStages; +}; + +type GrantData = CreateNewGrantReqBody & { builderAddress: string }; + +export async function notifyTelegramBot( + endpoint: T, + data: T extends "grant" ? GrantData : StageData, +) { if (!TELEGRAM_BOT_URL || !TELEGRAM_WEBHOOK_SECRET) { if (!TELEGRAM_BOT_URL) { console.warn("TELEGRAM_BOT_URL is not set. Telegram notifications will be disabled.");