create-bunspace 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/templates/monorepo/apps/example/package.json +1 -1
  2. package/dist/templates/monorepo/core/packages/utils/rolldown.config.ts +30 -0
  3. package/dist/templates/monorepo/tsconfig.json +3 -1
  4. package/dist/templates/telegram-bot/bun.lock +6 -20
  5. package/dist/templates/telegram-bot/core/package.json +11 -0
  6. package/dist/templates/telegram-bot/core/rolldown.config.ts +11 -0
  7. package/dist/templates/telegram-bot/core/src/config/logging.ts +1 -3
  8. package/dist/templates/telegram-bot/core/src/handlers/config-export.ts +10 -9
  9. package/dist/templates/telegram-bot/core/src/handlers/control.ts +30 -21
  10. package/dist/templates/telegram-bot/core/src/handlers/demo-full.ts +58 -0
  11. package/dist/templates/telegram-bot/core/src/handlers/demo-keyboard.ts +49 -0
  12. package/dist/templates/telegram-bot/core/src/handlers/demo-media.ts +163 -0
  13. package/dist/templates/telegram-bot/core/src/handlers/demo-text.ts +27 -0
  14. package/dist/templates/telegram-bot/core/src/handlers/health.ts +22 -14
  15. package/dist/templates/telegram-bot/core/src/handlers/info.ts +21 -23
  16. package/dist/templates/telegram-bot/core/src/handlers/logs.ts +8 -6
  17. package/dist/templates/telegram-bot/core/src/index.ts +20 -1
  18. package/dist/templates/telegram-bot/core/src/utils/formatters.ts +5 -60
  19. package/dist/templates/telegram-bot/core/tsconfig.json +2 -0
  20. package/dist/templates/telegram-bot/package.json +3 -2
  21. package/dist/templates/telegram-bot/packages/utils/package.json +12 -1
  22. package/dist/templates/telegram-bot/packages/utils/rolldown.config.ts +11 -0
  23. package/dist/templates/telegram-bot/packages/utils/tsconfig.json +10 -0
  24. package/dist/templates/telegram-bot/tsconfig.json +7 -2
  25. package/package.json +1 -1
  26. package/templates/monorepo/apps/example/package.json +1 -1
  27. package/templates/monorepo/core/packages/utils/rolldown.config.ts +30 -0
  28. package/templates/monorepo/tsconfig.json +3 -1
  29. package/templates/telegram-bot/bun.lock +6 -20
  30. package/templates/telegram-bot/core/package.json +11 -0
  31. package/templates/telegram-bot/core/rolldown.config.ts +11 -0
  32. package/templates/telegram-bot/core/src/config/logging.ts +1 -3
  33. package/templates/telegram-bot/core/src/handlers/config-export.ts +10 -9
  34. package/templates/telegram-bot/core/src/handlers/control.ts +30 -21
  35. package/templates/telegram-bot/core/src/handlers/demo-full.ts +58 -0
  36. package/templates/telegram-bot/core/src/handlers/demo-keyboard.ts +49 -0
  37. package/templates/telegram-bot/core/src/handlers/demo-media.ts +163 -0
  38. package/templates/telegram-bot/core/src/handlers/demo-text.ts +27 -0
  39. package/templates/telegram-bot/core/src/handlers/health.ts +22 -14
  40. package/templates/telegram-bot/core/src/handlers/info.ts +21 -23
  41. package/templates/telegram-bot/core/src/handlers/logs.ts +8 -6
  42. package/templates/telegram-bot/core/src/index.ts +20 -1
  43. package/templates/telegram-bot/core/src/utils/formatters.ts +5 -60
  44. package/templates/telegram-bot/core/tsconfig.json +2 -0
  45. package/templates/telegram-bot/package.json +3 -2
  46. package/templates/telegram-bot/packages/utils/package.json +12 -1
  47. package/templates/telegram-bot/packages/utils/rolldown.config.ts +11 -0
  48. package/templates/telegram-bot/packages/utils/tsconfig.json +10 -0
  49. package/templates/telegram-bot/tsconfig.json +7 -2
  50. package/templates/telegram-bot/core/src/utils/message-builder.ts +0 -180
@@ -5,7 +5,7 @@
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "bun --watch src/index.ts",
8
- "build": "bun build src/index.ts --outdir ./dist",
8
+ "build": "bun build src/index.ts --outdir ./dist --sourcemap && tsgo --emitDeclarationOnly",
9
9
  "typecheck": "tsgo --noEmit",
