create-gramstax 0.5.13 → 0.5.15

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.
@@ -1,15 +1,15 @@
1
1
  # Telegram Bot Token
2
- BOT_TOKEN=your_bot_token_here
2
+ TELEGRAM_BOT_TOKEN=your_bot_token_here
3
3
 
4
4
  # Bot Deployment Mode
5
5
  # Options:
6
6
  # - polling
7
7
  # - webhook:<full-public-url> | example: webhook:https://yourdomain.com/telegram-webhook
8
8
  # - serverless:<adapter> | example: serverless:std/http
9
- BOT_DEPLOY=polling
9
+ TELEGRAM_BOT_DEPLOY=polling
10
10
 
11
11
  # Cache configuration for session
12
12
  # Options:
13
13
  # - memory
14
14
  # - redis:<url> | example: redis://127.0.0.1:6379
15
- CACHE_SESSION=memory
15
+ TELEGRAM_CACHE_SESSION=memory
@@ -17,7 +17,7 @@ A Telegram bot built with Gramstax framework.
17
17
  Copy `.env.example` to `.env` and add your Telegram bot token:
18
18
 
19
19
  ```bash
20
- BOT_TOKEN=your_bot_token_here
20
+ TELEGRAM_BOT_TOKEN="<...your_bot_token_here...>"
21
21
  ```
22
22
 
23
23
  3. Run the development server:
@@ -26,57 +26,6 @@ BOT_TOKEN=your_bot_token_here
26
26
  {{runDevCmd}}
27
27
  ```
28
28
 
29
- ### Production
30
-
31
- #### Using PM2 (Recommended)
32
-
33
- PM2 is a production process manager for Node.js applications with built-in load balancer.
34
-
35
- 1. Install dependencies:
36
-
37
- ```bash
38
- {{installCmd}}
39
- ```
40
-
41
- 2. Set up production environment:
42
-
43
- ```bash
44
- cp .env.example .env
45
- # Edit .env with your production BOT_TOKEN
46
- ```
47
-
48
- 3. Start with PM2:
49
-
50
- ```bash
51
- {{runPm2StartCmd}}
52
- ```
53
-
54
- 4. PM2 Management Commands:
55
-
56
- ```bash
57
- # View logs
58
- {{runPm2LogsCmd}}
59
-
60
- # Monitor processes
61
- {{runPm2MonitCmd}}
62
-
63
- # Restart bot
64
- {{runPm2RestartCmd}}
65
-
66
- # Stop bot
67
- {{runPm2StopCmd}}
68
-
69
- # Delete from PM2
70
- {{runPm2DeleteCmd}}
71
- ```
72
-
73
- 5. Setup PM2 to start on system boot:
74
-
75
- ```bash
76
- pm2 startup
77
- pm2 save
78
- ```
79
-
80
29
  #### Using Bun directly
81
30
 
82
31
  ```bash
@@ -86,12 +35,10 @@ pm2 save
86
35
  ## Project Structure
87
36
 
88
37
  - `src/base/` - Base classes for your bot components
38
+ - `src/blocks/` - Block data builder classes
89
39
  - `src/core/` - Core bot configuration and hooks
90
- - `src/pages/` - Bot pages/screens
91
40
  - `src/guards/` - Route guards and middleware
92
- - `src/services/` - Business logic services
93
- - `src/repositories/` - Data access layer
94
- - `src/templates/` - Message templates
41
+ - `src/pages/` - Bot pages/screens
95
42
  - `src/utils/` - Utility functions
96
43
  - `logs/` - Application logs (created automatically)
97
44
 
@@ -99,22 +46,12 @@ pm2 save
99
46
 
100
47
  ### Environment Variables
101
48
 
102
- - `BOT_TOKEN` - Your Telegram bot token (required)
103
- - `CACHE_SESSION` - Cache type configuration (optional)
104
-
105
- ### PM2 Configuration
106
-
107
- The `ecosystem.config.js` file contains PM2 configuration:
108
-
109
- - **instances**: Number of instances (default: 1)
110
- - **exec_mode**: Execution mode (cluster/fork)
111
- - **max_memory_restart**: Auto-restart if memory exceeds limit
112
- - **autorestart**: Auto-restart on crash
113
- - **error_file/out_file**: Log file locations
49
+ - `TELEGRAM_BOT_TOKEN` - Your Telegram bot token (required)
50
+ - `TELEGRAM_BOT_DEPLOY` - Your Telegram bot deploy (required)
51
+ - `TELEGRAM_CACHE_SESSION` - Cache type configuration (optional)
114
52
 
115
53
  ## Learn More
116
54
 
