diff --git a/package-lock.json b/package-lock.json index 212bf46..1702b3c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@fastify/cors": "^8.4.0", "@fastify/swagger": "^8.12.0", "@fastify/swagger-ui": "^1.10.1", + "@grammyjs/parse-mode": "^1.10.0", "correct-frequency-random-letters": "^1.0.1", "date-fns": "^3.6.0", "dictionary-en": "^3.2.0", @@ -185,10 +186,21 @@ "yaml": "^2.2.2" } }, + "node_modules/@grammyjs/parse-mode": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@grammyjs/parse-mode/-/parse-mode-1.10.0.tgz", + "integrity": "sha512-ZjbY2Ax0b4Nf8lPz3NV0cWDxUC10kOkzgxws+iTdgG+hAiPQVUnP/oJnAKrW1ZQOWULZYQ4GOR/+aCZHyUuLQA==", + "engines": { + "node": ">=14.13.1" + }, + "peerDependencies": { + "grammy": "^1.20.1" + } + }, "node_modules/@grammyjs/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@grammyjs/types/-/types-3.3.0.tgz", - "integrity": "sha512-18Qb12jXiIptqZAlboJMvFxNxydLskUjvE5PbU8ergKQlNIr8jRvYoHDm4t/x3qEfpf+FNhGw23lyZfgEE6e/g==" + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/@grammyjs/types/-/types-3.9.0.tgz", + "integrity": "sha512-QzZAbz5COBZnDlDs6x94TIIIH5Pi7AMk0rJPM2O5JAz5Q+s7Xxp3lGg/pWyiVR9Q8euRDYCJmDtcRjwwFD6a3g==" }, "node_modules/@isaacs/cliui": { "version": "8.0.2", @@ -968,11 +980,11 @@ } }, "node_modules/grammy": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/grammy/-/grammy-1.19.2.tgz", - "integrity": "sha512-bvDWesJgLn65MOsWhShVTVG1bSnh6Yo3OtUwoFzTG21CdPt6r8nzPWcuBSzxMDUQyv8I1c0TXH7zIxXFxiH4sw==", + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/grammy/-/grammy-1.25.1.tgz", + "integrity": "sha512-5BnnWQGUMUwfwkBST6dMRR7A9PS95qXqBMvLeOuJOTfI0RaM7VJATCTrE5HTlnceFPz1L3mxTwNwEmDv3LK/3g==", "dependencies": { - "@grammyjs/types": "3.3.0", + "@grammyjs/types": "3.9.0", "abort-controller": "^3.0.0", "debug": "^4.3.4", "node-fetch": "^2.7.0" @@ -2418,10 +2430,16 @@ "yaml": "^2.2.2" } }, + "@grammyjs/parse-mode": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@grammyjs/parse-mode/-/parse-mode-1.10.0.tgz", + "integrity": "sha512-ZjbY2Ax0b4Nf8lPz3NV0cWDxUC10kOkzgxws+iTdgG+hAiPQVUnP/oJnAKrW1ZQOWULZYQ4GOR/+aCZHyUuLQA==", + "requires": {} + }, "@grammyjs/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@grammyjs/types/-/types-3.3.0.tgz", - "integrity": "sha512-18Qb12jXiIptqZAlboJMvFxNxydLskUjvE5PbU8ergKQlNIr8jRvYoHDm4t/x3qEfpf+FNhGw23lyZfgEE6e/g==" + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/@grammyjs/types/-/types-3.9.0.tgz", + "integrity": "sha512-QzZAbz5COBZnDlDs6x94TIIIH5Pi7AMk0rJPM2O5JAz5Q+s7Xxp3lGg/pWyiVR9Q8euRDYCJmDtcRjwwFD6a3g==" }, "@isaacs/cliui": { "version": "8.0.2", @@ -3006,11 +3024,11 @@ } }, "grammy": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/grammy/-/grammy-1.19.2.tgz", - "integrity": "sha512-bvDWesJgLn65MOsWhShVTVG1bSnh6Yo3OtUwoFzTG21CdPt6r8nzPWcuBSzxMDUQyv8I1c0TXH7zIxXFxiH4sw==", + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/grammy/-/grammy-1.25.1.tgz", + "integrity": "sha512-5BnnWQGUMUwfwkBST6dMRR7A9PS95qXqBMvLeOuJOTfI0RaM7VJATCTrE5HTlnceFPz1L3mxTwNwEmDv3LK/3g==", "requires": { - "@grammyjs/types": "3.3.0", + "@grammyjs/types": "3.9.0", "abort-controller": "^3.0.0", "debug": "^4.3.4", "node-fetch": "^2.7.0" diff --git a/package.json b/package.json index 5374722..6a23438 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "@fastify/cors": "^8.4.0", "@fastify/swagger": "^8.12.0", "@fastify/swagger-ui": "^1.10.1", + "@grammyjs/parse-mode": "^1.10.0", "correct-frequency-random-letters": "^1.0.1", "date-fns": "^3.6.0", "dictionary-en": "^3.2.0", diff --git a/src/bot.ts b/src/bot.ts index 748449a..c130a6d 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -1,18 +1,24 @@ -import { Bot, GrammyError, InlineKeyboard } from "grammy"; -import { GAME_LIST, GAME_START_BUTTON_TEXT } from "./constants"; +import { Bot, Context, GrammyError, InlineKeyboard } from "grammy"; +import { GAME_LIST, GAME_START_BUTTON_TEXT, WELCOME_MESSAGE } from "./constants"; import { getSessionId, throwIfSessionExpired } from "./server/utils"; import { SessionExpiredError } from "./server/errors"; +import { ParseModeFlavor, hydrateReply } from "@grammyjs/parse-mode"; if (!process.env.BOT_API_KEY) { console.error("environment misconfigured"); } if (process.env.BOT_API_KEY == null) throw Error("Telegram bot API token is missing."); -export const bot = new Bot(process.env.BOT_API_KEY!); +export const bot = new Bot>(process.env.BOT_API_KEY!); + +bot.use(hydrateReply); const startingInlineKeyboard = new InlineKeyboard().game(GAME_START_BUTTON_TEXT); -bot.command("start", (ctx) => ctx.reply("Welcome! Up and running.")); +bot.command( + "start", + async (ctx) => await ctx.replyFmt(WELCOME_MESSAGE, { link_preview_options: { is_disabled: true } }), +); bot.command("game", async (ctx) => { await ctx.replyWithGame(process.env.WORD_HUNT_SHORTNAME as string, { diff --git a/src/constants.ts b/src/constants.ts index aff0921..a44aba8 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,3 +1,5 @@ +import { code, fmt, link } from "@grammyjs/parse-mode"; + export enum Game { WORD_HUNT, } @@ -21,7 +23,18 @@ export const TURN_MAX: { [key in Game]: number } = { [Game.WORD_HUNT]: Number.MAX_VALUE, }; -export const GAME_START_BUTTON_TEXT = "Play now!" +export const GAME_START_BUTTON_TEXT = "Play now!"; export const MAX_SESSIONS = 10000; export const NUM_DAYS_SESSION_EXPIRED = 3; + +export const WELCOME_MESSAGE = fmt`Welcome! + +This bot is best used in ${link( + "Inline Mode", + "https://telegram.org/blog/inline-bots", +)}. Just go to your chat then type the name of the bot with a space at the end: ${code( + "@gamejaybot ", +)} and a list of games should show up! You can search through the games by continuing to type your search query. Then, tap on the one you want to start and it will send a new game to the chat you're in. + +Currently, Word Hunt Online is the only game available for GameJay, but more are planned to be added!`;