@effect-ak/tg-bot-client 0.4.2 → 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 +311 -237
- package/dist/index.mjs +306 -231
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -30,90 +30,70 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
|
-
BotFactoryService: () => BotFactoryService,
|
|
34
|
-
BotFactoryServiceDefault: () => BotFactoryServiceDefault,
|
|
35
33
|
BotResponse: () => BotResponse,
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
BotRunService: () => BotRunService,
|
|
35
|
+
BotUpdateHandlersTag: () => BotUpdateHandlersTag,
|
|
38
36
|
MESSAGE_EFFECTS: () => MESSAGE_EFFECTS,
|
|
39
37
|
defaultBaseUrl: () => defaultBaseUrl,
|
|
40
38
|
isMessageEffect: () => isMessageEffect,
|
|
39
|
+
launchBot: () => launchBot,
|
|
41
40
|
makeTgBotClient: () => makeTgBotClient,
|
|
42
41
|
messageEffectIdCodes: () => messageEffectIdCodes,
|
|
43
42
|
runTgChatBot: () => runTgChatBot
|
|
44
43
|
});
|
|
45
44
|
module.exports = __toCommonJS(src_exports);
|
|
46
45
|
|
|
47
|
-
// src/bot/
|
|
46
|
+
// src/bot/internal/launch.ts
|
|
48
47
|
var Micro6 = __toESM(require("effect/Micro"));
|
|
49
|
-
var
|
|
48
|
+
var Context6 = __toESM(require("effect/Context"));
|
|
50
49
|
|
|
51
|
-
// src/
|
|
50
|
+
// src/client/config.ts
|
|
52
51
|
var Context = __toESM(require("effect/Context"));
|
|
53
|
-
var BotMessageHandler = class extends Context.Tag("BotMessageHandler")() {
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
// src/bot/update-poller/_service.ts
|
|
57
|
-
var Micro4 = __toESM(require("effect/Micro"));
|
|
58
|
-
var Context3 = __toESM(require("effect/Context"));
|
|
59
52
|
|
|
60
|
-
// src/
|
|
61
|
-
var
|
|
53
|
+
// src/const.ts
|
|
54
|
+
var defaultBaseUrl = "https://api.telegram.org";
|
|
55
|
+
var MESSAGE_EFFECTS = {
|
|
56
|
+
"\u{1F525}": "5104841245755180586",
|
|
57
|
+
"\u{1F44D}": "5107584321108051014",
|
|
58
|
+
"\u{1F44E}": "5104858069142078462",
|
|
59
|
+
"\u2764\uFE0F": "5159385139981059251",
|
|
60
|
+
"\u{1F389}": "5046509860389126442",
|
|
61
|
+
"\u{1F4A9}": "5046589136895476101"
|
|
62
|
+
};
|
|
63
|
+
var messageEffectIdCodes = Object.keys(MESSAGE_EFFECTS);
|
|
64
|
+
var isMessageEffect = (input) => {
|
|
65
|
+
return typeof input === "string" && input in MESSAGE_EFFECTS;
|
|
66
|
+
};
|
|
62
67
|
|
|
63
|
-
// src/
|
|
64
|
-
var
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
let on_error = input.on_error;
|
|
70
|
-
if (limit < 10 || limit > 100) {
|
|
71
|
-
console.warn("Wrong limit, must be in [10..100], using 10 instead");
|
|
72
|
-
limit = 10;
|
|
73
|
-
}
|
|
74
|
-
if (timeout < 2 || timeout > 10) {
|
|
75
|
-
console.warn("Wrong timeout, must be in [2..10], using 2 instead");
|
|
76
|
-
limit = 10;
|
|
77
|
-
}
|
|
78
|
-
if (max_empty_responses && max_empty_responses < 2) {
|
|
79
|
-
console.warn("Wrong max_empty_responses, must be in [2..infinity], using infinity");
|
|
80
|
-
max_empty_responses = void 0;
|
|
81
|
-
}
|
|
82
|
-
if (max_empty_responses && max_empty_responses < 2) {
|
|
83
|
-
console.warn("Wrong max_empty_responses, must be in [2..infinity], using infinity");
|
|
84
|
-
max_empty_responses = void 0;
|
|
85
|
-
}
|
|
86
|
-
if (!log_level) {
|
|
87
|
-
log_level = "info";
|
|
88
|
-
}
|
|
89
|
-
if (!on_error) {
|
|
90
|
-
on_error = "stop";
|
|
91
|
-
}
|
|
92
|
-
const config = {
|
|
93
|
-
limit,
|
|
94
|
-
timeout,
|
|
95
|
-
max_empty_responses,
|
|
96
|
-
log_level,
|
|
97
|
-
on_error
|
|
98
|
-
};
|
|
99
|
-
console.log("bot configuration", config);
|
|
100
|
-
return config;
|
|
68
|
+
// src/client/config.ts
|
|
69
|
+
var makeTgBotClientConfig = (input) => TgBotClientConfig.of({
|
|
70
|
+
...input,
|
|
71
|
+
base_url: input.base_url ?? defaultBaseUrl
|
|
72
|
+
});
|
|
73
|
+
var TgBotClientConfig = class extends Context.Tag("TgBotClientConfig")() {
|
|
101
74
|
};
|
|
102
75
|
|
|
103
|
-
// src/bot/
|
|
104
|
-
var Micro2 = __toESM(require("effect/Micro"));
|
|
76
|
+
// src/bot/internal/types.ts
|
|
105
77
|
var Data = __toESM(require("effect/Data"));
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
var import_Data = require("effect/Data");
|
|
109
|
-
var BotResponse = class _BotResponse extends (0, import_Data.TaggedClass)("BotResponse") {
|
|
78
|
+
var Context2 = __toESM(require("effect/Context"));
|
|
79
|
+
var BotResponse = class _BotResponse extends Data.TaggedClass("BotResponse") {
|
|
110
80
|
static make(result) {
|
|
111
81
|
return new _BotResponse({ response: result });
|
|
112
82
|
}
|
|
113
83
|
static ignore = new _BotResponse({});
|
|
114
84
|
};
|
|
85
|
+
var BotUpdateHandlersTag = class extends Context2.Tag("BotUpdateHandlers")() {
|
|
86
|
+
};
|
|
115
87
|
|
|
116
|
-
// src/bot/
|
|
88
|
+
// src/bot/service/run.ts
|
|
89
|
+
var Micro4 = __toESM(require("effect/Micro"));
|
|
90
|
+
var Context5 = __toESM(require("effect/Context"));
|
|
91
|
+
|
|
92
|
+
// src/bot/internal/handle-update.ts
|
|
93
|
+
var Micro2 = __toESM(require("effect/Micro"));
|
|
94
|
+
var Data3 = __toESM(require("effect/Data"));
|
|
95
|
+
|
|
96
|
+
// src/bot/internal/utils.ts
|
|
117
97
|
var extractUpdate = (input) => {
|
|
118
98
|
for (const [field, value] of Object.entries(input)) {
|
|
119
99
|
if (field == "update_id") {
|
|
@@ -132,8 +112,8 @@ var Micro = __toESM(require("effect/Micro"));
|
|
|
132
112
|
var String = __toESM(require("effect/String"));
|
|
133
113
|
|
|
134
114
|
// src/client/errors.ts
|
|
135
|
-
var
|
|
136
|
-
var TgBotClientError = class _TgBotClientError extends (0,
|
|
115
|
+
var import_Data = require("effect/Data");
|
|
116
|
+
var TgBotClientError = class _TgBotClientError extends (0, import_Data.TaggedError)("TgBotClientError") {
|
|
137
117
|
static missingSuccess = new _TgBotClientError({
|
|
138
118
|
reason: {
|
|
139
119
|
type: "ClientInternalError",
|
|
@@ -142,32 +122,6 @@ var TgBotClientError = class _TgBotClientError extends (0, import_Data2.TaggedEr
|
|
|
142
122
|
});
|
|
143
123
|
};
|
|
144
124
|
|
|
145
|
-
// src/client/config.ts
|
|
146
|
-
var Context2 = __toESM(require("effect/Context"));
|
|
147
|
-
|
|
148
|
-
// src/const.ts
|
|
149
|
-
var defaultBaseUrl = "https://api.telegram.org";
|
|
150
|
-
var MESSAGE_EFFECTS = {
|
|
151
|
-
"\u{1F525}": "5104841245755180586",
|
|
152
|
-
"\u{1F44D}": "5107584321108051014",
|
|
153
|
-
"\u{1F44E}": "5104858069142078462",
|
|
154
|
-
"\u2764\uFE0F": "5159385139981059251",
|
|
155
|
-
"\u{1F389}": "5046509860389126442",
|
|
156
|
-
"\u{1F4A9}": "5046589136895476101"
|
|
157
|
-
};
|
|
158
|
-
var messageEffectIdCodes = Object.keys(MESSAGE_EFFECTS);
|
|
159
|
-
var isMessageEffect = (input) => {
|
|
160
|
-
return typeof input === "string" && input in MESSAGE_EFFECTS;
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
// src/client/config.ts
|
|
164
|
-
var makeTgBotClientConfig = (input) => TgBotClientConfig.of({
|
|
165
|
-
...input,
|
|
166
|
-
base_url: input.base_url ?? defaultBaseUrl
|
|
167
|
-
});
|
|
168
|
-
var TgBotClientConfig = class extends Context2.Tag("TgBotClientConfig")() {
|
|
169
|
-
};
|
|
170
|
-
|
|
171
125
|
// src/client/guards.ts
|
|
172
126
|
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");
|
|
173
127
|
var isTgBotApiResponse = (input) => typeof input == "object" && input != null && ("ok" in input && typeof input.ok == "boolean");
|
|
@@ -229,60 +183,129 @@ var execute = (method, input) => Micro.gen(function* () {
|
|
|
229
183
|
return response.result;
|
|
230
184
|
});
|
|
231
185
|
|
|
232
|
-
// src/bot/
|
|
233
|
-
var
|
|
186
|
+
// src/bot/internal/poll-settings.ts
|
|
187
|
+
var Context3 = __toESM(require("effect/Context"));
|
|
188
|
+
var Data2 = __toESM(require("effect/Data"));
|
|
189
|
+
var BotPollSettings = class _BotPollSettings extends Data2.Class {
|
|
190
|
+
static make(input) {
|
|
191
|
+
let batch_size = input.batch_size ?? 10;
|
|
192
|
+
let poll_timeout = input.poll_timeout ?? 10;
|
|
193
|
+
let max_empty_responses = input.max_empty_responses;
|
|
194
|
+
let log_level = input.log_level ?? "info";
|
|
195
|
+
let on_error = input.on_error;
|
|
196
|
+
if (batch_size < 10 || batch_size > 100) {
|
|
197
|
+
console.warn("Wrong batch_size, must be in [10..100], using 10 instead");
|
|
198
|
+
batch_size = 10;
|
|
199
|
+
}
|
|
200
|
+
if (poll_timeout < 2 || poll_timeout > 10) {
|
|
201
|
+
console.warn("Wrong poll_timeout, must be in [2..10], using 2 instead");
|
|
202
|
+
poll_timeout = 10;
|
|
203
|
+
}
|
|
204
|
+
if (max_empty_responses && max_empty_responses < 2) {
|
|
205
|
+
console.warn("Wrong max_empty_responses, must be in [2..infinity], using infinity");
|
|
206
|
+
max_empty_responses = void 0;
|
|
207
|
+
}
|
|
208
|
+
if (!log_level) {
|
|
209
|
+
log_level = "info";
|
|
210
|
+
}
|
|
211
|
+
if (!on_error) {
|
|
212
|
+
on_error = "stop";
|
|
213
|
+
}
|
|
214
|
+
const config = new _BotPollSettings({
|
|
215
|
+
batch_size,
|
|
216
|
+
poll_timeout,
|
|
217
|
+
max_empty_responses,
|
|
218
|
+
log_level,
|
|
219
|
+
on_error
|
|
220
|
+
});
|
|
221
|
+
console.log("bot poll settings", config);
|
|
222
|
+
return config;
|
|
223
|
+
}
|
|
234
224
|
};
|
|
235
|
-
var
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
225
|
+
var BotPollSettingsTag = class extends Context3.Reference()(
|
|
226
|
+
"BotSettings",
|
|
227
|
+
{
|
|
228
|
+
defaultValue() {
|
|
229
|
+
return BotPollSettings.make({});
|
|
230
|
+
}
|
|
239
231
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
232
|
+
) {
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
// src/bot/internal/handle-update.ts
|
|
236
|
+
var BatchUpdateResult = class extends Data3.Class {
|
|
237
|
+
};
|
|
238
|
+
var handleUpdates = (updates) => Micro2.gen(function* () {
|
|
239
|
+
const pollSettings = yield* Micro2.service(BotPollSettingsTag);
|
|
240
|
+
const updateHandler = yield* Micro2.service(BotUpdateHandlersTag);
|
|
241
|
+
if (updateHandler.type == "single") {
|
|
242
|
+
return yield* handleOneByOne(updates, updateHandler, pollSettings);
|
|
243
|
+
} else {
|
|
244
|
+
return yield* handleEntireBatch(updates, updateHandler, pollSettings);
|
|
248
245
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
),
|
|
263
|
-
{
|
|
264
|
-
concurrency: 10
|
|
246
|
+
});
|
|
247
|
+
var handleEntireBatch = (updates, handlers, pollSettings) => Micro2.try({
|
|
248
|
+
try: () => handlers.on_batch(updates),
|
|
249
|
+
catch: (_) => _
|
|
250
|
+
}).pipe(
|
|
251
|
+
Micro2.andThen((result) => {
|
|
252
|
+
if (result instanceof Promise) {
|
|
253
|
+
return Micro2.tryPromise({
|
|
254
|
+
try: () => result,
|
|
255
|
+
catch: (_) => _
|
|
256
|
+
});
|
|
257
|
+
} else {
|
|
258
|
+
return Micro2.succeed(result);
|
|
265
259
|
}
|
|
266
|
-
)
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
return !batchResult.every((error) => error == null);
|
|
260
|
+
}),
|
|
261
|
+
Micro2.andThen(
|
|
262
|
+
(doNext) => new BatchUpdateResult({
|
|
263
|
+
hasErrors: !doNext,
|
|
264
|
+
updates
|
|
272
265
|
})
|
|
273
|
-
)
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
266
|
+
),
|
|
267
|
+
Micro2.catchAll((error) => {
|
|
268
|
+
console.log("handle batch error", {
|
|
269
|
+
errorMessage: error instanceof Error ? error.message : void 0,
|
|
270
|
+
updates: updates.map((_) => Object.keys(_).at(1))
|
|
278
271
|
});
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
272
|
+
return Micro2.succeed(
|
|
273
|
+
new BatchUpdateResult({
|
|
274
|
+
hasErrors: true,
|
|
275
|
+
updates
|
|
276
|
+
})
|
|
277
|
+
);
|
|
278
|
+
})
|
|
279
|
+
);
|
|
280
|
+
var HandleUpdateError = class extends Data3.TaggedError("HandleUpdateError") {
|
|
281
|
+
};
|
|
282
|
+
var handleOneByOne = (updates, handlers, pollSettings) => Micro2.forEach(
|
|
283
|
+
updates,
|
|
284
|
+
(update) => handleOneUpdate(update, handlers).pipe(
|
|
285
|
+
Micro2.catchAll((error) => {
|
|
286
|
+
console.log("update handle error", {
|
|
287
|
+
updateId: update.update_id,
|
|
288
|
+
updateKey: Object.keys(update).at(1),
|
|
289
|
+
name: error._tag
|
|
290
|
+
});
|
|
291
|
+
return Micro2.succeed(error);
|
|
292
|
+
})
|
|
293
|
+
),
|
|
294
|
+
{
|
|
295
|
+
concurrency: 10
|
|
282
296
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
297
|
+
).pipe(
|
|
298
|
+
Micro2.andThen((batchResult) => {
|
|
299
|
+
if (pollSettings.log_level == "debug") {
|
|
300
|
+
console.debug("handle batch result", batchResult);
|
|
301
|
+
}
|
|
302
|
+
return new BatchUpdateResult({
|
|
303
|
+
hasErrors: !batchResult.every((error) => error == null),
|
|
304
|
+
updates
|
|
305
|
+
});
|
|
306
|
+
})
|
|
307
|
+
);
|
|
308
|
+
var handleOneUpdate = (updateObject, handlers) => Micro2.gen(function* () {
|
|
286
309
|
const update = extractUpdate(updateObject);
|
|
287
310
|
if (!update) {
|
|
288
311
|
return yield* Micro2.fail(
|
|
@@ -292,8 +315,8 @@ var handleUpdate = (updateObject, settings, handlers) => Micro2.gen(function* ()
|
|
|
292
315
|
})
|
|
293
316
|
);
|
|
294
317
|
}
|
|
295
|
-
const
|
|
296
|
-
if (!
|
|
318
|
+
const updateHandler = handlers[`on_${update.type}`];
|
|
319
|
+
if (!updateHandler) {
|
|
297
320
|
return yield* Micro2.fail(
|
|
298
321
|
new HandleUpdateError({
|
|
299
322
|
name: "HandlerNotDefined",
|
|
@@ -310,7 +333,7 @@ var handleUpdate = (updateObject, settings, handlers) => Micro2.gen(function* ()
|
|
|
310
333
|
}
|
|
311
334
|
let handleUpdateError;
|
|
312
335
|
const handleResult = yield* Micro2.try({
|
|
313
|
-
try: () =>
|
|
336
|
+
try: () => updateHandler(update),
|
|
314
337
|
catch: (error) => new HandleUpdateError({
|
|
315
338
|
name: "BotHandlerError",
|
|
316
339
|
update: updateObject,
|
|
@@ -351,7 +374,8 @@ var handleUpdate = (updateObject, settings, handlers) => Micro2.gen(function* ()
|
|
|
351
374
|
);
|
|
352
375
|
})
|
|
353
376
|
);
|
|
354
|
-
|
|
377
|
+
const pollSettings = yield* Micro2.service(BotPollSettingsTag);
|
|
378
|
+
if (!handleResult && pollSettings.log_level == "debug") {
|
|
355
379
|
console.log(`Bot response is undefined for update with ID #${updateObject.update_id}.`);
|
|
356
380
|
return;
|
|
357
381
|
}
|
|
@@ -361,87 +385,144 @@ var handleUpdate = (updateObject, settings, handlers) => Micro2.gen(function* ()
|
|
|
361
385
|
...handleResult.response,
|
|
362
386
|
chat_id: update.chat.id
|
|
363
387
|
});
|
|
364
|
-
if (
|
|
388
|
+
if (pollSettings.log_level == "debug" && "text") {
|
|
365
389
|
console.debug("bot response", response);
|
|
366
390
|
}
|
|
367
391
|
}
|
|
368
392
|
return handleUpdateError;
|
|
369
393
|
});
|
|
370
394
|
|
|
371
|
-
// src/bot/
|
|
372
|
-
var
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
console.
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
;
|
|
401
|
-
if (lastUpdateId) {
|
|
402
|
-
state.lastUpdateId = lastUpdateId + 1;
|
|
403
|
-
}
|
|
404
|
-
return true;
|
|
405
|
-
}
|
|
406
|
-
})
|
|
407
|
-
);
|
|
395
|
+
// src/bot/service/fetch-updates.ts
|
|
396
|
+
var Micro3 = __toESM(require("effect/Micro"));
|
|
397
|
+
var Data4 = __toESM(require("effect/Data"));
|
|
398
|
+
var Context4 = __toESM(require("effect/Context"));
|
|
399
|
+
var BotFetchUpdatesService = class extends Context4.Reference()(
|
|
400
|
+
"BotFetchUpdatesService",
|
|
401
|
+
{
|
|
402
|
+
defaultValue: () => {
|
|
403
|
+
const state = {
|
|
404
|
+
lastUpdateId: void 0,
|
|
405
|
+
emptyResponses: 0
|
|
406
|
+
};
|
|
407
|
+
const fetchUpdates = _fetchUpdates(state).pipe(
|
|
408
|
+
Micro3.tap((updates) => {
|
|
409
|
+
const id = updates.map((_) => _.update_id).sort().at(-1);
|
|
410
|
+
console.log("updating last update id", id);
|
|
411
|
+
state.lastUpdateId = id ? id + 1 : void 0;
|
|
412
|
+
console.log(state);
|
|
413
|
+
})
|
|
414
|
+
);
|
|
415
|
+
const commit = _commitLastBatch(state);
|
|
416
|
+
return {
|
|
417
|
+
state,
|
|
418
|
+
fetchUpdates,
|
|
419
|
+
commit
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
) {
|
|
408
424
|
};
|
|
409
|
-
|
|
410
|
-
// src/bot/update-poller/_service.ts
|
|
411
|
-
var BotUpdatePollerService = class extends Context3.Tag("BotUpdatePollerService")() {
|
|
425
|
+
var FetchUpdatesError = class extends Data4.TaggedError("FetchUpdatesError") {
|
|
412
426
|
};
|
|
413
|
-
var
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
427
|
+
var _fetchUpdates = (pollState) => Micro3.gen(function* () {
|
|
428
|
+
const pollSettings = yield* Micro3.service(BotPollSettingsTag);
|
|
429
|
+
if (pollSettings.max_empty_responses && pollState.emptyResponses == pollSettings.max_empty_responses) {
|
|
430
|
+
return yield* Micro3.fail(
|
|
431
|
+
new FetchUpdatesError({ name: "TooManyEmptyResponses" })
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
const updateId = pollState.lastUpdateId;
|
|
435
|
+
if (pollSettings.log_level == "debug") {
|
|
436
|
+
console.debug("getting updates", pollState);
|
|
437
|
+
}
|
|
438
|
+
const updates = yield* execute("get_updates", {
|
|
439
|
+
timeout: pollSettings.poll_timeout,
|
|
440
|
+
...updateId ? { offset: updateId } : void 0
|
|
441
|
+
}).pipe(
|
|
442
|
+
Micro3.andThen((_) => _.sort((_2) => _2.update_id))
|
|
443
|
+
);
|
|
444
|
+
if (updates.length) {
|
|
445
|
+
console.debug(`got a batch of updates (${updates.length})`);
|
|
446
|
+
pollState.emptyResponses = 0;
|
|
447
|
+
return updates;
|
|
448
|
+
} else {
|
|
449
|
+
pollState.emptyResponses += 1;
|
|
450
|
+
return [];
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
var _commitLastBatch = (pollState) => Micro3.gen(function* () {
|
|
454
|
+
console.log("commit", { pollState });
|
|
455
|
+
if (pollState.lastUpdateId) {
|
|
456
|
+
return yield* execute("get_updates", {
|
|
457
|
+
offset: pollState.lastUpdateId,
|
|
458
|
+
limit: 0
|
|
423
459
|
}).pipe(
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
460
|
+
Micro3.andThen(
|
|
461
|
+
Micro3.andThen(Micro3.service(BotPollSettingsTag), (pollSettings) => {
|
|
462
|
+
if (pollSettings.log_level == "debug") {
|
|
463
|
+
console.debug("committed offset", pollState);
|
|
464
|
+
}
|
|
428
465
|
})
|
|
429
466
|
)
|
|
430
467
|
);
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
468
|
+
} else {
|
|
469
|
+
return yield* Micro3.fail(new FetchUpdatesError({
|
|
470
|
+
name: "NoUpdatesToCommit"
|
|
471
|
+
}));
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
// src/bot/service/run.ts
|
|
476
|
+
var BotRunService = class extends Context5.Reference()(
|
|
477
|
+
"BotRunService",
|
|
478
|
+
{
|
|
479
|
+
defaultValue: () => {
|
|
480
|
+
console.log("Initiating BotRunService");
|
|
481
|
+
const state = {
|
|
482
|
+
fiber: void 0
|
|
483
|
+
};
|
|
484
|
+
const runBotInBackground = _runBotDaemon(state);
|
|
485
|
+
const getFiber = () => state.fiber;
|
|
486
|
+
return {
|
|
487
|
+
runBotInBackground,
|
|
488
|
+
getFiber
|
|
489
|
+
};
|
|
434
490
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
491
|
+
}
|
|
492
|
+
) {
|
|
493
|
+
};
|
|
494
|
+
var _runBotDaemon = (state) => Micro4.gen(function* () {
|
|
495
|
+
console.log("run bot");
|
|
496
|
+
const fetchService = yield* Micro4.service(BotFetchUpdatesService);
|
|
497
|
+
const startFiber = Micro4.delay(1e3)(
|
|
498
|
+
fetchService.fetchUpdates.pipe(
|
|
499
|
+
Micro4.andThen(
|
|
500
|
+
(updates) => handleUpdates(updates)
|
|
501
|
+
),
|
|
502
|
+
Micro4.tap(
|
|
503
|
+
({ updates }) => updates.length > 0 ? fetchService.commit : Micro4.void
|
|
504
|
+
)
|
|
505
|
+
)
|
|
506
|
+
).pipe(
|
|
507
|
+
Micro4.repeat({
|
|
508
|
+
while: (_) => !_.hasErrors
|
|
509
|
+
}),
|
|
510
|
+
Micro4.forkDaemon,
|
|
511
|
+
Micro4.tap(
|
|
512
|
+
(fiber) => fiber.addObserver((exit) => {
|
|
513
|
+
console.log("bot's fiber has been closed", exit);
|
|
514
|
+
})
|
|
515
|
+
)
|
|
516
|
+
);
|
|
517
|
+
if (state.fiber) {
|
|
518
|
+
console.log("killing previous bot's fiber");
|
|
519
|
+
yield* Micro4.fiberInterrupt(state.fiber);
|
|
520
|
+
}
|
|
521
|
+
state.fiber = yield* startFiber;
|
|
522
|
+
console.log("Fetching bot updates via long polling...");
|
|
442
523
|
});
|
|
443
524
|
|
|
444
|
-
// src/bot/
|
|
525
|
+
// src/bot/internal/client-config.ts
|
|
445
526
|
var Micro5 = __toESM(require("effect/Micro"));
|
|
446
527
|
var makeClientConfigFrom = (input) => Micro5.gen(function* () {
|
|
447
528
|
if (input.type == "config") {
|
|
@@ -463,35 +544,29 @@ var makeClientConfigFrom = (input) => Micro5.gen(function* () {
|
|
|
463
544
|
return makeTgBotClientConfig(config);
|
|
464
545
|
});
|
|
465
546
|
|
|
466
|
-
// src/bot/
|
|
467
|
-
var
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
reload,
|
|
486
|
-
fiber: poller.getFiber
|
|
487
|
-
};
|
|
488
|
-
})
|
|
489
|
-
};
|
|
547
|
+
// src/bot/internal/launch.ts
|
|
548
|
+
var launchBot = (input) => Micro6.gen(function* () {
|
|
549
|
+
const clientConfig = Context6.make(TgBotClientConfig, yield* makeClientConfigFrom(input));
|
|
550
|
+
const service8 = yield* Micro6.service(BotRunService);
|
|
551
|
+
yield* service8.runBotInBackground.pipe(
|
|
552
|
+
Micro6.provideContext(clientConfig),
|
|
553
|
+
Micro6.provideService(BotUpdateHandlersTag, input.mode),
|
|
554
|
+
Micro6.provideService(BotPollSettingsTag, BotPollSettings.make(input.poll ?? {}))
|
|
555
|
+
);
|
|
556
|
+
const reload = (mode) => service8.runBotInBackground.pipe(
|
|
557
|
+
Micro6.provideService(BotUpdateHandlersTag, mode),
|
|
558
|
+
Micro6.provideContext(clientConfig),
|
|
559
|
+
Micro6.runPromise
|
|
560
|
+
);
|
|
561
|
+
return {
|
|
562
|
+
reload,
|
|
563
|
+
fiber: service8.getFiber
|
|
564
|
+
};
|
|
565
|
+
});
|
|
490
566
|
|
|
491
567
|
// src/bot/run.ts
|
|
492
568
|
var Micro7 = __toESM(require("effect/Micro"));
|
|
493
|
-
var runTgChatBot = (input) =>
|
|
494
|
-
Micro7.provideService(BotMessageHandler, input),
|
|
569
|
+
var runTgChatBot = (input) => launchBot(input).pipe(
|
|
495
570
|
Micro7.runPromise
|
|
496
571
|
);
|
|
497
572
|
|
|
@@ -500,7 +575,7 @@ var Micro10 = __toESM(require("effect/Micro"));
|
|
|
500
575
|
|
|
501
576
|
// src/client/file/_service.ts
|
|
502
577
|
var Micro9 = __toESM(require("effect/Micro"));
|
|
503
|
-
var
|
|
578
|
+
var Context7 = __toESM(require("effect/Context"));
|
|
504
579
|
|
|
505
580
|
// src/client/file/get-file.ts
|
|
506
581
|
var Micro8 = __toESM(require("effect/Micro"));
|
|
@@ -531,7 +606,7 @@ var getFile = (fileId) => Micro8.gen(function* () {
|
|
|
531
606
|
});
|
|
532
607
|
|
|
533
608
|
// src/client/file/_service.ts
|
|
534
|
-
var ClientFileService = class extends
|
|
609
|
+
var ClientFileService = class extends Context7.Tag("ClientFileService")() {
|
|
535
610
|
};
|
|
536
611
|
var ClientFileServiceDefault = Micro9.gen(function* () {
|
|
537
612
|
return {
|
|
@@ -563,14 +638,13 @@ var makeTgBotClient = (input) => {
|
|
|
563
638
|
};
|
|
564
639
|
// Annotate the CommonJS export names for ESM import in node:
|
|
565
640
|
0 && (module.exports = {
|
|
566
|
-
BotFactoryService,
|
|
567
|
-
BotFactoryServiceDefault,
|
|
568
641
|
BotResponse,
|
|
569
|
-
|
|
570
|
-
|
|
642
|
+
BotRunService,
|
|
643
|
+
BotUpdateHandlersTag,
|
|
571
644
|
MESSAGE_EFFECTS,
|
|
572
645
|
defaultBaseUrl,
|
|
573
646
|
isMessageEffect,
|
|
647
|
+
launchBot,
|
|
574
648
|
makeTgBotClient,
|
|
575
649
|
messageEffectIdCodes,
|
|
576
650
|
runTgChatBot
|