10
10
  "start": "bun run dist/index.js"
11
11
  },
@@ -11,6 +11,16 @@ export default defineConfig([
11
11
  },
12
12
  external: ['@mks2508/better-logger', '@mks2508/no-throw'],
13
13
  },
14
+ {
15
+ input: './src/index.ts',
16
+ output: {
17
+ file: './dist/index.cjs',
18
+ format: 'cjs',
19
+ exports: 'named',
20
+ sourcemap: true,
21
+ },
22
+ external: ['@mks2508/better-logger', '@mks2508/no-throw'],
23
+ },
14
24
  {
15
25
  input: './src/logger.ts',
16
26
  output: {
@@ -21,6 +31,16 @@ export default defineConfig([
21
31
  },
22
32
  external: ['@mks2508/better-logger'],
23
33
  },
34
+ {
35
+ input: './src/logger.ts',
36
+ output: {
37
+ file: './dist/logger.cjs',
38
+ format: 'cjs',
39
+ exports: 'named',
40
+ sourcemap: true,
41
+ },
42
+ external: ['@mks2508/better-logger'],
43
+ },
24
44
  {
25
45
  input: './src/result.ts',
26
46
  output: {
@@ -31,4 +51,14 @@ export default defineConfig([
31
51
  },
32
52
  external: ['@mks2508/no-throw'],
33
53
  },
54
+ {
55
+ input: './src/result.ts',
56
+ output: {
57
+ file: './dist/result.cjs',
58
+ format: 'cjs',
59
+ exports: 'named',
60
+ sourcemap: true,
61
+ },
62
+ external: ['@mks2508/no-throw'],
63
+ },
34
64
  ]);
@@ -29,7 +29,9 @@
29
29
  "declaration": true,
30
30
  "declarationMap": true,
31
31
  "sourceMap": true,
32
- "removeComments": false
32
+ "removeComments": false,
33
+ "outDir": "./dist",
34
+ "declarationDir": "./dist"
33
35
  },
34
36
  "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"]
