@effect-ak/tg-bot-client 0.0.4 → 0.0.7
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/cjs/client/_client.js +1 -1
- package/dist/cjs/client/download-file.js +28 -9
- package/dist/cjs/client/errors.js +19 -0
- package/dist/cjs/client/execute-request.js +48 -11
- package/dist/cjs/client/response.js +13 -1
- package/dist/dts/client/_client.d.ts +9 -2
- package/dist/dts/client/download-file.d.ts +7 -1
- package/dist/dts/client/errors.d.ts +21 -0
- package/dist/dts/client/execute-request.d.ts +10 -2
- package/dist/dts/client/request.d.ts +1 -1
- package/dist/dts/client/response.d.ts +1 -1
- package/dist/dts/specification/api.d.ts +131 -132
- package/dist/esm/client/_client.js +1 -1
- package/dist/esm/client/download-file.js +27 -8
- package/dist/esm/client/errors.js +12 -0
- package/dist/esm/client/execute-request.js +44 -11
- package/dist/esm/client/response.js +13 -4
- package/package.json +2 -1
- package/readme.md +11 -2
- package/dist/cjs/client/factory.js +0 -29
- package/dist/dts/client/factory.d.ts +0 -9
- package/dist/esm/client/factory.js +0 -23
|
@@ -1,15 +1,34 @@
|
|
|
1
|
+
import { TgBotClientError } from "./errors.js";
|
|
1
2
|
export const makeDownloadFile = (config, execute) => {
|
|
2
3
|
const getFile = async (input) => {
|
|
3
|
-
const response = await execute("get_file", input);
|
|
4
|
-
response.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
const response = await execute.execute("get_file", input);
|
|
5
|
+
if (response.error)
|
|
6
|
+
return { error: response.error };
|
|
7
|
+
const file_path = response.success?.file_path;
|
|
8
|
+
if (!file_path || file_path.length == 0) {
|
|
9
|
+
return {
|
|
10
|
+
error: new TgBotClientError({
|
|
11
|
+
type: "UnableToGetFile",
|
|
12
|
+
cause: "File path not defined"
|
|
13
|
+
})
|
|
14
|
+
};
|
|
15
|
+
}
|
|
8
16
|
const file_name = file_path.replaceAll("/", "-");
|
|
9
17
|
const url = `${config.baseUrl}/file/bot${config.token}/${file_path}`;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
18
|
+
try {
|
|
19
|
+
const fileContent = await fetch(url).then(_ => _.arrayBuffer());
|
|
20
|
+
const file = new File([new Uint8Array(fileContent)], file_name);
|
|
21
|
+
return {
|
|
22
|
+
success: file
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
catch (cause) {
|
|
26
|
+
return {
|
|
27
|
+
error: new TgBotClientError({
|
|
28
|
+
type: "UnableToGetFile", cause
|
|
29
|
+
})
|
|
30
|
+
};
|
|
31
|
+
}
|
|
13
32
|
};
|
|
14
33
|
return {
|
|
15
34
|
getFile
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export class TgBotClientError extends Error {
|
|
2
|
+
reason;
|
|
3
|
+
_tag = "TgBotClientError";
|
|
4
|
+
constructor(reason) {
|
|
5
|
+
super();
|
|
6
|
+
this.reason = reason;
|
|
7
|
+
}
|
|
8
|
+
static missingSuccess = new TgBotClientError({
|
|
9
|
+
type: "ClientInternalError",
|
|
10
|
+
cause: "Expected 'success' to be defined"
|
|
11
|
+
});
|
|
12
|
+
}
|
|
@@ -1,21 +1,54 @@
|
|
|
1
1
|
import { makePayload } from "./request.js";
|
|
2
2
|
import { isTgBotApiResponse } from "./response.js";
|
|
3
|
+
import { TgBotClientError } from "./errors.js";
|
|
3
4
|
export const makeExecute = (config) => {
|
|
4
5
|
const execute = async (method, input) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (!isTgBotApiResponse(httpResponse))
|
|
10
|
-
throw new Error("Not valid response", {
|
|
11
|
-
cause: httpResponse
|
|
6
|
+
try {
|
|
7
|
+
const httpResponse = await fetch(`${config.baseUrl}/bot${config.token}/${snakeToCamel(method)}`, {
|
|
8
|
+
body: makePayload(input) ?? null,
|
|
9
|
+
method: "POST",
|
|
12
10
|
});
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
const response = await httpResponse.json();
|
|
12
|
+
if (!isTgBotApiResponse(response)) {
|
|
13
|
+
return {
|
|
14
|
+
error: new TgBotClientError({
|
|
15
|
+
type: "UnexpectedResponse",
|
|
16
|
+
response
|
|
17
|
+
})
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
if (!httpResponse.ok) {
|
|
21
|
+
return {
|
|
22
|
+
error: new TgBotClientError({
|
|
23
|
+
type: "NotOkResponse",
|
|
24
|
+
...(response.error_code ? { errorCode: response.error_code } : undefined),
|
|
25
|
+
...(response.description ? { details: response.description } : undefined)
|
|
26
|
+
})
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
success: response.result
|
|
31
|
+
};
|
|
15
32
|
}
|
|
16
|
-
|
|
33
|
+
catch (cause) {
|
|
34
|
+
return {
|
|
35
|
+
error: new TgBotClientError({
|
|
36
|
+
type: "ClientInternalError", cause
|
|
37
|
+
})
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const unsafeExecute = async (method, input) => {
|
|
42
|
+
const result = await execute(method, input);
|
|
43
|
+
if (result.error)
|
|
44
|
+
throw result.error;
|
|
45
|
+
if (!("success" in result))
|
|
46
|
+
throw TgBotClientError.missingSuccess;
|
|
47
|
+
return result.success;
|
|
48
|
+
};
|
|
49
|
+
return {
|
|
50
|
+
execute, unsafeExecute
|
|
17
51
|
};
|
|
18
|
-
return execute;
|
|
19
52
|
};
|
|
20
53
|
const snakeToCamel = (methodName) => methodName
|
|
21
54
|
.split("_")
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
export const isTgBotApiResponse = (input) => {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
if (typeof input !== "object" || input == null) {
|
|
3
|
+
return false;
|
|
4
|
+
}
|
|
5
|
+
if (!("ok" in input && typeof input.ok == "boolean")) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
if ("error_code" in input && typeof input.error_code != "number") {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
if ("description" in input && typeof input.description != "string") {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
return true;
|
|
6
15
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect-ak/tg-bot-client",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Aleksandr Kondaurov",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"vitest": "^2.1.8"
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
|
+
"gen": "bun run codegen/main",
|
|
43
44
|
"build": "pnpm build-esm && pnpm build-cjs",
|
|
44
45
|
"build-esm": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
|
|
45
46
|
"build-cjs": "babel dist/esm --out-dir dist/cjs"
|
package/readme.md
CHANGED
|
@@ -23,14 +23,23 @@ They only provide documentation in the form of a massive HTML page, which is ver
|
|
|
23
23
|
#### Creating a Client
|
|
24
24
|
|
|
25
25
|
```typescript
|
|
26
|
-
import { makeTgBotClient } from "effect-ak/tg-bot-client"
|
|
26
|
+
import { makeTgBotClient } from "@effect-ak/tg-bot-client"
|
|
27
27
|
|
|
28
28
|
const client = makeTgBotClient({
|
|
29
29
|
token: "" //your token from bot father
|
|
30
30
|
});
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
#### Executing api methods, typesafety
|
|
34
|
+
|
|
35
|
+
`client` has an `execute` method which requires two arguments
|
|
36
|
+
|
|
37
|
+
- the first is the API method, e.g. `send_message`
|
|
38
|
+
- the second is an object containing the arguments for that method, e.g. `text`
|
|
39
|
+
|
|
40
|
+
`execute` never returns failed promise, instead, it gives an object with two fields, `success`, `error`.
|
|
41
|
+
|
|
42
|
+
if you want, you can use unsafe alternative, `unsafeExecute`, which gives you the result of method or throws an Error
|
|
34
43
|
|
|
35
44
|
#### 1. Sending a Message with an Effect
|
|
36
45
|
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.makeTgBotClient = void 0;
|
|
7
|
-
var _request = require("./request.js");
|
|
8
|
-
var _response = require("./response.js");
|
|
9
|
-
const defaultBaseUrl = "https://api.telegram.org";
|
|
10
|
-
const makeTgBotClient = options => {
|
|
11
|
-
const baseUrl = options.baseUrl ?? defaultBaseUrl;
|
|
12
|
-
const execute = async (method, input) => {
|
|
13
|
-
const httpResponse = await fetch(`${baseUrl}/bot${options.token}/${(0, _request.methodPath)(method)}`, {
|
|
14
|
-
body: (0, _request.makePayload)(input) ?? null,
|
|
15
|
-
method: "POST"
|
|
16
|
-
}).then(_ => _.json());
|
|
17
|
-
if (!(0, _response.isTgBotApiResponse)(httpResponse)) throw new Error("Not valid response", {
|
|
18
|
-
cause: httpResponse
|
|
19
|
-
});
|
|
20
|
-
if (httpResponse.ok == false) {
|
|
21
|
-
console.warn(httpResponse);
|
|
22
|
-
}
|
|
23
|
-
return httpResponse;
|
|
24
|
-
};
|
|
25
|
-
return {
|
|
26
|
-
execute
|
|
27
|
-
};
|
|
28
|
-
};
|
|
29
|
-
exports.makeTgBotClient = makeTgBotClient;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { Api } from "../specification/api.js";
|
|
2
|
-
import { TgBotApiResponse } from "./response.js";
|
|
3
|
-
export type TgBotClient = ReturnType<typeof makeTgBotClient>;
|
|
4
|
-
export declare const makeTgBotClient: (options: {
|
|
5
|
-
token: string;
|
|
6
|
-
baseUrl?: string;
|
|
7
|
-
}) => {
|
|
8
|
-
readonly execute: <M extends keyof Api>(method: M, input: Parameters<Api[M]>[0]) => Promise<TgBotApiResponse<ReturnType<Api[M]>>>;
|
|
9
|
-
};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { makePayload, methodPath } from "./request.js";
|
|
2
|
-
import { isTgBotApiResponse } from "./response.js";
|
|
3
|
-
const defaultBaseUrl = "https://api.telegram.org";
|
|
4
|
-
export const makeTgBotClient = (options) => {
|
|
5
|
-
const baseUrl = options.baseUrl ?? defaultBaseUrl;
|
|
6
|
-
const execute = async (method, input) => {
|
|
7
|
-
const httpResponse = await fetch(`${baseUrl}/bot${options.token}/${methodPath(method)}`, {
|
|
8
|
-
body: makePayload(input) ?? null,
|
|
9
|
-
method: "POST"
|
|
10
|
-
}).then(_ => _.json());
|
|
11
|
-
if (!isTgBotApiResponse(httpResponse))
|
|
12
|
-
throw new Error("Not valid response", {
|
|
13
|
-
cause: httpResponse
|
|
14
|
-
});
|
|
15
|
-
if (httpResponse.ok == false) {
|
|
16
|
-
console.warn(httpResponse);
|
|
17
|
-
}
|
|
18
|
-
return httpResponse;
|
|
19
|
-
};
|
|
20
|
-
return {
|
|
21
|
-
execute
|
|
22
|
-
};
|
|
23
|
-
};
|