@grom.js/effect-tg 0.10.0 → 0.11.0
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.
- package/README.md +383 -25
- package/dist/BotApiError.js +1 -1
- package/dist/BotApiError.js.map +1 -1
- package/dist/Dialog.d.ts +24 -23
- package/dist/Dialog.d.ts.map +1 -1
- package/dist/Dialog.js +15 -17
- package/dist/Dialog.js.map +1 -1
- package/dist/Markup.d.ts +200 -11
- package/dist/Markup.d.ts.map +1 -1
- package/dist/Markup.js +39 -0
- package/dist/Markup.js.map +1 -1
- package/dist/Reply.d.ts +22 -0
- package/dist/Reply.d.ts.map +1 -0
- package/dist/Reply.js +18 -0
- package/dist/Reply.js.map +1 -0
- package/dist/Send.d.ts +16 -1
- package/dist/Send.d.ts.map +1 -1
- package/dist/Send.js +28 -5
- package/dist/Send.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/botApi.gen.d.ts +263 -191
- package/dist/internal/botApi.gen.d.ts.map +1 -1
- package/dist/internal/dialog.d.ts +4 -4
- package/dist/internal/dialog.d.ts.map +1 -1
- package/dist/internal/dialog.js +12 -13
- package/dist/internal/dialog.js.map +1 -1
- package/dist/internal/send.d.ts +4 -1
- package/dist/internal/send.d.ts.map +1 -1
- package/dist/internal/send.js +150 -6
- package/dist/internal/send.js.map +1 -1
- package/package.json +11 -10
- package/src/BotApiError.ts +1 -1
- package/src/Dialog.ts +31 -30
- package/src/Markup.ts +251 -11
- package/src/Reply.ts +36 -0
- package/src/Send.ts +51 -17
- package/src/index.ts +1 -0
- package/src/internal/botApi.gen.ts +267 -191
- package/src/internal/dialog.ts +16 -17
- package/src/internal/send.ts +170 -6
package/README.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# effect-tg
|
|
2
2
|
|
|
3
|
-
[](https://effect.website/)
|
|
4
|
+
[](https://core.telegram.org/bots/api)
|
|
5
|
+
[](https://www.npmjs.com/package/@grom.js/effect-tg)
|
|
6
|
+
[](https://codecov.io/gh/grom-dev/effect-tg)
|
|
5
7
|
|
|
6
8
|
Effectful library for crafting Telegram bots.
|
|
7
9
|
|
|
@@ -9,6 +11,8 @@ Effectful library for crafting Telegram bots.
|
|
|
9
11
|
|
|
10
12
|
- Modular design to build with [Effect](https://effect.website).
|
|
11
13
|
- Complete type definitions for [Bot API](https://core.telegram.org/bots/api) methods and types.
|
|
14
|
+
- Composable API for [sending messages](#sending-messages).
|
|
15
|
+
- [JSX syntax](#jsx-syntax) support for creating formatted text.
|
|
12
16
|
|
|
13
17
|
## Installation
|
|
14
18
|
|
|
@@ -18,6 +22,9 @@ npm install @grom.js/effect-tg
|
|
|
18
22
|
|
|
19
23
|
# Install Effect dependencies
|
|
20
24
|
npm install effect @effect/platform
|
|
25
|
+
|
|
26
|
+
# Install JSX runtime for formatted text
|
|
27
|
+
npm install @grom.js/tgx
|
|
21
28
|
```
|
|
22
29
|
|
|
23
30
|
## Working with Bot API
|
|
@@ -66,7 +73,7 @@ const program = Effect.gen(function* () {
|
|
|
66
73
|
`BotApi` has a layered architecture:
|
|
67
74
|
|
|
68
75
|
```
|
|
69
|
-
┌• BotApi — typed interface that delegates calls to
|
|
76
|
+
┌• BotApi — typed interface that delegates calls to BotApiTransport.
|
|
70
77
|
└─┬• BotApiTransport — serializes parameters, sends HTTP requests, parses responses.
|
|
71
78
|
├──• BotApiUrl — constructs endpoint URLs to methods and files.
|
|
72
79
|
└──• HttpClient — performs HTTP requests.
|
|
@@ -78,41 +85,37 @@ This design enables:
|
|
|
78
85
|
- **Testability**: Mock implementation of `BotApiTransport` or `HttpClient` to test your bot.
|
|
79
86
|
- **Portability:** Provide different `BotApiUrl` to run a bot on test environment or with local Bot API server.
|
|
80
87
|
|
|
81
|
-
**Example:** Constructing `BotApi` layer.
|
|
88
|
+
**Example:** Constructing `BotApi` layer with method call tracing.
|
|
82
89
|
|
|
83
90
|
```ts
|
|
84
91
|
import { FetchHttpClient } from '@effect/platform'
|
|
85
|
-
import { BotApi
|
|
92
|
+
import { BotApi } from '@grom.js/effect-tg'
|
|
86
93
|
import { Config, Effect, Layer } from 'effect'
|
|
87
94
|
|
|
88
|
-
// Use a shortcut to construct BotApi
|
|
89
95
|
const BotApiLive = Layer.provide(
|
|
90
|
-
BotApi.layerConfig({
|
|
96
|
+
BotApi.layerConfig({
|
|
97
|
+
token: Config.redacted('BOT_TOKEN'),
|
|
98
|
+
environment: 'prod',
|
|
99
|
+
transformTransport: transport => ({
|
|
100
|
+
sendRequest: (method, params) =>
|
|
101
|
+
transport.sendRequest(method, params).pipe(
|
|
102
|
+
Effect.withSpan(method),
|
|
103
|
+
),
|
|
104
|
+
}),
|
|
105
|
+
}),
|
|
91
106
|
FetchHttpClient.layer
|
|
92
107
|
)
|
|
93
|
-
|
|
94
|
-
// Or provide all layers manually
|
|
95
|
-
const BotApiLive = BotApi.layer.pipe(
|
|
96
|
-
Layer.provide(BotApiTransport.layer),
|
|
97
|
-
Layer.provide(
|
|
98
|
-
Layer.effect(
|
|
99
|
-
BotApiUrl.BotApiUrl,
|
|
100
|
-
Effect.map(Config.string('BOT_API_TOKEN'), BotApiUrl.makeProd)
|
|
101
|
-
),
|
|
102
|
-
),
|
|
103
|
-
Layer.provide(FetchHttpClient.layer),
|
|
104
|
-
)
|
|
105
108
|
```
|
|
106
109
|
|
|
107
110
|
### Error handling
|
|
108
111
|
|
|
109
112
|
Failed `BotApi` method calls result in `BotApiError`, which is a union of tagged errors with additional information:
|
|
110
113
|
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
-
|
|
114
|
-
-
|
|
115
|
-
-
|
|
114
|
+
- **`TransportError`** — HTTP or network failure. The `cause` property contains the original error from `HttpClient`.
|
|
115
|
+
- **`RateLimited`** — bot has exceeded the flood limit. The `retryAfter` property contains the duration to wait before the next attempt.
|
|
116
|
+
- **`GroupUpgraded`** — group has been migrated to a supergroup. The `supergroup` property contains an object with the ID of the new supergroup.
|
|
117
|
+
- **`MethodFailed`** — response was unsuccessful, but the exact reason could not be determined. The `possibleReason` property contains a string literal representing one of the common failure reasons. It is determined by the error code and description of the Bot API response, which are subject to change.
|
|
118
|
+
- **`InternalServerError`** — Bot API server failed with a 5xx error code.
|
|
116
119
|
|
|
117
120
|
All errors except `TransportError` also have `response` property that contains the original response from Bot API.
|
|
118
121
|
|
|
@@ -132,7 +135,7 @@ const program = BotApi.callMethod('doSomething').pipe(
|
|
|
132
135
|
RateLimited: ({ retryAfter }) =>
|
|
133
136
|
Effect.logError(`Try again in ${Duration.format(retryAfter)}`),
|
|
134
137
|
GroupUpgraded: ({ supergroup }) =>
|
|
135
|
-
Effect.logError(`Group now
|
|
138
|
+
Effect.logError(`Group is now a supergroup with ID: ${supergroup.id}`),
|
|
136
139
|
MethodFailed: ({ possibleReason, response }) =>
|
|
137
140
|
Match.value(possibleReason).pipe(
|
|
138
141
|
Match.when('BotBlockedByUser', () =>
|
|
@@ -171,3 +174,358 @@ type GiftsCollector = (
|
|
|
171
174
|
BotApi.BotApi
|
|
172
175
|
>
|
|
173
176
|
```
|
|
177
|
+
|
|
178
|
+
## Sending messages
|
|
179
|
+
|
|
180
|
+
One of the most common tasks for a messenger bot is sending messages.
|
|
181
|
+
|
|
182
|
+
Bot API exposes multiple methods for sending a message, each corresponding to a different content type:
|
|
183
|
+
|
|
184
|
+
- `sendMessage` for text;
|
|
185
|
+
- `sendPhoto` for photos;
|
|
186
|
+
- `sendVideo` for videos;
|
|
187
|
+
- and so on.
|
|
188
|
+
|
|
189
|
+
`Send` module provides a unified, more composable way to send messages of all kinds.
|
|
190
|
+
|
|
191
|
+
### Basic usage
|
|
192
|
+
|
|
193
|
+
To send a message, you need:
|
|
194
|
+
|
|
195
|
+
- **Content** — content of the message to be sent.
|
|
196
|
+
- **Dialog** — target chat and topic where the message will be sent.
|
|
197
|
+
- **Markup** — (optional) markup for replying to the message.
|
|
198
|
+
- **Reply** — (optional) information about the message being replied to.
|
|
199
|
+
- **Options** — (optional) additional options for sending the message.
|
|
200
|
+
|
|
201
|
+
`Send.sendMessage` function accepts mentioned parameters and returns an `Effect` that sends a message, automatically choosing the appropriate Bot API method based on the content type.
|
|
202
|
+
|
|
203
|
+
**Example:** Sending messages using `Send.sendMessage`.
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
import { Content, Dialog, File, Markup, Reply, Send, Text } from '@grom.js/effect-tg'
|
|
207
|
+
import { Effect } from 'effect'
|
|
208
|
+
|
|
209
|
+
const program = Effect.gen(function* () {
|
|
210
|
+
// Plain text to a user
|
|
211
|
+
const greeting = yield* Send.sendMessage({
|
|
212
|
+
content: Content.text(Text.plain('Hey! Wanna roll a dice?')),
|
|
213
|
+
dialog: Dialog.user(382713),
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
// Photo with formatted caption and inline keyboard
|
|
217
|
+
yield* Send.sendMessage({
|
|
218
|
+
content: Content.photo(
|
|
219
|
+
File.External(new URL('https://cataas.com/cat')),
|
|
220
|
+
{ caption: Text.html('<b>Cat of the day</b>\n<i>Rate this cat:</i>') },
|
|
221
|
+
),
|
|
222
|
+
dialog: Dialog.user(382713),
|
|
223
|
+
markup: Markup.inlineKeyboard([
|
|
224
|
+
[Markup.InlineButton.callback('❤️', 'rate_love')],
|
|
225
|
+
[Markup.InlineButton.callback('👎', 'rate_nope')],
|
|
226
|
+
]),
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
// Reply with a dice
|
|
230
|
+
const roll = yield* Send.sendMessage({
|
|
231
|
+
content: Content.dice('🎲'),
|
|
232
|
+
dialog: Dialog.user(382713),
|
|
233
|
+
reply: Reply.toMessage(greeting),
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
const rolled = roll.dice!.value
|
|
237
|
+
if (rolled === 6) {
|
|
238
|
+
// DM channel
|
|
239
|
+
yield* Send.sendMessage({
|
|
240
|
+
content: Content.text(Text.plain(`User 382713 rolled ${rolled}.`)),
|
|
241
|
+
dialog: Dialog.channel(100200).directMessages(42),
|
|
242
|
+
})
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
// Send silently
|
|
246
|
+
yield* Send.sendMessage({
|
|
247
|
+
content: Content.text(Text.plain(`You rolled ${rolled}. Disappointing.`)),
|
|
248
|
+
dialog: Dialog.user(382713),
|
|
249
|
+
options: Send.options({ disableNotification: true })
|
|
250
|
+
})
|
|
251
|
+
}
|
|
252
|
+
})
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
#### Content
|
|
256
|
+
|
|
257
|
+
`Content` module provides constructors for creating objects that represent the content of a message. `Send.sendMessage` uses the content type to choose the appropriate Bot API method automatically.
|
|
258
|
+
|
|
259
|
+
| Constructor | Bot API method | Description |
|
|
260
|
+
| ---------------------- | --------------- | ---------------------- |
|
|
261
|
+
| `Content.text` | `sendMessage` | Text |
|
|
262
|
+
| `Content.photo` | `sendPhoto` | Photo |
|
|
263
|
+
| `Content.video` | `sendVideo` | Video |
|
|
264
|
+
| `Content.animation` | `sendAnimation` | GIF or video w/o sound |
|
|
265
|
+
| `Content.audio` | `sendAudio` | Audio file |
|
|
266
|
+
| `Content.voice` | `sendVoice` | Voice note |
|
|
267
|
+
| `Content.videoNote` | `sendVideoNote` | Round video note |
|
|
268
|
+
| `Content.document` | `sendDocument` | File of any type |
|
|
269
|
+
| `Content.sticker` | `sendSticker` | Sticker |
|
|
270
|
+
| `Content.location` | `sendLocation` | Static location |
|
|
271
|
+
| `Content.liveLocation` | `sendLocation` | Live location |
|
|
272
|
+
| `Content.venue` | `sendVenue` | Venue with address |
|
|
273
|
+
| `Content.contact` | `sendContact` | Phone contact |
|
|
274
|
+
| `Content.dice` | `sendDice` | Random dice |
|
|
275
|
+
|
|
276
|
+
#### Dialog
|
|
277
|
+
|
|
278
|
+
`Dialog` module provides utilities for creating target chats:
|
|
279
|
+
|
|
280
|
+
- `Dialog.user(id)` — private chat with a user.
|
|
281
|
+
- `Dialog.group(id)` — chat of a (basic) group.
|
|
282
|
+
- `Dialog.supergroup(id)` — supergroup chat.
|
|
283
|
+
- `Dialog.channel(id)` — channel.
|
|
284
|
+
|
|
285
|
+
To target a specific topic, chain a method on the peer:
|
|
286
|
+
|
|
287
|
+
- `Dialog.user(id).topic(topicId)` — topic in a private chat.
|
|
288
|
+
- `Dialog.supergroup(id).topic(topicId)` — topic in a forum supergroup.
|
|
289
|
+
- `Dialog.channel(id).directMessages(topicId)` — channel direct messages.
|
|
290
|
+
|
|
291
|
+
`Dialog.ofMessage` helper extracts the dialog from an incoming `Message` object.
|
|
292
|
+
|
|
293
|
+
##### Dialog and peer IDs
|
|
294
|
+
|
|
295
|
+
Bot API uses a single integer to encode peer type with its ID — [dialog ID](https://core.telegram.org/api/bots/ids).
|
|
296
|
+
|
|
297
|
+
This may not be a problem for user IDs, since user IDs map to the same dialog IDs.
|
|
298
|
+
However, this may cause some defects when working with other peers.
|
|
299
|
+
For example, to send a message to a channel with ID `3011378744`, you need to set `chat_id` parameter to `-1003011378744`.
|
|
300
|
+
|
|
301
|
+
To prevent this confusion, `Dialog` module defines **branded types** that distinguish peer IDs from dialog IDs at the type level:
|
|
302
|
+
|
|
303
|
+
- `UserId` — number representing a user ID.
|
|
304
|
+
- `GroupId` — number representing a group ID.
|
|
305
|
+
- `ChannelId` — number representing a channel ID.
|
|
306
|
+
- `SupergroupId` — alias to `ChannelId`, since supergroups share ID space with channels.
|
|
307
|
+
- `DialogId` — number encoding peer type and peer ID.
|
|
308
|
+
|
|
309
|
+
Constructors like `Dialog.user`, `Dialog.channel`, etc. validate and encode IDs internally, so you rarely need to convert manually. When you do, `Dialog` module exports conversion utilities:
|
|
310
|
+
|
|
311
|
+
- `Dialog.decodeDialogId(dialogId)` — decodes a dialog ID into peer type and peer ID.
|
|
312
|
+
- `Dialog.decodePeerId(peer, dialogId)` — extracts a typed peer ID from a dialog ID.
|
|
313
|
+
- `Dialog.encodePeerId(peer, id)` — encodes a peer type and ID into a dialog ID.
|
|
314
|
+
|
|
315
|
+
#### Markup
|
|
316
|
+
|
|
317
|
+
`Markup` module provides reply markup types and constructors:
|
|
318
|
+
|
|
319
|
+
- `Markup.inlineKeyboard(rows)` — inline keyboard attached to the message.
|
|
320
|
+
- `Markup.replyKeyboard(rows, options?)` — custom keyboard for quick reply or other action.
|
|
321
|
+
- `Markup.replyKeyboardRemove()` — hide a previously shown reply keyboard.
|
|
322
|
+
- `Markup.forceReply()` — forces Telegram client to reply to the message.
|
|
323
|
+
|
|
324
|
+
**Example:** Creating reply markups.
|
|
325
|
+
|
|
326
|
+
```ts
|
|
327
|
+
import { Markup } from '@grom.js/effect-tg'
|
|
328
|
+
|
|
329
|
+
const inline = Markup.inlineKeyboard([
|
|
330
|
+
[Markup.InlineButton.callback('Like', 'liked')],
|
|
331
|
+
[Markup.InlineButton.url('Source code', 'https://github.com/grom-dev/effect-tg')],
|
|
332
|
+
])
|
|
333
|
+
|
|
334
|
+
const reply = Markup.replyKeyboard(
|
|
335
|
+
[
|
|
336
|
+
['Option A', 'Option B'],
|
|
337
|
+
[Markup.ReplyButton.requestContact('Share phone')],
|
|
338
|
+
],
|
|
339
|
+
{ oneTime: true, resizable: true }
|
|
340
|
+
)
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Prepared messages
|
|
344
|
+
|
|
345
|
+
`Send.message` creates a `MessageToSend` — prepared message that bundles content, markup, reply, and options.
|
|
346
|
+
|
|
347
|
+
`MessageToSend` is also an `Effect`, which means:
|
|
348
|
+
|
|
349
|
+
- It can be piped to chain modifiers that customize markup, reply, and options.
|
|
350
|
+
- It can be executed to send the message. To be sent, `Send.TargetDialog` service should be provided.
|
|
351
|
+
|
|
352
|
+
**Example:** Creating and sending prepared messages.
|
|
353
|
+
|
|
354
|
+
```ts
|
|
355
|
+
import { Content, Dialog, Send, Text } from '@grom.js/effect-tg'
|
|
356
|
+
import { Effect } from 'effect'
|
|
357
|
+
|
|
358
|
+
// Reusable template
|
|
359
|
+
const welcomeMessage = Send.message(
|
|
360
|
+
Content.text(Text.html('<b>Welcome!</b> Thanks for joining.'))
|
|
361
|
+
).pipe(
|
|
362
|
+
Send.withMarkup(
|
|
363
|
+
Markup.replyKeyboard([
|
|
364
|
+
[Markup.ReplyButton.text('Effect?')],
|
|
365
|
+
[Markup.ReplyButton.text('Die.')],
|
|
366
|
+
]),
|
|
367
|
+
),
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
// Send to different dialogs
|
|
371
|
+
const greet1 = Effect.gen(function* () {
|
|
372
|
+
yield* welcomeMessage.pipe(Send.to(Dialog.user(123)))
|
|
373
|
+
yield* welcomeMessage.pipe(Send.to(Dialog.channel(321)))
|
|
374
|
+
})
|
|
375
|
+
|
|
376
|
+
// Send to the same dialog with different options
|
|
377
|
+
const greet2 = Effect.gen(function* () {
|
|
378
|
+
yield* welcomeMessage.pipe(Send.withoutNotification)
|
|
379
|
+
yield* welcomeMessage.pipe(Send.withContentProtection)
|
|
380
|
+
}).pipe(
|
|
381
|
+
Send.to(Dialog.supergroup(4).topic(2)),
|
|
382
|
+
)
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Composing options
|
|
386
|
+
|
|
387
|
+
Chain modifiers on a `MessageToSend` to customize its behavior:
|
|
388
|
+
|
|
389
|
+
- `withMarkup`/`withoutMarkup` — set/remove reply markup.
|
|
390
|
+
- `withReply`/`withoutReply` — set/remove reply options.
|
|
391
|
+
- `withNotification`/`withoutNotification` — enable/disable notification sound.
|
|
392
|
+
- `withContentProtection`/`withoutContentProtection` — prevent/allow forwarding and saving.
|
|
393
|
+
- `withPaidBroadcast`/`withoutPaidBroadcast` — enable/disable paid broadcast.
|
|
394
|
+
- `withOptions` — merge with the new send options.
|
|
395
|
+
|
|
396
|
+
**Example:** Chaining modifiers on a prepared message.
|
|
397
|
+
|
|
398
|
+
```ts
|
|
399
|
+
import { Content, Markup, Send, Text } from '@grom.js/effect-tg'
|
|
400
|
+
|
|
401
|
+
const secretPromo = Send.message(Content.text(Text.plain('Shh!'))).pipe(
|
|
402
|
+
Send.withMarkup(
|
|
403
|
+
Markup.inlineKeyboard([
|
|
404
|
+
[Markup.InlineButton.copyText('Copy promo', 'EFFECT_TG')],
|
|
405
|
+
]),
|
|
406
|
+
),
|
|
407
|
+
Send.withoutNotification,
|
|
408
|
+
Send.withContentProtection,
|
|
409
|
+
)
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Text formatting
|
|
413
|
+
|
|
414
|
+
`Text` module provides utilities for creating [formatted text](https://core.telegram.org/bots/api#formatting-options) to be used in text messages and captions.
|
|
415
|
+
|
|
416
|
+
**Example:** Formatting text with `Text` module.
|
|
417
|
+
|
|
418
|
+
```tsx
|
|
419
|
+
import { Text } from '@grom.js/effect-tg'
|
|
420
|
+
|
|
421
|
+
// Plain text — sent as is
|
|
422
|
+
Text.plain('*Not bold*. _Not italic_.')
|
|
423
|
+
|
|
424
|
+
// HTML — sent with 'HTML' parse mode
|
|
425
|
+
Text.html('<b>Bold</b> and <i>italic</i>.')
|
|
426
|
+
|
|
427
|
+
// Markdown — sent with 'MarkdownV2' parse mode
|
|
428
|
+
Text.markdown('*Bold* and _italic_.')
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
#### JSX syntax
|
|
432
|
+
|
|
433
|
+
`Text` module also allows to compose formatted text with JSX.
|
|
434
|
+
|
|
435
|
+
Benefits of using JSX:
|
|
436
|
+
|
|
437
|
+
- **Validation**: JSX is validated during compilation, so you can't specify invalid HTML or Markdown.
|
|
438
|
+
- **Composability**: JSX allows composing formatted text with custom components.
|
|
439
|
+
- **Auto-escaping**: JSX escapes special characters, saving you from \<s\>bAd\</s\> \_iNpUtS\_.
|
|
440
|
+
- **Type safety**: LSP hints and type checking for text entities and custom components.
|
|
441
|
+
|
|
442
|
+
`Text.tgx` function accepts a JSX element and returns an instance of `Text.Tgx`, which can then be used as a content of a message.
|
|
443
|
+
|
|
444
|
+
**Example:** Composing reusable messages with JSX.
|
|
445
|
+
|
|
446
|
+
```tsx
|
|
447
|
+
import type { PropsWithChildren } from '@grom.js/tgx/types'
|
|
448
|
+
import { Content, Dialog, Send, Text } from '@grom.js/effect-tg'
|
|
449
|
+
import { pipe } from 'effect'
|
|
450
|
+
|
|
451
|
+
// Reusable component for a key-value field
|
|
452
|
+
const Field = (props: PropsWithChildren<{ label: string }>) => (
|
|
453
|
+
<><b>{props.label}:</b> {props.children}{'\n'}</>
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
// Simple component for convenience
|
|
457
|
+
const RocketEmoji = () => (
|
|
458
|
+
<emoji id="5445284980978621387" alt="🚀" />
|
|
459
|
+
)
|
|
460
|
+
|
|
461
|
+
// Component that renders a deploy summary
|
|
462
|
+
const DeploySummary = (props: {
|
|
463
|
+
service: string
|
|
464
|
+
version: string
|
|
465
|
+
env: string
|
|
466
|
+
author: string
|
|
467
|
+
url: string
|
|
468
|
+
}) => (
|
|
469
|
+
<>
|
|
470
|
+
<RocketEmoji /> <b>Deploy to <i>{props.env}</i></b>
|
|
471
|
+
{'\n\n'}
|
|
472
|
+
<Field label="Service"><code>{props.service}</code></Field>
|
|
473
|
+
<Field label="Version"><code>{props.version}</code></Field>
|
|
474
|
+
<Field label="Author">{props.author}</Field>
|
|
475
|
+
{'\n'}
|
|
476
|
+
<a href={props.url}>View in dashboard</a>
|
|
477
|
+
{'\n\n'}
|
|
478
|
+
<blockquote expandable>
|
|
479
|
+
Changelog:{'\n'}
|
|
480
|
+
- Fix rate limiting on /api/submit{'\n'}
|
|
481
|
+
- Add retry logic for webhook delivery{'\n'}
|
|
482
|
+
- Update dependencies
|
|
483
|
+
</blockquote>
|
|
484
|
+
</>
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
// Create summary text
|
|
488
|
+
const summary = Text.tgx(
|
|
489
|
+
<DeploySummary
|
|
490
|
+
service="billing-api"
|
|
491
|
+
version="2.14.0"
|
|
492
|
+
env="production"
|
|
493
|
+
author="Alice"
|
|
494
|
+
url="https://deploy.example.com/runs/4821"
|
|
495
|
+
/>
|
|
496
|
+
)
|
|
497
|
+
|
|
498
|
+
// Publish a new post
|
|
499
|
+
const publish = Send.message(Content.text(summary)).pipe(
|
|
500
|
+
Send.to(Dialog.channel(3011378744)),
|
|
501
|
+
)
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
<details>
|
|
505
|
+
<summary>How it works?</summary>
|
|
506
|
+
|
|
507
|
+
JSX is just syntactic sugar transformed by the compiler.
|
|
508
|
+
Result of transformation depends on the JSX runtime.
|
|
509
|
+
`effect-tg` relies on JSX runtime from [`@grom.js/tgx`](https://github.com/grom-dev/tgx), which transforms JSX elements to `TgxElement` instances.
|
|
510
|
+
When `Send.sendMessage` encounters an instance of `Text.Tgx`, it converts inner `TgxElement`s to the parameters for a `send*` method.
|
|
511
|
+
|
|
512
|
+
</details>
|
|
513
|
+
|
|
514
|
+
To enable JSX support:
|
|
515
|
+
|
|
516
|
+
1. Install `@grom.js/tgx` package:
|
|
517
|
+
|
|
518
|
+
```sh
|
|
519
|
+
npm install @grom.js/tgx
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
2. Update your `tsconfig.json`:
|
|
523
|
+
|
|
524
|
+
```json
|
|
525
|
+
{
|
|
526
|
+
"compilerOptions": {
|
|
527
|
+
"jsx": "react-jsx",
|
|
528
|
+
"jsxImportSource": "@grom.js/tgx"
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
```
|
package/dist/BotApiError.js
CHANGED
|
@@ -54,7 +54,7 @@ export const fromResponse = (response) => {
|
|
|
54
54
|
if (response.error_code === 400 && response.parameters?.migrate_to_chat_id != null) {
|
|
55
55
|
return new GroupUpgraded({
|
|
56
56
|
response,
|
|
57
|
-
supergroup: Dialog.supergroup(Option.getOrThrow(Dialog.decodePeerId('
|
|
57
|
+
supergroup: Dialog.supergroup(Option.getOrThrow(Dialog.decodePeerId('channel', response.parameters.migrate_to_chat_id))),
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
60
|
if (response.error_code >= 500) {
|
package/dist/BotApiError.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BotApiError.js","sourceRoot":"","sources":["../src/BotApiError.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"BotApiError.js","sourceRoot":"","sources":["../src/BotApiError.ts"],"names":[],"mappings":"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"}
|
package/dist/Dialog.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export declare class ChannelDm extends ChannelDm_base<{
|
|
|
26
26
|
topicId: number;
|
|
27
27
|
}> {
|
|
28
28
|
}
|
|
29
|
-
export type Peer = User | Group |
|
|
29
|
+
export type Peer = User | Group | Channel | Supergroup;
|
|
30
30
|
declare const User_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Readonly<A> & {
|
|
31
31
|
readonly _tag: "User";
|
|
32
32
|
};
|
|
@@ -44,15 +44,6 @@ export declare class Group extends Group_base<{
|
|
|
44
44
|
}> {
|
|
45
45
|
dialogId(): DialogId;
|
|
46
46
|
}
|
|
47
|
-
declare const Supergroup_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Readonly<A> & {
|
|
48
|
-
readonly _tag: "Supergroup";
|
|
49
|
-
};
|
|
50
|
-
export declare class Supergroup extends Supergroup_base<{
|
|
51
|
-
id: SupergroupId;
|
|
52
|
-
}> {
|
|
53
|
-
dialogId(): DialogId;
|
|
54
|
-
topic(topicId: number): ForumTopic;
|
|
55
|
-
}
|
|
56
47
|
declare const Channel_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Readonly<A> & {
|
|
57
48
|
readonly _tag: "Channel";
|
|
58
49
|
};
|
|
@@ -62,6 +53,15 @@ export declare class Channel extends Channel_base<{
|
|
|
62
53
|
dialogId(): DialogId;
|
|
63
54
|
directMessages(topicId: number): ChannelDm;
|
|
64
55
|
}
|
|
56
|
+
declare const Supergroup_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Readonly<A> & {
|
|
57
|
+
readonly _tag: "Supergroup";
|
|
58
|
+
};
|
|
59
|
+
export declare class Supergroup extends Supergroup_base<{
|
|
60
|
+
id: SupergroupId;
|
|
61
|
+
}> {
|
|
62
|
+
dialogId(): DialogId;
|
|
63
|
+
topic(topicId: number): ForumTopic;
|
|
64
|
+
}
|
|
65
65
|
/**
|
|
66
66
|
* Dialog ID is a single integer encoding peer type and its ID.
|
|
67
67
|
*
|
|
@@ -73,16 +73,17 @@ export type UserId = number & Brand.Brand<'@grom.js/effect-tg/UserId'>;
|
|
|
73
73
|
export declare const UserId: Brand.Brand.Constructor<UserId>;
|
|
74
74
|
export type GroupId = number & Brand.Brand<'@grom.js/effect-tg/GroupId'>;
|
|
75
75
|
export declare const GroupId: Brand.Brand.Constructor<GroupId>;
|
|
76
|
-
export type SupergroupId = number & Brand.Brand<'@grom.js/effect-tg/SupergroupId'>;
|
|
77
|
-
export declare const SupergroupId: Brand.Brand.Constructor<SupergroupId>;
|
|
78
|
-
/**
|
|
79
|
-
* @alias SupergroupId
|
|
80
|
-
*/
|
|
81
|
-
export type ChannelId = SupergroupId;
|
|
82
76
|
/**
|
|
83
|
-
*
|
|
77
|
+
* ID for channels (including supergroups).
|
|
78
|
+
*
|
|
79
|
+
* @see {@link https://core.telegram.org/api/bots/ids Telegram API • Bot API dialog IDs}
|
|
84
80
|
*/
|
|
85
|
-
export
|
|
81
|
+
export type ChannelId = number & Brand.Brand<'@grom.js/effect-tg/ChannelId'>;
|
|
82
|
+
export declare const ChannelId: Brand.Brand.Constructor<ChannelId>;
|
|
83
|
+
/** @alias ChannelId */
|
|
84
|
+
export type SupergroupId = ChannelId;
|
|
85
|
+
/** @alias ChannelId */
|
|
86
|
+
export declare const SupergroupId: Brand.Brand.Constructor<ChannelId>;
|
|
86
87
|
export declare const decodeDialogId: (dialogId: number) => Option.Option<{
|
|
87
88
|
peer: 'user';
|
|
88
89
|
id: UserId;
|
|
@@ -90,8 +91,8 @@ export declare const decodeDialogId: (dialogId: number) => Option.Option<{
|
|
|
90
91
|
peer: 'group';
|
|
91
92
|
id: GroupId;
|
|
92
93
|
} | {
|
|
93
|
-
peer: '
|
|
94
|
-
id:
|
|
94
|
+
peer: 'channel';
|
|
95
|
+
id: ChannelId;
|
|
95
96
|
} | {
|
|
96
97
|
peer: 'monoforum';
|
|
97
98
|
id: number;
|
|
@@ -102,15 +103,15 @@ export declare const decodeDialogId: (dialogId: number) => Option.Option<{
|
|
|
102
103
|
export declare const decodePeerId: {
|
|
103
104
|
(peer: 'user', dialogId: number): Option.Option<UserId>;
|
|
104
105
|
(peer: 'group', dialogId: number): Option.Option<GroupId>;
|
|
105
|
-
(peer: '
|
|
106
|
+
(peer: 'channel', dialogId: number): Option.Option<ChannelId>;
|
|
106
107
|
(peer: 'monoforum', dialogId: number): Option.Option<number>;
|
|
107
108
|
(peer: 'secret-chat', dialogId: number): Option.Option<number>;
|
|
108
109
|
};
|
|
109
|
-
export declare const encodePeerId: (peer: 'user' | 'group' | '
|
|
110
|
+
export declare const encodePeerId: (peer: 'user' | 'group' | 'channel' | 'monoforum' | 'secret-chat', id: number) => Option.Option<DialogId>;
|
|
110
111
|
export declare const user: (id: number) => User;
|
|
111
112
|
export declare const group: (id: number) => Group;
|
|
112
|
-
export declare const supergroup: (id: number) => Supergroup;
|
|
113
113
|
export declare const channel: (id: number) => Channel;
|
|
114
|
+
export declare const supergroup: (id: number) => Supergroup;
|
|
114
115
|
export declare const ofMessage: (message: BotApi.Types.Message) => Dialog;
|
|
115
116
|
export {};
|
|
116
117
|
//# sourceMappingURL=Dialog.d.ts.map
|
package/dist/Dialog.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../src/Dialog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAOvC,MAAM,MAAM,MAAM,GACd,IAAI,GACJ,YAAY,GACZ,UAAU,GACV,SAAS,CAAA;;;;AAEb,qBAAa,YAAa,SAAQ,kBAAiC;IACjE,IAAI,EAAE,IAAI,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;CAChB,CAAC;CAAG;;;;AAEL,qBAAa,UAAW,SAAQ,gBAA+B;IAC7D,UAAU,EAAE,UAAU,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAC;CAAG;;;;AAEL,qBAAa,SAAU,SAAQ,eAA8B;IAC3D,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAC;CAAG;AAML,MAAM,MAAM,IAAI,GACZ,IAAI,GACJ,KAAK,GACL,
|
|
1
|
+
{"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../src/Dialog.ts"],"names":[],"mappings":"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"}
|
package/dist/Dialog.js
CHANGED
|
@@ -21,30 +21,28 @@ export class Group extends Data.TaggedClass('Group') {
|
|
|
21
21
|
return Option.getOrThrow(internal.encodePeerId('group', this.id));
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
export class
|
|
24
|
+
export class Channel extends Data.TaggedClass('Channel') {
|
|
25
25
|
dialogId() {
|
|
26
|
-
return Option.getOrThrow(internal.encodePeerId('
|
|
26
|
+
return Option.getOrThrow(internal.encodePeerId('channel', this.id));
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
return new
|
|
28
|
+
directMessages(topicId) {
|
|
29
|
+
return new ChannelDm({ channel: this, topicId });
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
export class
|
|
32
|
+
export class Supergroup extends Data.TaggedClass('Supergroup') {
|
|
33
33
|
dialogId() {
|
|
34
|
-
return Option.getOrThrow(internal.encodePeerId('
|
|
34
|
+
return Option.getOrThrow(internal.encodePeerId('channel', this.id));
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
return new
|
|
36
|
+
topic(topicId) {
|
|
37
|
+
return new ForumTopic({ supergroup: this, topicId });
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
export const DialogId = Brand.refined(n => Option.isSome(internal.decodeDialogId(n)), n => Brand.error(`Invalid dialog ID: ${n}`));
|
|
41
41
|
export const UserId = Brand.refined(n => Option.isSome(internal.encodePeerId('user', n)), n => Brand.error(`Invalid user ID: ${n}`));
|
|
42
42
|
export const GroupId = Brand.refined(n => Option.isSome(internal.encodePeerId('group', n)), n => Brand.error(`Invalid group ID: ${n}`));
|
|
43
|
-
export const
|
|
44
|
-
/**
|
|
45
|
-
|
|
46
|
-
*/
|
|
47
|
-
export const ChannelId = SupergroupId;
|
|
43
|
+
export const ChannelId = Brand.refined(n => Option.isSome(internal.encodePeerId('channel', n)), n => Brand.error(`Invalid channel or supergroup ID: ${n}`));
|
|
44
|
+
/** @alias ChannelId */
|
|
45
|
+
export const SupergroupId = ChannelId;
|
|
48
46
|
// =============================================================================
|
|
49
47
|
// Dialog ID <-> Peer ID
|
|
50
48
|
// =============================================================================
|
|
@@ -60,11 +58,11 @@ export const user = (id) => {
|
|
|
60
58
|
export const group = (id) => {
|
|
61
59
|
return new Group({ id: GroupId(id) });
|
|
62
60
|
};
|
|
63
|
-
export const supergroup = (id) => {
|
|
64
|
-
return new Supergroup({ id: SupergroupId(id) });
|
|
65
|
-
};
|
|
66
61
|
export const channel = (id) => {
|
|
67
|
-
return new Channel({ id:
|
|
62
|
+
return new Channel({ id: ChannelId(id) });
|
|
63
|
+
};
|
|
64
|
+
export const supergroup = (id) => {
|
|
65
|
+
return new Supergroup({ id: ChannelId(id) });
|
|
68
66
|
};
|
|
69
67
|
export const ofMessage = internal.ofMessage;
|
|
70
68
|
//# sourceMappingURL=Dialog.js.map
|