35
37
  }
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "lockfileVersion": 1,
3
+ "configVersion": 0,
3
4
  "workspaces": {
4
5
  "": {
5
6
  "name": "mks-telegram-bot",
6
7
  "dependencies": {
7
- "@flla/telegram-format": "^3.1.2",
8
8
  "@inquirer/prompts": "^8.1.0",
9
+ "@mks2508/telegram-bot-utils": "workspace:*",
10
+ "@mks2508/telegram-message-builder": "0.3.1",
9
11
  "chalk": "^5.6.2",
10
12
  "commander": "^14.0.2",
11
13
  "dotenv": "^17.2.3",
@@ -27,25 +29,11 @@
27
29
  "version": "0.1.0",
28
30
  "dependencies": {
29
31
  "@mks2508/telegram-bot-utils": "workspace:*",
32
+ "@mks2508/telegram-message-builder": "0.3.1",
30
33
  "telegraf": "^4.16.3",
31
34
  "zod": "^3.24.0",
32
35
  },
33
36
  },
34
- "packages/bootstrapper": {
35
- "name": "@mks2508/bootstrapper",
36
- "version": "0.1.0",
37
- "dependencies": {
38
- "@inquirer/prompts": "^8.1.0",
39
- "@mks2508/better-logger": "^4.0.0",
40
- "big-integer": "^1.6.52",
41
- "telegraf": "^4.16.3",
42
- "telegram": "^2.26.22",
43
- },
44
- "devDependencies": {
45
- "@types/node": "^20",
46
- "typescript": "^5",
47
- },
48
- },
49
37
  "packages/utils": {
50
38
  "name": "@mks2508/telegram-bot-utils",
51
39
  "version": "0.1.0",
@@ -58,8 +46,6 @@
58
46
  "packages": {
59
47
  "@cryptography/aes": ["@cryptography/aes@0.1.1", "", {}, "sha512-PcYz4FDGblO6tM2kSC+VzhhK62vml6k6/YAkiWtyPvrgJVfnDRoHGDtKn5UiaRRUrvUTTocBpvc2rRgTCqxjsg=="],
60
48
 
61
- "@flla/telegram-format": ["@flla/telegram-format@3.1.2", "", {}, "sha512-pmBcT0f2ay77WlVq0EX3KseFp07IXU7QYahsY/Halx4/YnsM70qYeLRBoKysukU/l0ZQ2u15xu9rMECm9ov2+A=="],
62
-
63
49
  "@inquirer/ansi": ["@inquirer/ansi@2.0.2", "", {}, "sha512-SYLX05PwJVnW+WVegZt1T4Ip1qba1ik+pNJPDiqvk6zS5Y/i8PhRzLpGEtVd7sW0G8cMtkD8t4AZYhQwm8vnww=="],
64
50
 
65
51
  "@inquirer/checkbox": ["@inquirer/checkbox@5.0.3", "", { "dependencies": { "@inquirer/ansi": "^2.0.2", "@inquirer/core": "^11.1.0", "@inquirer/figures": "^2.0.2", "@inquirer/type": "^4.0.2" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-xtQP2eXMFlOcAhZ4ReKP2KZvDIBb1AnCfZ81wWXG3DXLVH0f0g4obE0XDPH+ukAEMRcZT0kdX2AS1jrWGXbpxw=="],
@@ -98,14 +84,14 @@
98
84
 
99
85
  "@mks2508/better-logger": ["@mks2508/better-logger@4.0.0", "", { "dependencies": { "chalk": "^5.6.2" } }, "sha512-39PYkAKg7kC0ncPjcN5zAwTsLIS+iXoL4294gl3Cm4OAI6sAT7YJ+RccD42Ve5ybRC/TGgJnD0AUH5M26w0pWA=="],
100
86
 
101
- "@mks2508/bootstrapper": ["@mks2508/bootstrapper@workspace:packages/bootstrapper"],
102
-
103
87
  "@mks2508/no-throw": ["@mks2508/no-throw@0.1.0", "", {}, "sha512-/CI8FqiO3oLw66XIQ07mw13b6PDNh1vit0cGzUBLq5MfJUTKDU0yaKFE0l9CqSpe6xv4n4+z4RWEytP5xePKZQ=="],
104
88
 
105
89
  "@mks2508/telegram-bot-core": ["@mks2508/telegram-bot-core@workspace:core"],
106
90
 
107
91
  "@mks2508/telegram-bot-utils": ["@mks2508/telegram-bot-utils@workspace:packages/utils"],
108
92
 
93
+ "@mks2508/telegram-message-builder": ["@mks2508/telegram-message-builder@0.3.1", "", {}, "sha512-i/BdbxVq13l8XzCUq8jMkFfYjrTXiCdErpzo9tEazLLqqEucAm2aY9HE5i8U+15mEWeSV4D6I9gfU8a5dSn1Cw=="],
94
+
109
95
  "@oxlint/darwin-arm64": ["@oxlint/darwin-arm64@1.38.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-9rN3047QTyA4i73FKikDUBdczRcLtOsIwZ5TsEx5Q7jr5nBjolhYQOFQf9QdhBLdInxw1iX4+lgdMCf1g74zjg=="],
110
96
 
111
97
  "@oxlint/darwin-x64": ["@oxlint/darwin-x64@1.38.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-Y1UHW4KOlg5NvyrSn/bVBQP8/LRuid7Pnu+BWGbAVVsFcK0b565YgMSO3Eu9nU3w8ke91dr7NFpUmS+bVkdkbw=="],
@@ -3,13 +3,24 @@
3
3
  "version": "0.1.0",
4
4
  "type": "module",
5
5
  "scripts": {
6
+ "build": "rolldown --config rolldown.config.ts && tsgo --emitDeclarationOnly",
6
7
  "dev": "bun run --watch src/index.ts",
7
8
  "start": "bun run src/index.ts",
8
9
  "typecheck": "tsgo --noEmit"
9
10
  },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
10
17
  "dependencies": {
11
18
  "@mks2508/telegram-bot-utils": "workspace:*",
19
+ "@mks2508/telegram-message-builder": "0.3.1",
12
20
  "telegraf": "^4.16.3",
13
21
  "zod": "^3.24.0"
22
+ },
23
+ "devDependencies": {
24
+ "rolldown": "^1.0.0-beta.58"
14
25
  }
15
26
  }
@@ -0,0 +1,11 @@
1
+ import { defineConfig } from 'rolldown';
2
+
3
+ export default defineConfig({
4
+ input: './src/index.ts',
5
+ output: {
6
+ file: './dist/index.js',
7
+ format: 'esm',
8
+ sourcemap: true,
9
+ },
10
+ external: ['grammy', 'telegraf', '@mks2508/telegram-bot-utils', '@mks2508/telegram-message-builder', 'zod'],
11
+ });
@@ -54,9 +54,7 @@ let fileHandlersInitialized = false
54
54
  * fileLogLevels: ['error', 'critical']
55
55
  * })
56
56
  */
57
- export function initializeFileLogging(
58
- config: Partial<FileLoggingConfig> = {}
59
- ): void {
57
+ export function initializeFileLogging(config: Partial<FileLoggingConfig> = {}): void {
60
58
  // Setup logger with debug/logLevel options
61
59
  const appConfig = getConfig()
62
60
  setupLogger({ debug: appConfig.debug, logLevel: appConfig.logLevel })
@@ -2,7 +2,7 @@ import type { Context } from 'telegraf'
2
2
  import { badge, kv, colors, colorText } from '../middleware/logging.js'
3
3
  import { getConfig } from '../config/index.js'
4
4
  import { configLogger } from '@mks2508/telegram-bot-utils'
5
- import { MessageBuilder } from '../utils/message-builder.js'
5
+ import { TelegramMessageBuilder } from '@mks2508/telegram-message-builder'
6
6
 
7
7
  const collectedTopics = new Map<number, string>()
8
8
 
@@ -19,14 +19,14 @@ export async function handleExportConfig(ctx: Context): Promise<void> {
19
19
  )
20
20
 
21
21
  const config = getConfig()
22
- const builder = MessageBuilder.markdown()
22
+ const builder = TelegramMessageBuilder.text()
23
23
 
24
24
  // Title
25
25
  builder.title('🔧 Current Configuration')
26
26
  builder.newline()
27
27
 
28
28
  // Environment
29
- builder.section('Environment:')
29
+ builder.section('Environment')
30
30
  builder.line('TG_ENV', config.environment, { code: true })
31
31
  builder.line('TG_INSTANCE_NAME', config.instanceName, { code: true })
32
32
  builder.line('TG_MODE', config.mode, { code: true })
@@ -35,13 +35,13 @@ export async function handleExportConfig(ctx: Context): Promise<void> {
35
35
  // Bot Token (masked)
36
36
  if (config.botToken) {
37
37
  const masked = config.botToken.slice(0, 6) + '...' + config.botToken.slice(-6)
38
- builder.section('Bot:')
38
+ builder.section('Bot')
39
39
  builder.line('TG_BOT_TOKEN', masked, { code: true })
40
40
  builder.newline()
41
41
  }
42
42
 
43
43
  // Control
44
- builder.section('Control Commands:')
44
+ builder.section('Control Commands')
45
45
  if (config.controlChatId) {
46
46
  builder.line('TG_CONTROL_CHAT_ID', String(config.controlChatId), { code: true })
47
47
  } else {
@@ -61,7 +61,7 @@ export async function handleExportConfig(ctx: Context): Promise<void> {
61
61
  }
62
62
 
63
63
  // Logging
64
- builder.section('Logging:')
64
+ builder.section('Logging')
65
65
  if (config.logChatId) {
66
66
  builder.line('TG_LOG_CHAT_ID', String(config.logChatId), { code: true })
67
67
  } else {
@@ -77,7 +77,7 @@ export async function handleExportConfig(ctx: Context): Promise<void> {
77
77
 
78
78
  // Webhook
79
79
  if (config.mode === 'webhook') {
80
- builder.section('Webhook:')
80
+ builder.section('Webhook')
81
81
  builder.line('TG_WEBHOOK_URL', config.webhookUrl || 'not_set', { code: true })
82
82
  builder.line('TG_WEBHOOK_SECRET', config.webhookSecret || 'not_set', { code: true })
83
83
  builder.newline()
@@ -89,13 +89,14 @@ export async function handleExportConfig(ctx: Context): Promise<void> {
89
89
  builder.newline()
90
90
 
91
91
  // Instructions
92
- builder.section('📋 Quick Setup:')
92
+ builder.section('📋 Quick Setup')
93
93
  builder.listItem('Create topics: General, Control, Logs')
94
94
  builder.listItem('Mention @bot_username in each topic')
95
95
  builder.listItem('Use /getinfo to get Thread IDs')
96
96
  builder.listItem('Update .env with the IDs')
97
97
 
98
- await ctx.reply(builder.build(), { parse_mode: builder.getParseMode() })
98
+ const message = builder.build()
99
+ await ctx.reply(message.text || '', { parse_mode: (message.parse_mode || 'HTML') as any })
99
100
  configLogger.success(`Config exported for user ${userId}`)
100
101
  }
101
102
 
@@ -2,7 +2,7 @@ import type { Context } from 'telegraf'
2
2
  import { updateConfig, getConfig } from '../config/index.js'
3
3
  import { botLogger, controlLogger, badge, kv, colors, colorText } from '../middleware/logging.js'
4
4
  import { botManager } from '../utils/bot-manager.js'
5
- import { MessageBuilder } from '../utils/message-builder.js'
5
+ import { TelegramMessageBuilder } from '@mks2508/telegram-message-builder'
6
6
 
7
7
  export async function handleStop(ctx: Context): Promise<void> {
8
8
  const userId = ctx.from?.id ?? 'unknown'
@@ -14,8 +14,10 @@ export async function handleStop(ctx: Context): Promise<void> {
14
14
  })}`
15
15
  )
16
16
 
17
- const message = MessageBuilder.markdown().text('🛑 Shutting down bot...').build()
18
- ctx.reply(message, { parse_mode: 'Markdown' })
17
+ const message = TelegramMessageBuilder.text()
18
+ .text('🛑 Shutting down bot...')
19
+ .build()
20
+ ctx.reply(message.text || '', { parse_mode: (message.parse_mode || 'HTML') as any })
19
21
  process.exit(0)
20
22
  }
21
23
 
@@ -29,15 +31,17 @@ export async function handleRestart(ctx: Context): Promise<void> {
29
31
  })}`
30
32
  )
31
33
 
32
- const builder1 = MessageBuilder.markdown()
33
- builder1.text('🔄 Restarting bot...')
34
- ctx.reply(builder1.build(), { parse_mode: builder1.getParseMode() })
34
+ const message1 = TelegramMessageBuilder.text()
35
+ .text('🔄 Restarting bot...')
36
+ .build()
37
+ ctx.reply(message1.text || '', { parse_mode: (message1.parse_mode || 'HTML') as any })
35
38
 
36
39
  botManager.resetStats()
37
40
 
38
- const builder2 = MessageBuilder.markdown()
39
- builder2.text('✅ Bot stats reset. Restarting...')
40
- ctx.reply(builder2.build(), { parse_mode: builder2.getParseMode() })
41
+ const message2 = TelegramMessageBuilder.text()
42
+ .text('✅ Bot stats reset. Restarting...')
43
+ .build()
44
+ ctx.reply(message2.text || '', { parse_mode: (message2.parse_mode || 'HTML') as any })
41
45
  process.exit(0)
42
46
  }
43
47
 
@@ -48,34 +52,37 @@ export async function handleMode(ctx: Context): Promise<void> {
48
52
 
49
53
  if (!mode || (mode !== 'polling' && mode !== 'webhook')) {
50
54
  const config = getConfig()
51
- const builder = MessageBuilder.markdown()
52
- .title('📡 Current Mode:')
55
+ const message = TelegramMessageBuilder.text()
56
+ .title('📡 Current Mode')
53
57
  .newline()
54
58
  .line('Mode', config.mode, { code: true })
55
59
  .newline()
56
60
  .text('Usage: /mode <polling|webhook>')
61
+ .build()
57
62
 
58
- ctx.reply(builder.build(), { parse_mode: builder.getParseMode() })
63
+ ctx.reply(message.text || '', { parse_mode: (message.parse_mode || 'HTML') as any })
59
64
  return
60
65
  }
61
66
 
62
67
  if (mode === 'webhook') {
63
68
  const config = getConfig()
64
69
  if (!config.webhookUrl) {
65
- const builder = MessageBuilder.markdown()
70
+ const message = TelegramMessageBuilder.text()
66
71
  .text('❌ Webhook URL not configured. Set TG_WEBHOOK_URL environment variable.')
67
- ctx.reply(builder.build(), { parse_mode: builder.getParseMode() })
72
+ .build()
73
+ ctx.reply(message.text || '', { parse_mode: (message.parse_mode || 'HTML') as any })
68
74
  return
69
75
  }
70
76
  }
71
77
 
72
78
  updateConfig({ mode })
73
79
 
74
- const builder = MessageBuilder.markdown()
80
+ const message = TelegramMessageBuilder.text()
75
81
  .text('✅ Mode changed to:')
76
82
  .line('Mode', mode, { code: true })
83
+ .build()
77
84
 
78
- ctx.reply(builder.build(), { parse_mode: builder.getParseMode() })
85
+ ctx.reply(message.text || '', { parse_mode: (message.parse_mode || 'HTML') as any })
79
86
 
80
87
  controlLogger.info(
81
88
  `${badge('MODE', 'rounded')} ${kv({
@@ -89,18 +96,20 @@ export async function handleWebhook(ctx: Context): Promise<void> {
89
96
  const config = getConfig()
90
97
 
91
98
  if (config.mode !== 'webhook') {
92
- const builder = MessageBuilder.markdown()
99
+ const message = TelegramMessageBuilder.text()
93
100
  .text('❌ Bot is not in webhook mode. Use /mode webhook first.')
94
- ctx.reply(builder.build(), { parse_mode: builder.getParseMode() })
101
+ .build()
102
+ ctx.reply(message.text || '', { parse_mode: (message.parse_mode || 'HTML') as any })
95
103
  return
96
104
  }
97
105
 
98
- const builder = MessageBuilder.markdown()
99
- .title('🔗 Webhook Configuration:')
106
+ const message = TelegramMessageBuilder.text()
107
+ .title('🔗 Webhook Configuration')
100
108
  .newline()
101
109
  .line('URL', config.webhookUrl || 'Not set', { code: true })
110
+ .build()
102
111
 
103
- ctx.reply(builder.build(), { parse_mode: builder.getParseMode() })
112
+ ctx.reply(message.text || '', { parse_mode: (message.parse_mode || 'HTML') as any })
104
113
 
105
114
  controlLogger.info(
106
115
  `${badge('WEBHOOK', 'rounded')} ${kv({
@@ -0,0 +1,58 @@
1
+ import { TelegramMessageBuilder, TelegramKeyboardBuilder } from '@mks2508/telegram-message-builder'
2
+ import type { Context } from 'telegraf'
3
+ import { handleMediaDemo } from './demo-media.js'
4
+ import { handleKeyboardDemo } from './demo-keyboard.js'
5
+
6
+ export async function handleFullDemo(ctx: Context): Promise<void> {
7
+ const message = TelegramMessageBuilder.text()
8
+ .title('🚀 telegram-message-builder v0.3.0')
9
+ .newline()
10
+ .section('Features')
11
+ .listItem('✨ Fluent API for text formatting')
12
+ .listItem('⌨️ Inline and reply keyboards')
13
+ .listItem('📸 5 media types support')
14
+ .listItem('🎨 HTML, Markdown, MarkdownV2')
15
+ .listItem('🔒 Type-safe with TypeScript')
16
+ .listItem('📦 Zero runtime dependencies')
17
+ .newline()
18
+ .section('Installation')
19
+ .codeBlock('bun add @mks2508/telegram-message-builder', 'bash')
20
+ .newline()
21
+ .section('Quick Start')
22
+ .codeBlock(`import { TelegramMessageBuilder } from '@mks2508/telegram-message-builder'
23
+
24
+ const message = TelegramMessageBuilder.text()
25
+ .title('Hello World')
26
+ .line('Status', 'Active', { bold: true })
27
+ .build()
28
+
29
+ ctx.reply(message.text, { parse_mode: message.parse_mode })`, 'typescript')
30
+ .build()
31
+
32
+ const keyboard = TelegramKeyboardBuilder.inline()
33
+ .urlButton('📦 npm Package', 'https://www.npmjs.com/package/@mks2508/telegram-message-builder')
34
+ .urlButton('📖 GitHub', 'https://github.com/MKS2508/telegram-message-builder')
35
+ .row()
36
+ .callbackButton('📸 Media Demo', 'full_demo_media')
37
+ .callbackButton('⌨️ Keyboard Demo', 'full_demo_keyboard')
38
+ .buildMarkup()
39
+
40
+ await ctx.reply(message.text || '', {
41
+ parse_mode: (message.parse_mode || 'HTML') as any,
42
+ reply_markup: keyboard as any,
43
+ })
44
+ }
45
+
46
+ export async function handleFullDemoCallback(ctx: Context): Promise<void> {
47
+ const callbackData = (ctx.callbackQuery as any)?.data
48
+ await ctx.answerCbQuery()
49
+
50
+ switch (callbackData) {
51
+ case 'full_demo_media':
52
+ await handleMediaDemo(ctx)
53
+ break
54
+ case 'full_demo_keyboard':
55
+ await handleKeyboardDemo(ctx)
56
+ break
57
+ }
58
+ }
@@ -0,0 +1,49 @@
1
+ import { TelegramMessageBuilder, TelegramKeyboardBuilder } from '@mks2508/telegram-message-builder'
2
+ import type { Context } from 'telegraf'
3
+
4
+ export async function handleKeyboardDemo(ctx: Context): Promise<void> {
5
+ const message = TelegramMessageBuilder.text()
6
+ .title('⌨️ Keyboard Demo')
7
+ .newline()
8
+ .text('Try the buttons below:')
9
+ .build()
10
+
11
+ const keyboard = TelegramKeyboardBuilder.inline()
12
+ .urlButton('🌐 Visit Website', 'https://github.com/MKS2508/telegram-message-builder')
13
+ .callbackButton('✅ Yes', 'demo_yes')
14
+ .callbackButton('❌ No', 'demo_no')
15
+ .row()
16
+ .callbackButton('🔄 Refresh', 'demo_refresh')
17
+ .callbackButton('🔍 Search', 'demo_search')
18
+ .row()
19
+ .switchInlineQueryButton('🔍 Inline Query', 'query')
20
+ .buildMarkup()
21
+
22
+ await ctx.reply(message.text || '', {
23
+ parse_mode: (message.parse_mode || 'HTML') as any,
24
+ reply_markup: keyboard as any,
25
+ })
26
+ }
27
+
28
+ export async function handleKeyboardCallback(ctx: Context): Promise<void> {
29
+ const callbackData = (ctx.callbackQuery as any)?.data
30
+ let response = 'Unknown action'
31
+
32
+ switch (callbackData) {
33
+ case 'demo_yes':
34
+ response = '✅ You clicked YES!'
35
+ break
36
+ case 'demo_no':
37
+ response = '❌ You clicked NO!'
38
+ break
39
+ case 'demo_refresh':
40
+ response = '🔄 Content refreshed!'
41
+ break
42
+ case 'demo_search':
43
+ response = '🔍 Searching...'
44
+ break
45
+ }
46
+
47
+ await ctx.answerCbQuery(response)
48
+ await ctx.reply(response)
49
+ }
@@ -0,0 +1,163 @@
1
+ import { TelegramMessageBuilder, TelegramMediaBuilder, TelegramKeyboardBuilder } from '@mks2508/telegram-message-builder'
2
+ import type { Context } from 'telegraf'
3
+
4
+ export async function handleMediaDemo(ctx: Context): Promise<void> {
5
+ const message = TelegramMessageBuilder.text()
6
+ .title('📸 Media Builder Demo')
7
+ .newline()
8
+ .text('Choose a media type to test:')
9
+ .listItem('Photo with caption')
10
+ .listItem('Video with options')
11
+ .listItem('Document with metadata')
12
+ .listItem('Audio with performer info')
13
+ .listItem('Voice message')
14
+ .build()
15
+
16
+ const keyboard = TelegramKeyboardBuilder.inline()
17
+ .callbackButton('📷 Photo', 'media_photo')
18
+ .callbackButton('🎥 Video', 'media_video')
19
+ .row()
20
+ .callbackButton('📄 Document', 'media_document')
21
+ .callbackButton('🎵 Audio', 'media_audio')
22
+ .row()
23
+ .callbackButton('🎤 Voice', 'media_voice')
24
+ .buildMarkup()
25
+
26
+ await ctx.reply(message.text || '', {
27
+ parse_mode: (message.parse_mode || 'HTML') as any,
28
+ reply_markup: keyboard as any,
29
+ })
30
+ }
31
+
32
+ export async function handleMediaCallback(ctx: Context): Promise<void> {
33
+ const callbackData = (ctx.callbackQuery as any)?.data
34
+ await ctx.answerCbQuery()
35
+
36
+ switch (callbackData) {
37
+ case 'media_photo':
38
+ await sendPhotoDemo(ctx)
39
+ break
40
+ case 'media_video':
41
+ await sendVideoDemo(ctx)
42
+ break
43
+ case 'media_document':
44
+ await sendDocumentDemo(ctx)
45
+ break
46
+ case 'media_audio':
47
+ await sendAudioDemo(ctx)
48
+ break
49
+ case 'media_voice':
50
+ await sendVoiceDemo(ctx)
51
+ break
52
+ }
53
+ }
54
+
55
+ async function sendPhotoDemo(ctx: Context): Promise<void> {
56
+ const photo = TelegramMediaBuilder.photo('https://picsum.photos/800/600')
57
+ .caption('📷 Photo Demo\n\nThis is a photo with caption formatting support!')
58
+ .setParseMode('html')
59
+ .build()
60
+
61
+ const media = typeof photo.media === 'string' ? photo.media : undefined
62
+
63
+ if (!media) {
64
+ await ctx.reply('❌ Media source must be a URL or file_id')
65
+ return
66
+ }
67
+
68
+ await ctx.replyWithPhoto(media, {
69
+ caption: photo.caption || undefined,
70
+ parse_mode: photo.parse_mode as any,
71
+ })
72
+ }
73
+
74
+ async function sendVideoDemo(ctx: Context): Promise<void> {
75
+ const video = TelegramMediaBuilder.video('https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4')
76
+ .caption('🎥 Video Demo\n\nDuration: 10s\nResolution: 1280x720')
77
+ .duration(10)
78
+ .width(1280)
79
+ .height(720)
80
+ .enableStreaming()
81
+ .setParseMode('html')
82
+ .build()
83
+
84
+ const media = typeof video.media === 'string' ? video.media : undefined
85
+
86
+ if (!media) {
87
+ await ctx.reply('❌ Media source must be a URL or file_id')
88
+ return
89
+ }
90
+
91
+ await ctx.replyWithVideo(media, {
92
+ caption: video.caption || undefined,
93
+ parse_mode: video.parse_mode as any,
94
+ width: video.width as number,
95
+ height: video.height as number,
96
+ duration: video.duration as number,
97
+ supports_streaming: true,
98
+ })
99
+ }
100
+
101
+ async function sendDocumentDemo(ctx: Context): Promise<void> {
102
+ const doc = TelegramMediaBuilder.document('https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf')
103
+ .caption('📄 Document Demo\n\nThis is a PDF document with custom filename.')
104
+ .fileName('sample-document.pdf')
105
+ .mimeType('application/pdf')
106
+ .build()
107
+
108
+ const media = typeof doc.media === 'string' ? doc.media : undefined
109
+
110
+ if (!media) {
111
+ await ctx.reply('❌ Media source must be a URL or file_id')
112
+ return
113
+ }
114
+
115
+ await ctx.replyWithDocument(media, {
116
+ caption: doc.caption || undefined,
117
+ parse_mode: doc.parse_mode as any,
118
+ })
119
+ }
120
+
121
+ async function sendAudioDemo(ctx: Context): Promise<void> {
122
+ const audio = TelegramMediaBuilder.audio('https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3')
123
+ .caption('🎵 Audio Demo\n\nArtist: Demo Artist\nTitle: Demo Song')
124
+ .performer('Demo Artist')
125
+ .title('Demo Song')
126
+ .duration(180)
127
+ .build()
128
+
129
+ const media = typeof audio.media === 'string' ? audio.media : undefined
130
+
131
+ if (!media) {
132
+ await ctx.reply('❌ Media source must be a URL or file_id')
133
+ return
134
+ }
135
+
136
+ await ctx.replyWithAudio(media, {
137
+ caption: audio.caption || undefined,
138
+ parse_mode: audio.parse_mode as any,
139
+ performer: audio.performer as string,
140
+ title: audio.title as string,
141
+ duration: audio.duration as number,
142
+ })
143
+ }
144
+
145
+ async function sendVoiceDemo(ctx: Context): Promise<void> {
146
+ const voice = TelegramMediaBuilder.voice('https://sample-videos.com/audio/mp3/crowd-cheering.mp3')
147
+ .caption('🎤 Voice Demo\n\nThis is a voice message.')
148
+ .duration(5)
149
+ .build()
150
+
151
+ const media = typeof voice.media === 'string' ? voice.media : undefined
152
+
153
+ if (!media) {
154
+ await ctx.reply('❌ Media source must be a URL or file_id')
155
+ return
156
+ }
157
+
158
+ await ctx.replyWithVoice(media, {
159
+ caption: voice.caption || undefined,
160
+ parse_mode: voice.parse_mode as any,
161
+ duration: voice.duration as number,
162
+ })
163
+ }