@grom.js/effect-tg 0.7.0 → 0.9.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.
Files changed (99) hide show
  1. package/README.md +162 -5
  2. package/dist/BotApi.d.ts +10 -12
  3. package/dist/BotApi.d.ts.map +1 -1
  4. package/dist/BotApi.js +2 -2
  5. package/dist/BotApi.js.map +1 -1
  6. package/dist/BotApiError.d.ts +46 -71
  7. package/dist/BotApiError.d.ts.map +1 -1
  8. package/dist/BotApiError.js +59 -41
  9. package/dist/BotApiError.js.map +1 -1
  10. package/dist/BotApiTransport.d.ts +10 -17
  11. package/dist/BotApiTransport.d.ts.map +1 -1
  12. package/dist/BotApiTransport.js +2 -7
  13. package/dist/BotApiTransport.js.map +1 -1
  14. package/dist/BotApiUrl.d.ts +6 -8
  15. package/dist/BotApiUrl.d.ts.map +1 -1
  16. package/dist/BotApiUrl.js.map +1 -1
  17. package/dist/Content.d.ts.map +1 -1
  18. package/dist/Dialog.d.ts +96 -41
  19. package/dist/Dialog.d.ts.map +1 -1
  20. package/dist/Dialog.js +60 -25
  21. package/dist/Dialog.js.map +1 -1
  22. package/dist/File.d.ts +1 -2
  23. package/dist/File.d.ts.map +1 -1
  24. package/dist/File.js +1 -1
  25. package/dist/File.js.map +1 -1
  26. package/dist/Markup.d.ts.map +1 -1
  27. package/dist/Runner.d.ts +1 -1
  28. package/dist/Runner.d.ts.map +1 -1
  29. package/dist/Send.d.ts +57 -130
  30. package/dist/Send.d.ts.map +1 -1
  31. package/dist/Send.js +65 -128
  32. package/dist/Send.js.map +1 -1
  33. package/dist/Text.d.ts.map +1 -1
  34. package/dist/internal/botApi.d.ts +3 -1
  35. package/dist/internal/botApi.d.ts.map +1 -1
  36. package/dist/internal/botApi.gen.d.ts +6501 -0
  37. package/dist/internal/botApi.gen.d.ts.map +1 -0
  38. package/dist/internal/botApi.gen.js +2 -0
  39. package/dist/internal/botApi.gen.js.map +1 -0
  40. package/dist/internal/botApi.js +2 -6
  41. package/dist/internal/botApi.js.map +1 -1
  42. package/dist/internal/botApiError.d.ts +5 -2
  43. package/dist/internal/botApiError.d.ts.map +1 -1
  44. package/dist/internal/botApiError.js +8 -18
  45. package/dist/internal/botApiError.js.map +1 -1
  46. package/dist/internal/botApiTransport.d.ts +5 -2
  47. package/dist/internal/botApiTransport.d.ts.map +1 -1
  48. package/dist/internal/botApiTransport.js +14 -10
  49. package/dist/internal/botApiTransport.js.map +1 -1
  50. package/dist/internal/dialog.d.ts +27 -10
  51. package/dist/internal/dialog.d.ts.map +1 -1
  52. package/dist/internal/dialog.js +88 -14
  53. package/dist/internal/dialog.js.map +1 -1
  54. package/dist/internal/file.d.ts +1 -1
  55. package/dist/internal/file.d.ts.map +1 -1
  56. package/dist/internal/file.js +1 -1
  57. package/dist/internal/file.js.map +1 -1
  58. package/dist/internal/runner.d.ts +4 -5
  59. package/dist/internal/runner.d.ts.map +1 -1
  60. package/dist/internal/runner.js +14 -19
  61. package/dist/internal/runner.js.map +1 -1
  62. package/dist/internal/send.d.ts +4 -4
  63. package/dist/internal/send.d.ts.map +1 -1
  64. package/dist/internal/send.js +62 -51
  65. package/dist/internal/send.js.map +1 -1
  66. package/package.json +12 -10
  67. package/src/BotApi.ts +38 -31
  68. package/src/BotApiError.ts +109 -63
  69. package/src/BotApiTransport.ts +18 -20
  70. package/src/BotApiUrl.ts +6 -8
  71. package/src/Content.ts +14 -14
  72. package/src/Dialog.ts +164 -42
  73. package/src/File.ts +3 -4
  74. package/src/Markup.ts +5 -5
  75. package/src/Send.ts +114 -202
  76. package/src/Text.ts +5 -5
  77. package/src/internal/botApi.gen.ts +6783 -0
  78. package/src/internal/botApi.ts +7 -11
  79. package/src/internal/botApiError.ts +15 -20
  80. package/src/internal/botApiTransport.ts +25 -17
  81. package/src/internal/dialog.ts +109 -26
  82. package/src/internal/file.ts +1 -1
  83. package/src/internal/runner.ts +34 -38
  84. package/src/internal/send.ts +161 -132
  85. package/dist/internal/botApiMethods.gen.d.ts +0 -2026
  86. package/dist/internal/botApiMethods.gen.d.ts.map +0 -1
  87. package/dist/internal/botApiMethods.gen.js +0 -2
  88. package/dist/internal/botApiMethods.gen.js.map +0 -1
  89. package/dist/internal/botApiShape.gen.d.ts +0 -398
  90. package/dist/internal/botApiShape.gen.d.ts.map +0 -1
  91. package/dist/internal/botApiShape.gen.js +0 -2
  92. package/dist/internal/botApiShape.gen.js.map +0 -1
  93. package/dist/internal/botApiTypes.gen.d.ts +0 -3903
  94. package/dist/internal/botApiTypes.gen.d.ts.map +0 -1
  95. package/dist/internal/botApiTypes.gen.js +0 -2
  96. package/dist/internal/botApiTypes.gen.js.map +0 -1
  97. package/src/internal/botApiMethods.gen.ts +0 -2027
  98. package/src/internal/botApiShape.gen.ts +0 -398
  99. package/src/internal/botApiTypes.gen.ts +0 -4178
