Skip to content

Commit

Permalink
chore: bot boot rework (#481)
Browse files Browse the repository at this point in the history
  • Loading branch information
hmbanan666 authored Feb 5, 2025
1 parent 4b548e8 commit ce9788c
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 105 deletions.
4 changes: 2 additions & 2 deletions apps/website/server/api/telegram/payment/index.get.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Dictionary } from '@chat-game/locale'
import { createId } from '@paralleldrive/cuid2'
import { dictionary } from '~~/server/core/locale'
import { gameBot } from '~~/server/core/telegram/bot'
import { useGameBot } from '~~/server/core/telegram/bot'
import { validateTelegramData } from '~~/server/core/telegram/validate'

export default defineEventHandler(async (event) => {
Expand Down Expand Up @@ -60,7 +60,7 @@ export default defineEventHandler(async (event) => {

// Create invoice via bot
const paymentId = createId()
const link = await gameBot.api.createInvoiceLink(
const link = await useGameBot().api.createInvoiceLink(
title,
description,
`{"payment_id":"${paymentId}"}`,
Expand Down
160 changes: 87 additions & 73 deletions apps/website/server/core/telegram/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,90 +11,104 @@ const gameUrl = `tg://resolve?domain=woodlandsgamebot&appname=game&startapp=${st
const gameChannelUrl = 'https://t.me/chatgamespace'
const chatgameUrl = 'https://chatgame.space'

const gameBot = new Bot(telegramGameBotToken)

gameBot.on('message:text', async (ctx) => {
try {
const locale = ctx.message.from.language_code

if (ctx.hasCommand('start')) {
// Tree sticker
// await ctx.replyWithSticker('CAACAgEAAxkBAAENexdng5nCguO04hJRGAABxUYQUdZlkmMAAj8CAALjmxhEgCIYC2AbEOM2BA')

// Welcome message with buttons
await ctx.reply(
dictionary(locale).bots.woodland.welcomeMessage,
{
reply_markup: {
inline_keyboard: [
[{ text: dictionary(locale).bots.woodland.play, url: gameUrl }],
[{ text: dictionary(locale).bots.subscribeToChannel, url: gameChannelUrl }],
[{ text: dictionary(locale).bots.woodland.website, url: chatgameUrl }],
],
let gameBot: Bot | null = null

function useCreateGameBot() {
gameBot = new Bot(telegramGameBotToken)

gameBot.on('message:text', async (ctx) => {
try {
const locale = ctx.message.from.language_code

if (ctx.hasCommand('start')) {
// Tree sticker
// await ctx.replyWithSticker('CAACAgEAAxkBAAENexdng5nCguO04hJRGAABxUYQUdZlkmMAAj8CAALjmxhEgCIYC2AbEOM2BA')

// Welcome message with buttons
await ctx.reply(
dictionary(locale).bots.woodland.welcomeMessage,
{
reply_markup: {
inline_keyboard: [
[{ text: dictionary(locale).bots.woodland.play, url: gameUrl }],
[{ text: dictionary(locale).bots.subscribeToChannel, url: gameChannelUrl }],
[{ text: dictionary(locale).bots.woodland.website, url: chatgameUrl }],
],
},
},
},
)
)

return
}

logger.log(ctx.message.from.id, ctx.message.text)
ctx.reply(dictionary(locale).bots.defaultBotReply)
} catch (error) {
logger.error(error)
}
})

// regexp: id in object like { payment_id: 123 }
gameBot.preCheckoutQuery(/.+/, async (ctx) => {
try {
const invoicePayload = JSON.parse(ctx.preCheckoutQuery.invoice_payload)
return
}

// Telegram payment in stars
if (invoicePayload?.payment_id) {
await ctx.answerPreCheckoutQuery(true)
logger.log(ctx.message.from.id, ctx.message.text)
ctx.reply(dictionary(locale).bots.defaultBotReply)
} catch (error) {
logger.error(error)
}
} catch (error) {
logger.error(error)
}
})
})

// successful_payment
gameBot.on('message:successful_payment', async (ctx) => {
try {
if (ctx?.message?.successful_payment?.invoice_payload && ctx?.message?.successful_payment?.telegram_payment_charge_id) {
const invoicePayload = JSON.parse(ctx.message.successful_payment.invoice_payload)
// regexp: id in object like { payment_id: 123 }
gameBot.preCheckoutQuery(/.+/, async (ctx) => {
try {
const invoicePayload = JSON.parse(ctx.preCheckoutQuery.invoice_payload)

// Telegram payment in stars
if (invoicePayload?.payment_id) {
const id = invoicePayload?.payment_id as string
const telegramChargeId = ctx.message.successful_payment.telegram_payment_charge_id

const payment = await prisma.payment.findFirst({
where: { id },
})
if (!payment) {
return
await ctx.answerPreCheckoutQuery(true)
}
} catch (error) {
logger.error(error)
}
})

// successful_payment
gameBot.on('message:successful_payment', async (ctx) => {
try {
if (ctx?.message?.successful_payment?.invoice_payload && ctx?.message?.successful_payment?.telegram_payment_charge_id) {
const invoicePayload = JSON.parse(ctx.message.successful_payment.invoice_payload)

// Telegram payment in stars
if (invoicePayload?.payment_id) {
const id = invoicePayload?.payment_id as string
const telegramChargeId = ctx.message.successful_payment.telegram_payment_charge_id

const payment = await prisma.payment.findFirst({
where: { id },
})
if (!payment) {
return
}

await prisma.payment.update({
where: { id },
data: {
status: 'PAID',
telegramChargeId,
},
})

await activateProduct({ productId: payment.productId, profileId: payment.profileId })

await notifyAdmin(`[Woodlands] Профиль ${payment.profileId} совершил покупку. +${payment.amount} XTR`)
}

await prisma.payment.update({
where: { id },
data: {
status: 'PAID',
telegramChargeId,
},
})

await activateProduct({ productId: payment.productId, profileId: payment.profileId })

await notifyAdmin(`[Woodlands] Профиль ${payment.profileId} совершил покупку. +${payment.amount} XTR`)
}

logger.log('message:successful_payment', ctx?.message?.successful_payment)
} catch (error) {
logger.error(error)
}
})

gameBot.start()
}

logger.log('message:successful_payment', ctx?.message?.successful_payment)
} catch (error) {
logger.error(error)
function useGameBot(): Bot {
if (!gameBot) {
throw new Error('Bot is not created')
}
})

export { gameBot }
return gameBot
}

export { useCreateGameBot, useGameBot }
4 changes: 2 additions & 2 deletions apps/website/server/core/telegram/notification.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { gameBot } from './bot'
import { useGameBot } from './bot'

export async function sendNotificationToAllPlayers() {
const telegramProfiles = await prisma.telegramProfile.findMany()

for (const telegramProfile of telegramProfiles) {
try {
await gameBot.api.sendMessage(telegramProfile.telegramId, `Появилась возможность активировать предметы в Инвентаре! 🎉
await useGameBot().api.sendMessage(telegramProfile.telegramId, `Появилась возможность активировать предметы в Инвентаре! 🎉

Кладу тебе в Инвентарь Банан 🍌 Можешь его съесть и получить награду.`, {
reply_markup: {
Expand Down
62 changes: 38 additions & 24 deletions apps/website/server/core/telegram/oldBot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,49 @@ const gameChannelUrl = 'https://t.me/chatgamespace'
const woodlandsBotUrl = 'https://t.me/WoodlandsGameBot'
const twitchUrl = 'https://twitch.tv/hmbanan666'

const bot = new Bot(telegramBotToken)

bot.on('message:text', async (ctx) => {
const locale = ctx.message.from.language_code

if (ctx.hasCommand('start')) {
// Welcome message with buttons
await ctx.reply(
dictionary(locale).bots.chatgame.welcomeMessage,
{
reply_markup: {
inline_keyboard: [
[{ text: dictionary(locale).bots.woodland.title, url: woodlandsBotUrl }],
[{ text: dictionary(locale).bots.subscribeToChannel, url: gameChannelUrl }],
[{ text: dictionary(locale).bots.chatgame.playingOnTwitch, url: twitchUrl }],
],
let bot: Bot | null = null

function useCreateBot() {
bot = new Bot(telegramBotToken)

bot.on('message:text', async (ctx) => {
const locale = ctx.message.from.language_code

if (ctx.hasCommand('start')) {
// Welcome message with buttons
await ctx.reply(
dictionary(locale).bots.chatgame.welcomeMessage,
{
reply_markup: {
inline_keyboard: [
[{ text: dictionary(locale).bots.woodland.title, url: woodlandsBotUrl }],
[{ text: dictionary(locale).bots.subscribeToChannel, url: gameChannelUrl }],
[{ text: dictionary(locale).bots.chatgame.playingOnTwitch, url: twitchUrl }],
],
},
},
},
)
)

return
return
}

logger.log(ctx.message.from.id, ctx.message.text)
ctx.reply(dictionary(locale).bots.defaultBotReply)
})

bot.start()
}

function useBot(): Bot {
if (!bot) {
throw new Error('Bot is not created')
}

logger.log(ctx.message.from.id, ctx.message.text)
ctx.reply(dictionary(locale).bots.defaultBotReply)
})
return bot
}

async function notifyAdmin(message: string) {
return bot.api.sendMessage(telegramAdminId, message)
return useBot().api.sendMessage(telegramAdminId, message)
}

export { bot, notifyAdmin }
export { notifyAdmin, useBot, useCreateBot }
8 changes: 4 additions & 4 deletions apps/website/server/plugins/03.startTelegram.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import process from 'node:process'
import { gameBot } from '../core/telegram/bot'
import { bot } from '../core/telegram/oldBot'
import { useCreateGameBot } from '../core/telegram/bot'
import { useCreateBot } from '../core/telegram/oldBot'

export default defineNitroPlugin(() => {
if (process.env.NODE_ENV !== 'production') {
Expand All @@ -16,8 +16,8 @@ export default defineNitroPlugin(() => {
}

// Start the bots (using long polling)
bot.start()
gameBot.start()
useCreateBot()
useCreateGameBot()

logger.success('Telegram server started')
})

0 comments on commit ce9788c

Please sign in to comment.