@effect-ak/tg-bot-client 0.4.1 → 0.5.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/dist/index.d.ts +57 -50
- package/dist/index.js +317 -233
- package/dist/index.mjs +312 -227
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,73 +1,54 @@
|
|
|
1
|
-
// src/bot/
|
|
1
|
+
// src/bot/internal/launch.ts
|
|
2
2
|
import * as Micro6 from "effect/Micro";
|
|
3
|
-
import * as
|
|
3
|
+
import * as Context6 from "effect/Context";
|
|
4
4
|
|
|
5
|
-
// src/
|
|
5
|
+
// src/client/config.ts
|
|
6
6
|
import * as Context from "effect/Context";
|
|
7
|
-
var BotMessageHandler = class extends Context.Tag("BotMessageHandler")() {
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
// src/bot/update-poller/_service.ts
|
|
11
|
-
import * as Micro4 from "effect/Micro";
|
|
12
|
-
import * as Context3 from "effect/Context";
|
|
13
7
|
|
|
14
|
-
// src/
|
|
15
|
-
|
|
8
|
+
// src/const.ts
|
|
9
|
+
var defaultBaseUrl = "https://api.telegram.org";
|
|
10
|
+
var MESSAGE_EFFECTS = {
|
|
11
|
+
"\u{1F525}": "5104841245755180586",
|
|
12
|
+
"\u{1F44D}": "5107584321108051014",
|
|
13
|
+
"\u{1F44E}": "5104858069142078462",
|
|
14
|
+
"\u2764\uFE0F": "5159385139981059251",
|
|
15
|
+
"\u{1F389}": "5046509860389126442",
|
|
16
|
+
"\u{1F4A9}": "5046589136895476101"
|
|
17
|
+
};
|
|
18
|
+
var messageEffectIdCodes = Object.keys(MESSAGE_EFFECTS);
|
|
19
|
+
var isMessageEffect = (input) => {
|
|
20
|
+
return typeof input === "string" && input in MESSAGE_EFFECTS;
|
|
21
|
+
};
|
|
16
22
|
|
|
17
|
-
// src/
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
let on_error = input.on_error;
|
|
24
|
-
if (limit < 10 || limit > 100) {
|
|
25
|
-
console.warn("Wrong limit, must be in [10..100], using 10 instead");
|
|
26
|
-
limit = 10;
|
|
27
|
-
}
|
|
28
|
-
if (timeout < 2 || timeout > 10) {
|
|
29
|
-
console.warn("Wrong timeout, must be in [2..10], using 2 instead");
|
|
30
|
-
limit = 10;
|
|
31
|
-
}
|
|
32
|
-
if (max_empty_responses && max_empty_responses < 2) {
|
|
33
|
-
console.warn("Wrong max_empty_responses, must be in [2..infinity], using infinity");
|
|
34
|
-
max_empty_responses = void 0;
|
|
35
|
-
}
|
|
36
|
-
if (max_empty_responses && max_empty_responses < 2) {
|
|
37
|
-
console.warn("Wrong max_empty_responses, must be in [2..infinity], using infinity");
|
|
38
|
-
max_empty_responses = void 0;
|
|
39
|
-
}
|
|
40
|
-
if (!log_level) {
|
|
41
|
-
log_level = "info";
|
|
42
|
-
}
|
|
43
|
-
if (!on_error) {
|
|
44
|
-
on_error = "stop";
|
|
45
|
-
}
|
|
46
|
-
const config = {
|
|
47
|
-
limit,
|
|
48
|
-
timeout,
|
|
49
|
-
max_empty_responses,
|
|
50
|
-
log_level,
|
|
51
|
-
on_error
|
|
52
|
-
};
|
|
53
|
-
console.log("bot configuration", config);
|
|
54
|
-
return config;
|
|
23
|
+
// src/client/config.ts
|
|
24
|
+
var makeTgBotClientConfig = (input) => TgBotClientConfig.of({
|
|
25
|
+
...input,
|
|
26
|
+
base_url: input.base_url ?? defaultBaseUrl
|
|
27
|
+
});
|
|
28
|
+
var TgBotClientConfig = class extends Context.Tag("TgBotClientConfig")() {
|
|
55
29
|
};
|
|
56
30
|
|
|
57
|
-
// src/bot/
|
|
58
|
-
import * as Micro2 from "effect/Micro";
|
|
31
|
+
// src/bot/internal/types.ts
|
|
59
32
|
import * as Data from "effect/Data";
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
import { TaggedClass } from "effect/Data";
|
|
63
|
-
var BotResponse = class _BotResponse extends TaggedClass("BotResponse") {
|
|
33
|
+
import * as Context2 from "effect/Context";
|
|
34
|
+
var BotResponse = class _BotResponse extends Data.TaggedClass("BotResponse") {
|
|
64
35
|
static make(result) {
|
|
65
36
|
return new _BotResponse({ response: result });
|
|
66
37
|
}
|
|
67
38
|
static ignore = new _BotResponse({});
|
|
68
39
|
};
|
|
40
|
+
var BotUpdateHandlersTag = class extends Context2.Tag("BotUpdateHandlers")() {
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// src/bot/service/run.ts
|
|
44
|
+
import * as Micro4 from "effect/Micro";
|
|
45
|
+
import * as Context5 from "effect/Context";
|
|
69
46
|
|
|
70
|
-
// src/bot/
|
|
47
|
+
// src/bot/internal/handle-update.ts
|
|
48
|
+
import * as Micro2 from "effect/Micro";
|
|
49
|
+
import * as Data3 from "effect/Data";
|
|
50
|
+
|
|
51
|
+
// src/bot/internal/utils.ts
|
|
71
52
|
var extractUpdate = (input) => {
|
|
72
53
|
for (const [field, value] of Object.entries(input)) {
|
|
73
54
|
if (field == "update_id") {
|
|
@@ -96,32 +77,6 @@ var TgBotClientError = class _TgBotClientError extends TaggedError("TgBotClientE
|
|
|
96
77
|
});
|
|
97
78
|
};
|
|
98
79
|
|
|
99
|
-
// src/client/config.ts
|
|
100
|
-
import * as Context2 from "effect/Context";
|
|
101
|
-
|
|
102
|
-
// src/const.ts
|
|
103
|
-
var defaultBaseUrl = "https://api.telegram.org";
|
|
104
|
-
var MESSAGE_EFFECTS = {
|
|
105
|
-
"\u{1F525}": "5104841245755180586",
|
|
106
|
-
"\u{1F44D}": "5107584321108051014",
|
|
107
|
-
"\u{1F44E}": "5104858069142078462",
|
|
108
|
-
"\u2764\uFE0F": "5159385139981059251",
|
|
109
|
-
"\u{1F389}": "5046509860389126442",
|
|
110
|
-
"\u{1F4A9}": "5046589136895476101"
|
|
111
|
-
};
|
|
112
|
-
var messageEffectIdCodes = Object.keys(MESSAGE_EFFECTS);
|
|
113
|
-
var isMessageEffect = (input) => {
|
|
114
|
-
return typeof input === "string" && input in MESSAGE_EFFECTS;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
// src/client/config.ts
|
|
118
|
-
var makeTgBotClientConfig = (input) => TgBotClientConfig.of({
|
|
119
|
-
...input,
|
|
120
|
-
base_url: input.base_url ?? defaultBaseUrl
|
|
121
|
-
});
|
|
122
|
-
var TgBotClientConfig = class extends Context2.Tag("TgBotClientConfig")() {
|
|
123
|
-
};
|
|
124
|
-
|
|
125
80
|
// src/client/guards.ts
|
|
126
81
|
var isFileContent = (input) => typeof input == "object" && input != null && ("file_content" in input && input.file_content instanceof Uint8Array) && ("file_name" in input && typeof input.file_name == "string");
|
|
127
82
|
var isTgBotApiResponse = (input) => typeof input == "object" && input != null && ("ok" in input && typeof input.ok == "boolean");
|
|
@@ -183,55 +138,129 @@ var execute = (method, input) => Micro.gen(function* () {
|
|
|
183
138
|
return response.result;
|
|
184
139
|
});
|
|
185
140
|
|
|
186
|
-
// src/bot/
|
|
187
|
-
|
|
141
|
+
// src/bot/internal/poll-settings.ts
|
|
142
|
+
import * as Context3 from "effect/Context";
|
|
143
|
+
import * as Data2 from "effect/Data";
|
|
144
|
+
var BotPollSettings = class _BotPollSettings extends Data2.Class {
|
|
145
|
+
static make(input) {
|
|
146
|
+
let batch_size = input.batch_size ?? 10;
|
|
147
|
+
let poll_timeout = input.poll_timeout ?? 10;
|
|
148
|
+
let max_empty_responses = input.max_empty_responses;
|
|
149
|
+
let log_level = input.log_level ?? "info";
|
|
150
|
+
let on_error = input.on_error;
|
|
151
|
+
if (batch_size < 10 || batch_size > 100) {
|
|
152
|
+
console.warn("Wrong batch_size, must be in [10..100], using 10 instead");
|
|
153
|
+
batch_size = 10;
|
|
154
|
+
}
|
|
155
|
+
if (poll_timeout < 2 || poll_timeout > 10) {
|
|
156
|
+
console.warn("Wrong poll_timeout, must be in [2..10], using 2 instead");
|
|
157
|
+
poll_timeout = 10;
|
|
158
|
+
}
|
|
159
|
+
if (max_empty_responses && max_empty_responses < 2) {
|
|
160
|
+
console.warn("Wrong max_empty_responses, must be in [2..infinity], using infinity");
|
|
161
|
+
max_empty_responses = void 0;
|
|
162
|
+
}
|
|
163
|
+
if (!log_level) {
|
|
164
|
+
log_level = "info";
|
|
165
|
+
}
|
|
166
|
+
if (!on_error) {
|
|
167
|
+
on_error = "stop";
|
|
168
|
+
}
|
|
169
|
+
const config = new _BotPollSettings({
|
|
170
|
+
batch_size,
|
|
171
|
+
poll_timeout,
|
|
172
|
+
max_empty_responses,
|
|
173
|
+
log_level,
|
|
174
|
+
on_error
|
|
175
|
+
});
|
|
176
|
+
console.log("bot poll settings", config);
|
|
177
|
+
return config;
|
|
178
|
+
}
|
|
188
179
|
};
|
|
189
|
-
var
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
180
|
+
var BotPollSettingsTag = class extends Context3.Reference()(
|
|
181
|
+
"BotSettings",
|
|
182
|
+
{
|
|
183
|
+
defaultValue() {
|
|
184
|
+
return BotPollSettings.make({});
|
|
185
|
+
}
|
|
193
186
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
187
|
+
) {
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// src/bot/internal/handle-update.ts
|
|
191
|
+
var BatchUpdateResult = class extends Data3.Class {
|
|
192
|
+
};
|
|
193
|
+
var handleUpdates = (updates) => Micro2.gen(function* () {
|
|
194
|
+
const pollSettings = yield* Micro2.service(BotPollSettingsTag);
|
|
195
|
+
const updateHandler = yield* Micro2.service(BotUpdateHandlersTag);
|
|
196
|
+
if (updateHandler.type == "single") {
|
|
197
|
+
return yield* handleOneByOne(updates, updateHandler, pollSettings);
|
|
198
|
+
} else {
|
|
199
|
+
return yield* handleEntireBatch(updates, updateHandler, pollSettings);
|
|
202
200
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
),
|
|
217
|
-
{
|
|
218
|
-
concurrency: 10
|
|
201
|
+
});
|
|
202
|
+
var handleEntireBatch = (updates, handlers, pollSettings) => Micro2.try({
|
|
203
|
+
try: () => handlers.on_batch(updates),
|
|
204
|
+
catch: (_) => _
|
|
205
|
+
}).pipe(
|
|
206
|
+
Micro2.andThen((result) => {
|
|
207
|
+
if (result instanceof Promise) {
|
|
208
|
+
return Micro2.tryPromise({
|
|
209
|
+
try: () => result,
|
|
210
|
+
catch: (_) => _
|
|
211
|
+
});
|
|
212
|
+
} else {
|
|
213
|
+
return Micro2.succeed(result);
|
|
219
214
|
}
|
|
220
|
-
)
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
215
|
+
}),
|
|
216
|
+
Micro2.andThen(
|
|
217
|
+
(doNext) => new BatchUpdateResult({
|
|
218
|
+
hasErrors: !doNext,
|
|
219
|
+
updates
|
|
220
|
+
})
|
|
221
|
+
),
|
|
222
|
+
Micro2.catchAll((error) => {
|
|
223
|
+
console.log("handle batch error", {
|
|
224
|
+
errorMessage: error instanceof Error ? error.message : void 0,
|
|
225
|
+
updates: updates.map((_) => Object.keys(_).at(1))
|
|
227
226
|
});
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
227
|
+
return Micro2.succeed(
|
|
228
|
+
new BatchUpdateResult({
|
|
229
|
+
hasErrors: true,
|
|
230
|
+
updates
|
|
231
|
+
})
|
|
232
|
+
);
|
|
233
|
+
})
|
|
234
|
+
);
|
|
235
|
+
var HandleUpdateError = class extends Data3.TaggedError("HandleUpdateError") {
|
|
236
|
+
};
|
|
237
|
+
var handleOneByOne = (updates, handlers, pollSettings) => Micro2.forEach(
|
|
238
|
+
updates,
|
|
239
|
+
(update) => handleOneUpdate(update, handlers).pipe(
|
|
240
|
+
Micro2.catchAll((error) => {
|
|
241
|
+
console.log("update handle error", {
|
|
242
|
+
updateId: update.update_id,
|
|
243
|
+
updateKey: Object.keys(update).at(1),
|
|
244
|
+
name: error._tag
|
|
245
|
+
});
|
|
246
|
+
return Micro2.succeed(error);
|
|
247
|
+
})
|
|
248
|
+
),
|
|
249
|
+
{
|
|
250
|
+
concurrency: 10
|
|
231
251
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
252
|
+
).pipe(
|
|
253
|
+
Micro2.andThen((batchResult) => {
|
|
254
|
+
if (pollSettings.log_level == "debug") {
|
|
255
|
+
console.debug("handle batch result", batchResult);
|
|
256
|
+
}
|
|
257
|
+
return new BatchUpdateResult({
|
|
258
|
+
hasErrors: !batchResult.every((error) => error == null),
|
|
259
|
+
updates
|
|
260
|
+
});
|
|
261
|
+
})
|
|
262
|
+
);
|
|
263
|
+
var handleOneUpdate = (updateObject, handlers) => Micro2.gen(function* () {
|
|
235
264
|
const update = extractUpdate(updateObject);
|
|
236
265
|
if (!update) {
|
|
237
266
|
return yield* Micro2.fail(
|
|
@@ -241,8 +270,8 @@ var handleUpdate = (updateObject, settings, handlers) => Micro2.gen(function* ()
|
|
|
241
270
|
})
|
|
242
271
|
);
|
|
243
272
|
}
|
|
244
|
-
const
|
|
245
|
-
if (!
|
|
273
|
+
const updateHandler = handlers[`on_${update.type}`];
|
|
274
|
+
if (!updateHandler) {
|
|
246
275
|
return yield* Micro2.fail(
|
|
247
276
|
new HandleUpdateError({
|
|
248
277
|
name: "HandlerNotDefined",
|
|
@@ -259,7 +288,7 @@ var handleUpdate = (updateObject, settings, handlers) => Micro2.gen(function* ()
|
|
|
259
288
|
}
|
|
260
289
|
let handleUpdateError;
|
|
261
290
|
const handleResult = yield* Micro2.try({
|
|
262
|
-
try: () =>
|
|
291
|
+
try: () => updateHandler(update),
|
|
263
292
|
catch: (error) => new HandleUpdateError({
|
|
264
293
|
name: "BotHandlerError",
|
|
265
294
|
update: updateObject,
|
|
@@ -281,6 +310,11 @@ var handleUpdate = (updateObject, settings, handlers) => Micro2.gen(function* ()
|
|
|
281
310
|
}),
|
|
282
311
|
Micro2.catchAll((error) => {
|
|
283
312
|
handleUpdateError = error;
|
|
313
|
+
console.log("error", {
|
|
314
|
+
updateId: updateObject.update_id,
|
|
315
|
+
updateKey: Object.keys(update).at(1),
|
|
316
|
+
name: error._tag
|
|
317
|
+
});
|
|
284
318
|
return Micro2.succeed(
|
|
285
319
|
BotResponse.make({
|
|
286
320
|
type: "message",
|
|
@@ -295,7 +329,8 @@ var handleUpdate = (updateObject, settings, handlers) => Micro2.gen(function* ()
|
|
|
295
329
|
);
|
|
296
330
|
})
|
|
297
331
|
);
|
|
298
|
-
|
|
332
|
+
const pollSettings = yield* Micro2.service(BotPollSettingsTag);
|
|
333
|
+
if (!handleResult && pollSettings.log_level == "debug") {
|
|
299
334
|
console.log(`Bot response is undefined for update with ID #${updateObject.update_id}.`);
|
|
300
335
|
return;
|
|
301
336
|
}
|
|
@@ -305,87 +340,144 @@ var handleUpdate = (updateObject, settings, handlers) => Micro2.gen(function* ()
|
|
|
305
340
|
...handleResult.response,
|
|
306
341
|
chat_id: update.chat.id
|
|
307
342
|
});
|
|
308
|
-
if (
|
|
343
|
+
if (pollSettings.log_level == "debug" && "text") {
|
|
309
344
|
console.debug("bot response", response);
|
|
310
345
|
}
|
|
311
346
|
}
|
|
312
347
|
return handleUpdateError;
|
|
313
348
|
});
|
|
314
349
|
|
|
315
|
-
// src/bot/
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
console.
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
;
|
|
345
|
-
if (lastUpdateId) {
|
|
346
|
-
state.lastUpdateId = lastUpdateId + 1;
|
|
347
|
-
}
|
|
348
|
-
return true;
|
|
349
|
-
}
|
|
350
|
-
})
|
|
351
|
-
);
|
|
350
|
+
// src/bot/service/fetch-updates.ts
|
|
351
|
+
import * as Micro3 from "effect/Micro";
|
|
352
|
+
import * as Data4 from "effect/Data";
|
|
353
|
+
import * as Context4 from "effect/Context";
|
|
354
|
+
var BotFetchUpdatesService = class extends Context4.Reference()(
|
|
355
|
+
"BotFetchUpdatesService",
|
|
356
|
+
{
|
|
357
|
+
defaultValue: () => {
|
|
358
|
+
const state = {
|
|
359
|
+
lastUpdateId: void 0,
|
|
360
|
+
emptyResponses: 0
|
|
361
|
+
};
|
|
362
|
+
const fetchUpdates = _fetchUpdates(state).pipe(
|
|
363
|
+
Micro3.tap((updates) => {
|
|
364
|
+
const id = updates.map((_) => _.update_id).sort().at(-1);
|
|
365
|
+
console.log("updating last update id", id);
|
|
366
|
+
state.lastUpdateId = id ? id + 1 : void 0;
|
|
367
|
+
console.log(state);
|
|
368
|
+
})
|
|
369
|
+
);
|
|
370
|
+
const commit = _commitLastBatch(state);
|
|
371
|
+
return {
|
|
372
|
+
state,
|
|
373
|
+
fetchUpdates,
|
|
374
|
+
commit
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
) {
|
|
352
379
|
};
|
|
353
|
-
|
|
354
|
-
// src/bot/update-poller/_service.ts
|
|
355
|
-
var BotUpdatePollerService = class extends Context3.Tag("BotUpdatePollerService")() {
|
|
380
|
+
var FetchUpdatesError = class extends Data4.TaggedError("FetchUpdatesError") {
|
|
356
381
|
};
|
|
357
|
-
var
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
382
|
+
var _fetchUpdates = (pollState) => Micro3.gen(function* () {
|
|
383
|
+
const pollSettings = yield* Micro3.service(BotPollSettingsTag);
|
|
384
|
+
if (pollSettings.max_empty_responses && pollState.emptyResponses == pollSettings.max_empty_responses) {
|
|
385
|
+
return yield* Micro3.fail(
|
|
386
|
+
new FetchUpdatesError({ name: "TooManyEmptyResponses" })
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
const updateId = pollState.lastUpdateId;
|
|
390
|
+
if (pollSettings.log_level == "debug") {
|
|
391
|
+
console.debug("getting updates", pollState);
|
|
392
|
+
}
|
|
393
|
+
const updates = yield* execute("get_updates", {
|
|
394
|
+
timeout: pollSettings.poll_timeout,
|
|
395
|
+
...updateId ? { offset: updateId } : void 0
|
|
396
|
+
}).pipe(
|
|
397
|
+
Micro3.andThen((_) => _.sort((_2) => _2.update_id))
|
|
398
|
+
);
|
|
399
|
+
if (updates.length) {
|
|
400
|
+
console.debug(`got a batch of updates (${updates.length})`);
|
|
401
|
+
pollState.emptyResponses = 0;
|
|
402
|
+
return updates;
|
|
403
|
+
} else {
|
|
404
|
+
pollState.emptyResponses += 1;
|
|
405
|
+
return [];
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
var _commitLastBatch = (pollState) => Micro3.gen(function* () {
|
|
409
|
+
console.log("commit", { pollState });
|
|
410
|
+
if (pollState.lastUpdateId) {
|
|
411
|
+
return yield* execute("get_updates", {
|
|
412
|
+
offset: pollState.lastUpdateId,
|
|
413
|
+
limit: 0
|
|
367
414
|
}).pipe(
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
415
|
+
Micro3.andThen(
|
|
416
|
+
Micro3.andThen(Micro3.service(BotPollSettingsTag), (pollSettings) => {
|
|
417
|
+
if (pollSettings.log_level == "debug") {
|
|
418
|
+
console.debug("committed offset", pollState);
|
|
419
|
+
}
|
|
372
420
|
})
|
|
373
421
|
)
|
|
374
422
|
);
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
423
|
+
} else {
|
|
424
|
+
return yield* Micro3.fail(new FetchUpdatesError({
|
|
425
|
+
name: "NoUpdatesToCommit"
|
|
426
|
+
}));
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
// src/bot/service/run.ts
|
|
431
|
+
var BotRunService = class extends Context5.Reference()(
|
|
432
|
+
"BotRunService",
|
|
433
|
+
{
|
|
434
|
+
defaultValue: () => {
|
|
435
|
+
console.log("Initiating BotRunService");
|
|
436
|
+
const state = {
|
|
437
|
+
fiber: void 0
|
|
438
|
+
};
|
|
439
|
+
const runBotInBackground = _runBotDaemon(state);
|
|
440
|
+
const getFiber = () => state.fiber;
|
|
441
|
+
return {
|
|
442
|
+
runBotInBackground,
|
|
443
|
+
getFiber
|
|
444
|
+
};
|
|
378
445
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
446
|
+
}
|
|
447
|
+
) {
|
|
448
|
+
};
|
|
449
|
+
var _runBotDaemon = (state) => Micro4.gen(function* () {
|
|
450
|
+
console.log("run bot");
|
|
451
|
+
const fetchService = yield* Micro4.service(BotFetchUpdatesService);
|
|
452
|
+
const startFiber = Micro4.delay(1e3)(
|
|
453
|
+
fetchService.fetchUpdates.pipe(
|
|
454
|
+
Micro4.andThen(
|
|
455
|
+
(updates) => handleUpdates(updates)
|
|
456
|
+
),
|
|
457
|
+
Micro4.tap(
|
|
458
|
+
({ updates }) => updates.length > 0 ? fetchService.commit : Micro4.void
|
|
459
|
+
)
|
|
460
|
+
)
|
|
461
|
+
).pipe(
|
|
462
|
+
Micro4.repeat({
|
|
463
|
+
while: (_) => !_.hasErrors
|
|
464
|
+
}),
|
|
465
|
+
Micro4.forkDaemon,
|
|
466
|
+
Micro4.tap(
|
|
467
|
+
(fiber) => fiber.addObserver((exit) => {
|
|
468
|
+
console.log("bot's fiber has been closed", exit);
|
|
469
|
+
})
|
|
470
|
+
)
|
|
471
|
+
);
|
|
472
|
+
if (state.fiber) {
|
|
473
|
+
console.log("killing previous bot's fiber");
|
|
474
|
+
yield* Micro4.fiberInterrupt(state.fiber);
|
|
475
|
+
}
|
|
476
|
+
state.fiber = yield* startFiber;
|
|
477
|
+
console.log("Fetching bot updates via long polling...");
|
|
386
478
|
});
|
|
387
479
|
|
|
388
|
-
// src/bot/
|
|
480
|
+
// src/bot/internal/client-config.ts
|
|
389
481
|
import * as Micro5 from "effect/Micro";
|
|
390
482
|
var makeClientConfigFrom = (input) => Micro5.gen(function* () {
|
|
391
483
|
if (input.type == "config") {
|
|
@@ -407,35 +499,29 @@ var makeClientConfigFrom = (input) => Micro5.gen(function* () {
|
|
|
407
499
|
return makeTgBotClientConfig(config);
|
|
408
500
|
});
|
|
409
501
|
|
|
410
|
-
// src/bot/
|
|
411
|
-
var
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
reload,
|
|
430
|
-
fiber: poller.getFiber
|
|
431
|
-
};
|
|
432
|
-
})
|
|
433
|
-
};
|
|
502
|
+
// src/bot/internal/launch.ts
|
|
503
|
+
var launchBot = (input) => Micro6.gen(function* () {
|
|
504
|
+
const clientConfig = Context6.make(TgBotClientConfig, yield* makeClientConfigFrom(input));
|
|
505
|
+
const service8 = yield* Micro6.service(BotRunService);
|
|
506
|
+
yield* service8.runBotInBackground.pipe(
|
|
507
|
+
Micro6.provideContext(clientConfig),
|
|
508
|
+
Micro6.provideService(BotUpdateHandlersTag, input.mode),
|
|
509
|
+
Micro6.provideService(BotPollSettingsTag, BotPollSettings.make(input.poll ?? {}))
|
|
510
|
+
);
|
|
511
|
+
const reload = (mode) => service8.runBotInBackground.pipe(
|
|
512
|
+
Micro6.provideService(BotUpdateHandlersTag, mode),
|
|
513
|
+
Micro6.provideContext(clientConfig),
|
|
514
|
+
Micro6.runPromise
|
|
515
|
+
);
|
|
516
|
+
return {
|
|
517
|
+
reload,
|
|
518
|
+
fiber: service8.getFiber
|
|
519
|
+
};
|
|
520
|
+
});
|
|
434
521
|
|
|
435
522
|
// src/bot/run.ts
|
|
436
523
|
import * as Micro7 from "effect/Micro";
|
|
437
|
-
var runTgChatBot = (input) =>
|
|
438
|
-
Micro7.provideService(BotMessageHandler, input),
|
|
524
|
+
var runTgChatBot = (input) => launchBot(input).pipe(
|
|
439
525
|
Micro7.runPromise
|
|
440
526
|
);
|
|
441
527
|
|
|
@@ -444,7 +530,7 @@ import * as Micro10 from "effect/Micro";
|
|
|
444
530
|
|
|
445
531
|
// src/client/file/_service.ts
|
|
446
532
|
import * as Micro9 from "effect/Micro";
|
|
447
|
-
import * as
|
|
533
|
+
import * as Context7 from "effect/Context";
|
|
448
534
|
|
|
449
535
|
// src/client/file/get-file.ts
|
|
450
536
|
import * as Micro8 from "effect/Micro";
|
|
@@ -475,7 +561,7 @@ var getFile = (fileId) => Micro8.gen(function* () {
|
|
|
475
561
|
});
|
|
476
562
|
|
|
477
563
|
// src/client/file/_service.ts
|
|
478
|
-
var ClientFileService = class extends
|
|
564
|
+
var ClientFileService = class extends Context7.Tag("ClientFileService")() {
|
|
479
565
|
};
|
|
480
566
|
var ClientFileServiceDefault = Micro9.gen(function* () {
|
|
481
567
|
return {
|
|
@@ -506,14 +592,13 @@ var makeTgBotClient = (input) => {
|
|
|
506
592
|
return client;
|
|
507
593
|
};
|
|
508
594
|
export {
|
|
509
|
-
BotFactoryService,
|
|
510
|
-
BotFactoryServiceDefault,
|
|
511
595
|
BotResponse,
|
|
512
|
-
|
|
513
|
-
|
|
596
|
+
BotRunService,
|
|
597
|
+
BotUpdateHandlersTag,
|
|
514
598
|
MESSAGE_EFFECTS,
|
|
515
599
|
defaultBaseUrl,
|
|
516
600
|
isMessageEffect,
|
|
601
|
+
launchBot,
|
|
517
602
|
makeTgBotClient,
|
|
518
603
|
messageEffectIdCodes,
|
|
519
604
|
runTgChatBot
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect-ak/tg-bot-client",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"homepage": "https://effect-ak.github.io/telegram-bot-
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"homepage": "https://effect-ak.github.io/telegram-bot-playground/",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Aleksandr Kondaurov",
|
|
7
7
|
"email": "kondaurov.dev@gmail.com"
|