@@ -1,33 +1,83 @@
1
1
  import type * as Content from '../Content.ts'
2
2
  import type * as Dialog from '../Dialog.ts'
3
- import type * as Dialog_ from '../Dialog.ts'
4
3
  import type * as Markup from '../Markup.ts'
5
4
  import type * as Send from '../Send.ts'
6
5
  import type * as Text from '../Text.ts'
7
6
  import * as Tgx from '@grom.js/tgx'
8
7
  import * as Duration from 'effect/Duration'
9
8
  import * as Effect from 'effect/Effect'
10
- import * as Function from 'effect/Function'
11
9
  import * as Match from 'effect/Match'
12
10
  import * as Option from 'effect/Option'
13
11
  import * as BotApi from '../BotApi.ts'
14
12
  import * as LinkPreview from '../LinkPreview.ts'
15
13
 
14
+ // =============================================================================
15
+ // Helpers
16
+ // =============================================================================
17
+
18
+ const methodByContent: Record<Content.Content['_tag'], SendMethod> = {
19
+ Text: 'sendMessage',
20
+ Photo: 'sendPhoto',
21
+ Audio: 'sendAudio',
22
+ Document: 'sendDocument',
23
+ Video: 'sendVideo',
24
+ Animation: 'sendAnimation',
25
+ Voice: 'sendVoice',
26
+ VideoNote: 'sendVideoNote',
27
+ Location: 'sendLocation',
28
+ Venue: 'sendVenue',
29
+ Contact: 'sendContact',
30
+ Dice: 'sendDice',
31
+ Sticker: 'sendSticker',
32
+ }
33
+
34
+ type SendMethod = Extract<
35
+ keyof BotApi.MethodParams,
36
+ | 'sendMessage'
37
+ | 'sendPhoto'
38
+ | 'sendAudio'
39
+ | 'sendDocument'
40
+ | 'sendVideo'
41
+ | 'sendAnimation'
42
+ | 'sendVoice'
43
+ | 'sendVideoNote'
44
+ | 'sendPaidMedia'
45
+ | 'sendLocation'
46
+ | 'sendVenue'
47
+ | 'sendContact'
48
+ | 'sendDice'
49
+ | 'sendSticker'
50
+ | 'sendInvoice'
51
+ >
52
+
53
+ type PickMethodParams<
54
+ TMethod extends keyof BotApi.MethodParams,
55
+ TPick extends keyof BotApi.MethodParams[TMethod],
56
+ > = Pick<BotApi.MethodParams[TMethod], TPick>
57
+
58
+ // =============================================================================
59
+ // Parameters (Text)
60
+ // =============================================================================
61
+
16
62
  type ParamsText = PickMethodParams<'sendMessage', 'text' | 'entities' | 'parse_mode'>