117
55
  - [Gramstax Documentation](https://github.com/gramstax/gramstax)
118
56
  - [Grammy Documentation](https://grammy.dev/)
119
57
  - [Telegram Bot API](https://core.telegram.org/bots/api)
120
- - [PM2 Documentation](https://pm2.keymetrics.io/)
@@ -36,13 +36,12 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "logging-pretty": "^3.0.0",
39
- "gramstax": "^0.5.12"
39
+ "gramstax": "^0.5.14"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "typescript": "5.9.3"
43
43
  },
44
44
  "devDependencies": {
45
- "@types/bun": "latest",
46
- "pm2": "^5.3.0"
45
+ "@types/bun": "latest"
47
46
  }
48
47
  }
@@ -2,8 +2,8 @@ import {BlockKeyboard, LabelKeyboard} from "gramstax"
2
2
 
3
3
  export class KeyboardBlock extends BlockKeyboard {
4
4
  static label = class extends LabelKeyboard {
5
- static home = {default: `Home`, it: `Casa`, id: `Beranda`}
6
- static back = {default: `.. Back`, it: `.. Ritorno`, id: `.. Kembali`}
5
+ static home = {default: `Home`, id: `Beranda`}
6
+ static back = {default: `<< Back`, id: `<< Kembali`}
7
7
  }
8
8
  static home = (lang?: string, type?: string) => this._build(`home`, lang, type)
9
9
  static back = (lang?: string, type?: string) => this._build(`back`, lang, type)
@@ -5,7 +5,7 @@ import type {CtxCore} from "./ctx"
5
5
 
6
6
  export class BotCore extends Gramstax {
7
7
  async hookBeforeRoute(ctx: CtxCore) {
8
- const result = await new UserGuard(ctx).ensureValid(true)
8
+ const result = await new UserGuard(ctx).ensureUsername(true)
9
9
  if (result === null) {
10
10
  return false
11
11
  }
@@ -8,15 +8,15 @@ export class UserGuard extends GuardBase {
8
8
  return null
9
9
  }
10
10
 
11
- async ensureValid(isEdit: boolean) {
11
+ async ensureUsername(edit: boolean) {
12
12
  try {
13
13
  if (!this.userName || this.userName.length == 0) {
14
- await new UserNameNotFoundPage(this).transition(isEdit)
14
+ await new UserNameNotFoundPage(this).transition(edit)
15
15
  return null
16
16
  }
17
17
  return {status: true}
18
18
  } catch (err) {
19
- return await this._catch(err, `ensureValid`, isEdit)
19
+ return await this._catch(err, `ensureValid`, edit)
20
20
  }
21
21
  }
22
22
  }
@@ -1,14 +1,14 @@
1
1
  import {env} from "./env"
2
- import {logUt} from "./utils/log"
2
+ import {log} from "./utils/log"
3
3
  import {BotCore} from "./core/bot"
4
4
  import {CacheExternal} from "gramstax"
5
5
 
6
- logUt.success(`Bot started..`)
6
+ log.success(`Bot started..`)
7
7
 
8
8
  new BotCore({
9
9
  token: env.TELEGRAM_BOT_TOKEN,
10
10
  deploy: env.TELEGRAM_BOT_DEPLOY,
11
- cacheSession: new CacheExternal(env.TELEGRAM_CACHE_SESSION, 24 * 60 * 60 * 1000, `s`),
11
+ cacheSession: new CacheExternal(env.TELEGRAM_CACHE_SESSION, 4 * 60 * 60 * 1000, `s`), // 4 hours
12
12
  optionsPage: {
13
13
  shortCallbackData: true
14
14
  }
@@ -1,9 +1,11 @@
1
- import {log} from "gramstax"
1
+ import {log} from "~/utils/log"
2
2
  import {PageBase} from "~/base/page"
3
3
  import {StartPage} from "./start"
4
4
 
5
5
  export class GeneralStatusPage extends PageBase {
6
+ static BASE = {error: `error`, notFound: `not-found`}
6
7
  constructorName?: string
8
+
7
9
  constructor(p: any) {
8
10
  super(p)
9
11
  this.constructorName = p?.constructor?.name
@@ -18,13 +20,13 @@ export class GeneralStatusPage extends PageBase {
18
20
 
19
21
  await this.sessionClear()
20
22
  const kb = this.kb()
21
- const id = `error`
22
- if (edit) await this.edit(kb, {}, id)
23
- else await this.reply(kb, {}, id)
23
+ const bi = GeneralStatusPage.BASE.error
24
+ if (edit) await this.edit(kb, {}, bi)
25
+ else await this.reply(kb, {}, bi)
24
26
  }
25
27
 
26
28
  async toErrorInputNotFound() {
27
- await this.reply(this.kb(), {}, `error-input-notfound`)
29
+ await this.reply(this.kb(), {}, GeneralStatusPage.BASE.notFound)
28
30
  }
29
31
 
30
32
  static template = `
@@ -32,7 +34,7 @@ export class GeneralStatusPage extends PageBase {
32
34
  ${this.kbk.home()}
33
35
  </base>
34
36
 
35
- <base id="error">
37
+ <base id="${this.BASE.error}">
36
38
  <message>
37
39
  <b>❌ Error</b>
38
40
 
@@ -47,12 +49,16 @@ export class GeneralStatusPage extends PageBase {
47
49
  </message>
48
50
  </base>
49
51
 
50
- <base id="error-input-notfound">
52
+ <base id="${this.BASE.notFound}">
51
53
  <message>
52
54
  <b>❌ Not Found</b>
55
+
56
+ Not maching route.
53
57
  </message>
54
58
  <message lang="id">
55
59
  <b>❌ Tidak Ditemukan</b>
60
+
61
+ Tidak ada route terdeteksi.
56
62
  </message>
57
63
  </base>
58
64
  `
@@ -20,7 +20,6 @@ export class HelpPage extends PageBase {
20
20
  <base>
21
21
  ${this.kbk.back()}
22
22
  <message><b>Help message</b></message>
23
- <message lang="it"><b>Ordina aiuto</b></message>
24
23
  <message lang="id"><b>Pesan bantuan</b></message>
25
24
  </base>
26
25
  `
@@ -18,11 +18,6 @@ export class StartPage extends PageBase {
18
18
  }
19
19
 
20
20
  static template = `
21
- <base id="with-import-and-you-can-use-components">
22
- <keyboard>❓ Help</keyboard>
23
- <keyboard lang="it">❓ Aiuto</keyboard>
24
- <keyboard lang="id">❓ Bantuan</keyboard>
25
- </base>
26
21
  <base>
27
22
  <import src="start" base="with-import-and-you-can-use-components" />
28
23
  <message>
@@ -30,11 +25,6 @@ export class StartPage extends PageBase {
30
25
 
31
26
  <b>❓ Help</b> - View help
32
27
  </message>
33
- <message lang="it">
34
- <b>Benvenuto nel Bot di {{userName}}</b>
35
-
36
- <b>❓ Aiuto</b> - Ottieni assistenza e informazioni
37
- </message>
38
28
  <message lang="id">
39
29
  <b>Selamat datang di bot {{userName}}</b>
40
30
 
@@ -12,7 +12,6 @@ export class UserNameNotFoundPage extends PageBase {
12
12
  <base>
13
13
  ${this.kbk.home()}
14
14
  <message>Please set the username first before using the bot.</message>
15
- <message lang="it">Prima di utilizzare il bot, imposta prima il nome utente.</message>
16
15
  <message lang="id">Tolong set username dulu sebelum memakai bot</message>
17
16
  </base>
18
17
  `
@@ -1,2 +1,2 @@
1
1
  import {log} from "gramstax"
2
- export {log as logUt}
2
+ export {log}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-gramstax",
3
- "version": "0.5.13",
3
+ "version": "0.5.15",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -1,15 +0,0 @@
1
- import {GuardBase} from "~/base/guard"
2
-
3
- export class SessionGuard extends GuardBase {
4
- async ensureTextFree() {
5
- try {
6
- const {method, params} = this.session
7
- if (this.validateSessionTextFree(method, this.temp.data.name) === false) {
8
- return null
9
- }
10
- return params
11
- } catch {
12
- return null
13
- }
14
- }
15
- }
@@ -1,69 +0,0 @@
1
- import {PageBase} from "~/base/page"
2
- import {StartPage} from "./start"
3
- import {SessionGuard} from "~/guards/session"
4
-
5
- export class InputTextPage extends PageBase {
6
- static data = this.buildData({
7
- intentTextCommand: `input_text`
8
- })
9
-
10
- kb(baseId?: string) {
11
- return this.inlineKeyboardT([StartPage], `1`, baseId)
12
- }
13
-
14
- async callback() {
15
- await this.sessionToTextFree()
16
- await this.edit(this.kb())
17
- }
18
-
19
- async textCommand() {
20
- await this.sessionToTextFree()
21
- await this.reply(this.kb())
22
- }
23
-
24
- async textFree() {
25
- const params = await new SessionGuard(this).ensureTextFree()
26
- if (params === null) {
27
- /**
28
- * Return "null" if you want the bot to continue to check for suitable route for the
29
- * "dynamicSpecific" and "dynamic" type with the route suffix "Free" or "free" (without session), for example: textFree, animationFree, free.
30
- *
31
- * Return "undefined"/void if you want the bot to stop checking for "dynamicSpecific" and "dynamic" route types.
32
- *
33
- * Returning undefined/void indicates the success of this rule. There are only two returns allowed for all routes: null and undefined / void.
34
- */
35
- return null
36
- }
37
-
38
- const baseId = `result`
39
- const data = {res: this.msgText}
40
- await this.reply(this.kb(baseId), data, baseId)
41
- }
42
-
43
- static template = `
44
- <base>
45
- ${this.kbk.cancel()}
46
- <message>Please input text you want view</message>
47
- <message lang="it">Inserisci il testo che vuoi vedere</message>
48
- <message lang="id">Tolong masukan text yang ingin anda liat</message>
49
- </base>
50
- <base id="result">
51
- ${this.kbk.home()}
52
- <message>
53
- Result: {{res}}
54
-
55
- Please input other text to see difference result
56
- </message>
57
- <message lang="it">
58
- Risultato: {{res}}
59
-
60
- Inserisci un altro testo per vedere il risultato diverso
61
- </message>
62
- <message lang="id">
63
- Hasil: {{res}}
64
-
65
- Tolong masukan text lain untuk lihat hasil yang berbeda
66
- </message>
67
- </base>
68
- `
69
- }