17
- const paramsText: (text: Text.Text) => ParamsText = Function.pipe(
18
- Match.type<Text.Text>(),
63
+
64
+ const paramsText: (
65
+ text: Text.Text,
66
+ ) => ParamsText = Match.type<Text.Text>().pipe(
19
67
  Match.withReturnType<ParamsText>(),
20
- Match.tags({
68
+ Match.tagsExhaustive({
21
69
  Plain: ({ text, entities }) => ({ text, entities }),
22
70
  Html: ({ html }) => ({ text: html, parse_mode: 'HTML' }),
23
71
  Markdown: ({ markdown }) => ({ text: markdown, parse_mode: 'MarkdownV2' }),
24
72
  Tgx: ({ tgx }) => ({ text: Tgx.html(tgx), parse_mode: 'HTML' }),
25
73
  }),
26
- Match.exhaustive,
27
74
  )
28
75
 
29
76
  type ParamsCaption = PickMethodParams<'sendPhoto', 'caption' | 'caption_entities' | 'parse_mode'>
30
- const paramsCaption = (caption: Option.Option<Text.Text>): ParamsCaption => (
77
+
78
+ const paramsCaption = (
79
+ caption: Option.Option<Text.Text>,
80
+ ): ParamsCaption => (
31
81
  Option.match(caption, {
32
82
  onNone: () => ({}),
33
83
  onSome: (caption) => {
@@ -37,50 +87,44 @@ const paramsCaption = (caption: Option.Option<Text.Text>): ParamsCaption => (
37
87
  })
38
88
  )
39
89
 
40
- type ParamsContentText = PickMethodParams<'sendMessage', 'text' | 'entities' | 'parse_mode' | 'link_preview_options'>
41
- type ParamsContentPhoto = PickMethodParams<'sendPhoto', 'photo' | 'caption' | 'caption_entities' | 'parse_mode' | 'show_caption_above_media' | 'has_spoiler'>
42
- type ParamsContentAudio = PickMethodParams<'sendAudio', 'audio' | 'caption' | 'caption_entities' | 'parse_mode' | 'duration' | 'performer' | 'title' | 'thumbnail'>
43
- type ParamsContentDocument = PickMethodParams<'sendDocument', 'document' | 'thumbnail' | 'caption' | 'parse_mode' | 'caption_entities' | 'disable_content_type_detection'>
44
- type ParamsContentVideo = PickMethodParams<'sendVideo', 'video' | 'duration' | 'width' | 'height' | 'thumbnail' | 'cover' | 'start_timestamp' | 'show_caption_above_media' | 'has_spoiler' | 'supports_streaming'>
45
- type ParamsContentAnimation = PickMethodParams<'sendAnimation', 'animation' | 'duration' | 'width' | 'height' | 'thumbnail' | 'has_spoiler'>
46
- type ParamsContentVoice = PickMethodParams<'sendVoice', 'voice' | 'duration'>
47
- type ParamsContentVideoNote = PickMethodParams<'sendVideoNote', 'video_note' | 'duration' | 'length' | 'thumbnail'>
48
- type ParamsContentLocation = PickMethodParams<'sendLocation', 'latitude' | 'longitude' | 'horizontal_accuracy' | 'live_period' | 'heading' | 'proximity_alert_radius'>
49
- type ParamsContentVenue = PickMethodParams<'sendVenue', 'latitude' | 'longitude' | 'title' | 'address' | 'foursquare_id' | 'foursquare_type' | 'google_place_id' | 'google_place_type'>
50
- type ParamsContentContact = PickMethodParams<'sendContact', 'phone_number' | 'first_name' | 'last_name' | 'vcard'>
51
- type ParamsContentDice = PickMethodParams<'sendDice', 'emoji'>
52
- type ParamsContentSticker = PickMethodParams<'sendSticker', 'sticker' | 'emoji'>
53
- const paramsContent: {
54
- (content: Content.Text): ParamsContentText
55
- (content: Content.Photo): ParamsContentPhoto
56
- (content: Content.Audio): ParamsContentAudio
57
- (content: Content.Document): ParamsContentDocument
58
- (content: Content.Video): ParamsContentVideo
59
- (content: Content.Animation): ParamsContentAnimation
60
- (content: Content.Voice): ParamsContentVoice
61
- (content: Content.VideoNote): ParamsContentVideoNote
62
- (content: Content.Location): ParamsContentLocation
63
- (content: Content.Venue): ParamsContentVenue
64
- (content: Content.Contact): ParamsContentContact
65
- (content: Content.Dice): ParamsContentDice
66
- (content: Content.Sticker): ParamsContentSticker
67
- } = Function.pipe(
68
- Match.type<Content.Content>(),
69
- Match.tags({
70
- Text: ({ text, linkPreview }): ParamsContentText => ({
90
+ // =============================================================================
91
+ // Parameters (Content)
92
+ // =============================================================================
93
+
94
+ type ParamsContent =
95
+ | PickMethodParams<'sendMessage', 'text' | 'entities' | 'parse_mode' | 'link_preview_options'>
96
+ | PickMethodParams<'sendPhoto', 'photo' | 'caption' | 'caption_entities' | 'parse_mode' | 'show_caption_above_media' | 'has_spoiler'>
97
+ | PickMethodParams<'sendAudio', 'audio' | 'caption' | 'caption_entities' | 'parse_mode' | 'duration' | 'performer' | 'title' | 'thumbnail'>
98
+ | PickMethodParams<'sendDocument', 'document' | 'thumbnail' | 'caption' | 'parse_mode' | 'caption_entities' | 'disable_content_type_detection'>
99
+ | PickMethodParams<'sendVideo', 'video' | 'duration' | 'width' | 'height' | 'thumbnail' | 'cover' | 'start_timestamp' | 'show_caption_above_media' | 'has_spoiler' | 'supports_streaming'>
100
+ | PickMethodParams<'sendAnimation', 'animation' | 'duration' | 'width' | 'height' | 'thumbnail' | 'has_spoiler'>
101
+ | PickMethodParams<'sendVoice', 'voice' | 'duration'>
102
+ | PickMethodParams<'sendVideoNote', 'video_note' | 'duration' | 'length' | 'thumbnail'>
103
+ | PickMethodParams<'sendLocation', 'latitude' | 'longitude' | 'horizontal_accuracy' | 'live_period' | 'heading' | 'proximity_alert_radius'>
104
+ | PickMethodParams<'sendVenue', 'latitude' | 'longitude' | 'title' | 'address' | 'foursquare_id' | 'foursquare_type' | 'google_place_id' | 'google_place_type'>
105
+ | PickMethodParams<'sendContact', 'phone_number' | 'first_name' | 'last_name' | 'vcard'>
106
+ | PickMethodParams<'sendDice', 'emoji'>
107
+ | PickMethodParams<'sendSticker', 'sticker' | 'emoji'>
108
+
109
+ const paramsContent: (
110
+ content: Content.Content,
111
+ ) => ParamsContent = Match.type<Content.Content>().pipe(
112
+ Match.withReturnType<ParamsContent>(),
113
+ Match.tagsExhaustive({
114
+ Text: ({ text, linkPreview }) => ({
71
115
  ...paramsText(text),
72
116
  link_preview_options: Option.match(linkPreview, {
73
117
  onNone: () => ({ is_disabled: true }),
74
118
  onSome: linkPreview => LinkPreview.options(linkPreview),
75
119
  }),
76
120
  }),
77
- Photo: ({ file, caption, layout, spoiler }): ParamsContentPhoto => ({
121
+ Photo: ({ file, caption, layout, spoiler }) => ({
78
122
  ...paramsCaption(caption),
79
123
  photo: file instanceof URL ? file.toString() : file,
80
124
  show_caption_above_media: layout === 'caption-above',
81
125
  has_spoiler: spoiler,
82
126
  }),
83
- Audio: ({ file, caption, duration, performer, title, thumbnail }): ParamsContentAudio => ({
127
+ Audio: ({ file, caption, duration, performer, title, thumbnail }) => ({
84
128
  ...paramsCaption(caption),
85
129
  audio: file instanceof URL ? file.toString() : file,
86
130
  duration: Option.match(duration, {
@@ -91,13 +135,13 @@ const paramsContent: {
91
135
  title: Option.getOrUndefined(title),
92
136
  thumbnail: Option.getOrUndefined(thumbnail),
93
137
  }),
94
- Document: ({ file, caption, thumbnail, contentTypeDetection }): ParamsContentDocument => ({
138
+ Document: ({ file, caption, thumbnail, contentTypeDetection }) => ({
95
139
  ...paramsCaption(caption),
96
140
  document: file instanceof URL ? file.toString() : file,
97
141
  thumbnail: Option.getOrUndefined(thumbnail),
98
142
  disable_content_type_detection: !contentTypeDetection,
99
143
  }),
100
- Video: ({ file, caption, layout, spoiler, duration, width, height, thumbnail, cover, startAt, supportsStreaming }): ParamsContentVideo => ({
144
+ Video: ({ file, caption, layout, spoiler, duration, width, height, thumbnail, cover, startAt, supportsStreaming }) => ({
101
145
  ...paramsCaption(caption),
102
146
  video: file instanceof URL ? file.toString() : file,
103
147
  duration: Option.match(duration, {
@@ -116,7 +160,7 @@ const paramsContent: {
116
160
  has_spoiler: spoiler,
117
161
  supports_streaming: supportsStreaming,
118
162
  }),
119
- Animation: ({ file, caption, spoiler, duration, width, height, thumbnail }): ParamsContentAnimation => ({
163
+ Animation: ({ file, caption, spoiler, duration, width, height, thumbnail }) => ({
120
164
  ...paramsCaption(caption),
121
165
  animation: file instanceof URL ? file.toString() : file,
122
166
  duration: Option.match(duration, {
@@ -128,7 +172,7 @@ const paramsContent: {
128
172
  thumbnail: Option.getOrUndefined(thumbnail),
129
173
  has_spoiler: spoiler,
130
174
  }),
131
- Voice: ({ file, caption, duration }): ParamsContentVoice => ({
175
+ Voice: ({ file, caption, duration }) => ({
132
176
  ...paramsCaption(caption),
133
177
  voice: file instanceof URL ? file.toString() : file,
134
178
  duration: Option.match(duration, {
@@ -136,7 +180,7 @@ const paramsContent: {
136
180
  onSome: duration => Math.round(Duration.toSeconds(duration)),
137
181
  }),
138
182
  }),
139
- VideoNote: ({ file, duration, diameter, thumbnail }): ParamsContentVideoNote => ({
183
+ VideoNote: ({ file, duration, diameter, thumbnail }) => ({
140
184
  video_note: file,
141
185
  duration: Option.match(duration, {
142
186
  onNone: () => undefined,
@@ -145,7 +189,7 @@ const paramsContent: {
145
189
  length: Option.getOrUndefined(diameter),
146
190
  thumbnail: Option.getOrUndefined(thumbnail),
147
191
  }),
148
- Location: ({ latitude, longitude, uncertaintyRadius, livePeriod, heading, proximityAlertRadius }): ParamsContentLocation => ({
192
+ Location: ({ latitude, longitude, uncertaintyRadius, livePeriod, heading, proximityAlertRadius }) => ({
149
193
  latitude,
150
194
  longitude,
151
195
  horizontal_accuracy: Option.getOrUndefined(uncertaintyRadius),
@@ -158,7 +202,7 @@ const paramsContent: {
158
202
  heading: Option.getOrUndefined(heading),
159
203
  proximity_alert_radius: Option.getOrUndefined(proximityAlertRadius),
160
204
  }),
161
- Venue: ({ latitude, longitude, title, address, foursquareId, foursquareType, googlePlaceId, googlePlaceType }): ParamsContentVenue => ({
205
+ Venue: ({ latitude, longitude, title, address, foursquareId, foursquareType, googlePlaceId, googlePlaceType }) => ({
162
206
  latitude,
163
207
  longitude,
164
208
  title,
@@ -168,67 +212,72 @@ const paramsContent: {
168
212
  google_place_id: Option.getOrUndefined(googlePlaceId),
169
213
  google_place_type: Option.getOrUndefined(googlePlaceType),
170
214
  }),
171
- Contact: ({ phoneNumber, firstName, lastName, vcard }): ParamsContentContact => ({
215
+ Contact: ({ phoneNumber, firstName, lastName, vcard }) => ({
172
216
  phone_number: phoneNumber,
173
217
  first_name: firstName,
174
218
  last_name: Option.getOrUndefined(lastName),
175
219
  vcard: Option.getOrUndefined(vcard),
176
220
  }),
177
- Dice: ({ emoji }): ParamsContentDice => ({
221
+ Dice: ({ emoji }) => ({
178
222
  emoji,
179
223
  }),
180
- Sticker: ({ file, emoji }): ParamsContentSticker => ({
224
+ Sticker: ({ file, emoji }) => ({
181
225
  sticker: file instanceof URL ? file.toString() : file,
182
226
  emoji: Option.getOrUndefined(emoji),
183
227
  }),
184
228
  }),
185
- Match.exhaustive,
186
- ) as any
229
+ )
230
+
231
+ // =============================================================================
232
+ // Parameters (Dialog)
233
+ // =============================================================================
187
234
 
188
235
  type ParamsDialog = PickMethodParams<SendMethod, 'chat_id' | 'message_thread_id' | 'direct_messages_topic_id'>
189
- const paramsDialog: (dialog: Dialog.Dialog) => ParamsDialog = Function.pipe(
190
- Match.type<Dialog.Dialog>(),
236
+
237
+ const paramsDialog: (
238
+ dialog: Dialog.Dialog | Dialog.DialogId,
239
+ ) => ParamsDialog = Match.type<Dialog.Dialog | Dialog.DialogId>().pipe(
191
240
  Match.withReturnType<ParamsDialog>(),
241
+ Match.when(Match.number, dialogId => ({
242
+ chat_id: dialogId,
243
+ })),
192
244
  Match.tagsExhaustive({
193
- UserId: ({ dialogId }) => ({ chat_id: dialogId }),
194
- GroupId: ({ dialogId }) => ({ chat_id: dialogId }),
195
- ChannelId: ({ dialogId }) => ({ chat_id: dialogId }),
196
- SupergroupId: ({ dialogId }) => ({ chat_id: dialogId }),
197
- PublicChannel: ({ username }) => ({ chat_id: username }),
198
- PublicSupergroup: ({ username }) => ({ chat_id: username }),
199
- ForumTopic: ({ forum, topicId }) => ({
200
- chat_id: Match.value(forum).pipe(
201
- Match.tagsExhaustive({
202
- SupergroupId: ({ dialogId }) => dialogId,
203
- PublicSupergroup: ({ username }) => username,
204
- }),
205
- ),
206
- message_thread_id: topicId,
245
+ User: user => ({
246
+ chat_id: user.dialogId(),
247
+ }),
248
+ Group: group => ({
249
+ chat_id: group.dialogId(),
250
+ }),
251
+ Supergroup: supergroup => ({
252
+ chat_id: supergroup.dialogId(),
207
253
  }),
208
- ChannelDm: ({ channel, userId }) => ({
209
- chat_id: Match.value(channel).pipe(
210
- Match.tagsExhaustive({
211
- ChannelId: ({ dialogId }) => dialogId,
212
- PublicChannel: ({ username }) => username,
213
- }),
214
- ),
215
- direct_messages_topic_id: userId,
254
+ Channel: channel => ({
255
+ chat_id: channel.dialogId(),
256
+ }),
257
+ PrivateTopic: topic => ({
258
+ chat_id: topic.user.dialogId(),
259
+ message_thread_id: topic.topicId,
260
+ }),
261
+ ForumTopic: topic => ({
262
+ chat_id: topic.supergroup.dialogId(),
263
+ message_thread_id: topic.topicId,
264
+ }),
265
+ ChannelDm: dm => ({
266
+ chat_id: dm.channel.dialogId(),
267
+ direct_messages_topic_id: dm.topicId,
216
268
  }),
217
269
  }),
218
270
  )
219
271
 
220
- type ParamsOptions = PickMethodParams<SendMethod, 'disable_notification' | 'protect_content' | 'allow_paid_broadcast'>
221
- const paramsOptions = (options: Send.Options): ParamsOptions => {
222
- return {
223
- disable_notification: options.disableNotification || undefined,
224
- protect_content: options.protectContent || undefined,
225
- allow_paid_broadcast: options.allowPaidBroadcast || undefined,
226
- }
227
- }
272
+ // =============================================================================
273
+ // Parameters (Reply Markup)
274
+ // =============================================================================
228
275
 
229
276
  type ParamsMarkup = PickMethodParams<SendMethod, 'reply_markup'>
230
- const paramsMarkup: (markup: Markup.Markup) => ParamsMarkup = Function.pipe(
231
- Match.type<Markup.Markup>(),
277
+
278
+ const paramsMarkup: (
279
+ markup: Markup.Markup,
280
+ ) => ParamsMarkup = Match.type<Markup.Markup>().pipe(
232
281
  Match.withReturnType<ParamsMarkup>(),
233
282
  Match.tagsExhaustive({
234
283
  InlineKeyboard: markup => ({
@@ -262,57 +311,37 @@ const paramsMarkup: (markup: Markup.Markup) => ParamsMarkup = Function.pipe(
262
311
  }),
263
312
  )
264
313
 
265
- type PickMethodParams<
266
- TMethod extends keyof BotApi.MethodParams,
267
- TPick extends keyof BotApi.MethodParams[TMethod],
268
- > = Pick<BotApi.MethodParams[TMethod], TPick>
314
+ // =============================================================================
315
+ // Parameters (Send Options)
316
+ // =============================================================================
269
317
 
270
- type SendMethod = Extract<
271
- keyof BotApi.MethodParams,
272
- | 'sendMessage'
273
- | 'sendPhoto'
274
- | 'sendAudio'
275
- | 'sendDocument'
276
- | 'sendVideo'
277
- | 'sendAnimation'
278
- | 'sendVoice'
279
- | 'sendVideoNote'
280
- | 'sendPaidMedia'
281
- | 'sendLocation'
282
- | 'sendVenue'
283
- | 'sendContact'
284
- | 'sendDice'
285
- | 'sendSticker'
286
- | 'sendInvoice'
287
- >
318
+ type ParamsOptions = PickMethodParams<SendMethod, 'disable_notification' | 'protect_content' | 'allow_paid_broadcast'>
319
+
320
+ const paramsOptions = (options: Send.Options): ParamsOptions => {
321
+ return {
322
+ disable_notification: options.disableNotification || undefined,
323
+ protect_content: options.protectContent || undefined,
324
+ allow_paid_broadcast: options.allowPaidBroadcast || undefined,
325
+ }
326
+ }
327
+
328
+ // =============================================================================
329
+ // Send Methods
330
+ // =============================================================================
288
331
 
289
332
  export const sendMessage = Effect.fnUntraced(function* (params: {
290
333
  content: Content.Content
291
- dialog: Dialog_.Dialog
292
- options?: Send.Options
334
+ dialog: Dialog.Dialog | Dialog.DialogId
293
335
  markup?: Markup.Markup
336
+ options?: Send.Options
294
337
  }) {
295
- const api = yield* BotApi.BotApi
296
- const common = {
297
- ...paramsDialog(params.dialog),
298
- ...(params.options ? paramsOptions(params.options) : {}),
299
- ...(params.markup ? paramsMarkup(params.markup) : {}),
300
- }
301
- return yield* Match.value(params.content).pipe(
302
- Match.tagsExhaustive({
303
- Text: content => api.sendMessage({ ...common, ...paramsContent(content) }),
304
- Photo: content => api.sendPhoto({ ...common, ...paramsContent(content) }),
305
- Audio: content => api.sendAudio({ ...common, ...paramsContent(content) }),
306
- Document: content => api.sendDocument({ ...common, ...paramsContent(content) }),
307
- Video: content => api.sendVideo({ ...common, ...paramsContent(content) }),
308
- Animation: content => api.sendAnimation({ ...common, ...paramsContent(content) }),
309
- Voice: content => api.sendVoice({ ...common, ...paramsContent(content) }),
310
- VideoNote: content => api.sendVideoNote({ ...common, ...paramsContent(content) }),
311
- Location: content => api.sendLocation({ ...common, ...paramsContent(content) }),
312
- Venue: content => api.sendVenue({ ...common, ...paramsContent(content) }),
313
- Contact: content => api.sendContact({ ...common, ...paramsContent(content) }),
314
- Dice: content => api.sendDice({ ...common, ...paramsContent(content) }),
315
- Sticker: content => api.sendSticker({ ...common, ...paramsContent(content) }),
316
- }),
338
+ return yield* BotApi.callMethod(
339
+ methodByContent[params.content._tag],
340
+ {
341
+ ...paramsContent(params.content),
342
+ ...paramsDialog(params.dialog),
343
+ ...(params.options ? paramsOptions(params.options) : {}),
344
+ ...(params.markup ? paramsMarkup(params.markup) : {}),
345
+ },
317
346
  )
318
347
  })