@effect-ak/tg-bot-client 0.6.4 → 1.1.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 +294 -0
- package/dist/index.cjs +209 -0
- package/dist/index.d.cts +98 -0
- package/dist/index.d.ts +63 -28
- package/dist/index.js +169 -1
- package/package.json +19 -56
- package/src/client-file.ts +73 -0
- package/src/client.ts +34 -0
- package/src/config.ts +10 -0
- package/src/const.ts +20 -0
- package/src/errors.ts +18 -0
- package/src/execute.ts +81 -0
- package/src/guards.ts +27 -0
- package/src/index.ts +8 -0
- package/src/utils.ts +3 -0
- package/test/execute.test.ts +102 -0
- package/test/file.test.ts +23 -0
- package/test/fixture.ts +35 -0
- package/tsconfig.json +12 -0
- package/tsup.config.json +10 -0
- package/dist/bot-bundle.js +0 -22
- package/dist/bot-bundle.mjs +0 -22
- package/dist/bot.d.ts +0 -111
- package/dist/bot.js +0 -1
- package/dist/bot.mjs +0 -1
- package/dist/config-3uU0YevV.d.ts +0 -3250
- package/dist/index.mjs +0 -1
- package/dist/webapp.d.ts +0 -392
- package/dist/webapp.js +0 -1
- package/dist/webapp.mjs +0 -0
- package/readme.md +0 -236
package/dist/index.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import*as C from"effect/String";import*as p from"effect/Micro";import*as M from"effect/Data";var a=class extends M.TaggedError("TgBotClientError"){};var T=e=>typeof e=="object"&&e!=null&&"file_content"in e&&e.file_content instanceof Uint8Array&&"file_name"in e&&typeof e.file_name=="string",k=e=>typeof e=="object"&&e!=null&&"ok"in e&&typeof e.ok=="boolean",U=e=>typeof e=="object"&&e!=null&&"update_id"in e&&typeof e.update_id=="number";import*as g from"effect/Context";var F="https://api.telegram.org",_={"\u{1F525}":"5104841245755180586","\u{1F44D}":"5107584321108051014","\u{1F44E}":"5104858069142078462","\u2764\uFE0F":"5159385139981059251","\u{1F389}":"5046509860389126442","\u{1F4A9}":"5046589136895476101"},P=Object.keys(_),v=e=>typeof e=="string"&&e in _;var m=class extends g.Reference()("TgBotApiBaseUrl",{defaultValue:()=>F}){},l=class extends g.Tag("TgBotApiToken")(){};var B=e=>{let s=Object.entries(e);if(s.length==0)return;let t=new FormData;for(let[r,o]of s)o&&(typeof o!="object"?t.append(r,`${o}`):T(o)?t.append(r,new Blob([o.file_content]),o.file_name):t.append(r,JSON.stringify(o)));return t};var u=(e,s)=>p.gen(function*(){let t=yield*p.service(l),r=yield*p.service(m),o=yield*p.tryPromise({try:()=>fetch(`${r}/bot${t}/${C.snakeToCamel(e)}`,{body:B(s)??null,method:"POST"}),catch:f=>new a({cause:{_tag:"ClientInternalError",cause:f}})}),c=yield*p.tryPromise({try:()=>o.json(),catch:()=>new a({cause:{_tag:"NotJsonResponse",response:o}})});return k(c)?o.ok?c.result:yield*p.fail(new a({cause:{_tag:"NotOkResponse",...c.error_code?{errorCode:c.error_code}:void 0,...c.description?{details:c.description}:void 0}})):yield*p.fail(new a({cause:{_tag:"UnexpectedResponse",response:c}}))});import*as i from"effect/Micro";var A=({fileId:e,type:s})=>b(e).pipe(i.andThen(({content:t,file_name:r})=>new File([t],r,{...s?{type:s}:void 0}))),Q=({fileId:e,type:s})=>b(e).pipe(i.andThen(({content:t,file_name:r})=>{let o=Buffer.from(t).toString("base64");return{encoded:`data:${s};base64,${o}`,file_name:r}})),b=e=>i.gen(function*(){let t=(yield*u("get_file",{file_id:e})).file_path;if(!t||t.length==0)return yield*i.fail(new a({cause:{_tag:"UnableToGetFile",cause:"File path not defined"}}));let r=t.replaceAll("/","-"),o=yield*i.service(m),c=yield*i.service(l),f=`${o}/file/bot${c}/${t}`;return{content:yield*i.tryPromise({try:()=>fetch(f).then(y=>y.arrayBuffer()),catch:y=>new a({cause:{_tag:"UnableToGetFile",cause:y}})}),file_name:r}});import*as n from"effect/Micro";import*as S from"effect/Context";import*as E from"effect/Micro";import*as h from"effect/Context";var d=class extends h.Tag("ClientFileService")(){},R=E.gen(function*(){return{getFile:A}});function re(e){return n.gen(function*(){let t=yield*n.service(d),r=S.make(l,e.bot_token);return{execute:(f,x)=>u(f,x).pipe(n.provideContext(r),n.runPromise),getFile:f=>t.getFile(f).pipe(n.provideContext(r),n.runPromise)}}).pipe(n.provideServiceEffect(d,R),n.runSync)}export{_ as MESSAGE_EFFECTS,F as TG_BOT_API_URL,m as TgBotApiBaseUrl,l as TgBotApiToken,a as TgBotClientError,u as executeTgBotMethod,A as getFile,Q as getFileAsBase64String,b as getFileBytes,T as isFileContent,v as isMessageEffect,k as isTgBotApiResponse,U as isTgBotApiUpdate,re as makeTgBotClient,P as messageEffectIdCodes};
|
package/dist/webapp.d.ts
DELETED
|
@@ -1,392 +0,0 @@
|
|
|
1
|
-
type BindOrUnbindEventHandler = <K extends keyof EventHandlers>(eventName: K, handler: EventHandlers[K]) => void;
|
|
2
|
-
type EventHandlers = {
|
|
3
|
-
activated: () => void;
|
|
4
|
-
deactivated: () => void;
|
|
5
|
-
themeChanged: () => void;
|
|
6
|
-
viewportChanged: (options: {
|
|
7
|
-
isStateStable: boolean;
|
|
8
|
-
}) => void;
|
|
9
|
-
safeAreaChanged: () => void;
|
|
10
|
-
contentSafeAreaChanged: () => void;
|
|
11
|
-
mainButtonClicked: () => void;
|
|
12
|
-
backButtonClicked: () => void;
|
|
13
|
-
settingsButtonClicked: () => void;
|
|
14
|
-
invoiceClosed: (options: {
|
|
15
|
-
url: string;
|
|
16
|
-
status: "paid" | "cancelled" | "failed" | "pending";
|
|
17
|
-
}) => void;
|
|
18
|
-
popupClosed: (options: {
|
|
19
|
-
button_id: string | null;
|
|
20
|
-
}) => void;
|
|
21
|
-
qrTextReceived: (options: {
|
|
22
|
-
data: string;
|
|
23
|
-
}) => void;
|
|
24
|
-
scanQrPopupClosed: () => void;
|
|
25
|
-
clipboardTextReceived: (options: {
|
|
26
|
-
data: string;
|
|
27
|
-
}) => void;
|
|
28
|
-
writeAccessRequested: (options: {
|
|
29
|
-
status: "allowed" | "cancelled";
|
|
30
|
-
}) => void;
|
|
31
|
-
biometricManagerUpdated: () => void;
|
|
32
|
-
biometricAuthRequested: (options: {
|
|
33
|
-
isAuthenticated: boolean;
|
|
34
|
-
biometricToken: string | null;
|
|
35
|
-
}) => void;
|
|
36
|
-
biometricTokenUpdated: (options: {
|
|
37
|
-
isUpdated: boolean;
|
|
38
|
-
}) => void;
|
|
39
|
-
fullscreenChanged: () => void;
|
|
40
|
-
fullscreenFailed: (options: {
|
|
41
|
-
error: "UNSUPPORTED" | "ALREADY_FULLSCREEN";
|
|
42
|
-
}) => void;
|
|
43
|
-
homeScreenAdded: () => void;
|
|
44
|
-
homeScreenChecked: (options: {
|
|
45
|
-
status: "unsupported" | "unknown" | "added" | "missed";
|
|
46
|
-
}) => void;
|
|
47
|
-
accelerometerStarted: () => void;
|
|
48
|
-
accelerometerStopped: () => void;
|
|
49
|
-
accelerometerChanged: () => void;
|
|
50
|
-
accelerometerFailed: (options: {
|
|
51
|
-
error: "UNSUPPORTED";
|
|
52
|
-
}) => void;
|
|
53
|
-
deviceOrientationStarted: () => void;
|
|
54
|
-
deviceOrientationStopped: () => void;
|
|
55
|
-
deviceOrientationChanged: () => void;
|
|
56
|
-
deviceOrientationFailed: (options: {
|
|
57
|
-
error: "UNSUPPORTED";
|
|
58
|
-
}) => void;
|
|
59
|
-
gyroscopeStarted: () => void;
|
|
60
|
-
gyroscopeStopped: () => void;
|
|
61
|
-
gyroscopeChanged: () => void;
|
|
62
|
-
gyroscopeFailed: (options: {
|
|
63
|
-
error: "UNSUPPORTED";
|
|
64
|
-
}) => void;
|
|
65
|
-
locationManagerUpdated: () => void;
|
|
66
|
-
locationRequested: (options: {
|
|
67
|
-
locationData: LocationData;
|
|
68
|
-
}) => void;
|
|
69
|
-
shareMessageSent: () => void;
|
|
70
|
-
shareMessageFailed: (options: {
|
|
71
|
-
error: "UNSUPPORTED" | "MESSAGE_EXPIRED" | "MESSAGE_SEND_FAILED" | "USER_DECLINED" | "UNKNOWN_ERROR";
|
|
72
|
-
}) => void;
|
|
73
|
-
emojiStatusSet: () => void;
|
|
74
|
-
emojiStatusFailed: (options: {
|
|
75
|
-
error: "UNSUPPORTED" | "SUGGESTED_EMOJI_INVALID" | "DURATION_INVALID" | "USER_DECLINED" | "SERVER_ERROR" | "UNKNOWN_ERROR";
|
|
76
|
-
}) => void;
|
|
77
|
-
emojiStatusAccessRequested: (options: {
|
|
78
|
-
status: "allowed" | "cancelled";
|
|
79
|
-
}) => void;
|
|
80
|
-
fileDownloadRequested: (options: {
|
|
81
|
-
status: "downloading" | "cancelled";
|
|
82
|
-
}) => void;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
interface WebApp {
|
|
86
|
-
initData: string;
|
|
87
|
-
initDataUnsafe: WebAppInitData;
|
|
88
|
-
version: string;
|
|
89
|
-
platform: string;
|
|
90
|
-
colorScheme: string;
|
|
91
|
-
themeParams: ThemeParams;
|
|
92
|
-
isActive: boolean;
|
|
93
|
-
isExpanded: boolean;
|
|
94
|
-
viewportHeight: number;
|
|
95
|
-
viewportStableHeight: number;
|
|
96
|
-
headerColor: string;
|
|
97
|
-
backgroundColor: string;
|
|
98
|
-
bottomBarColor: string;
|
|
99
|
-
isClosingConfirmationEnabled: boolean;
|
|
100
|
-
isVerticalSwipesEnabled: boolean;
|
|
101
|
-
isFullscreen: boolean;
|
|
102
|
-
isOrientationLocked: boolean;
|
|
103
|
-
safeAreaInset: SafeAreaInset;
|
|
104
|
-
contentSafeAreaInset: ContentSafeAreaInset;
|
|
105
|
-
BackButton: BackButton;
|
|
106
|
-
MainButton: BottomButton;
|
|
107
|
-
SecondaryButton: BottomButton;
|
|
108
|
-
SettingsButton: SettingsButton;
|
|
109
|
-
HapticFeedback: HapticFeedback;
|
|
110
|
-
CloudStorage: CloudStorage;
|
|
111
|
-
BiometricManager: BiometricManager;
|
|
112
|
-
Accelerometer: Accelerometer;
|
|
113
|
-
DeviceOrientation: DeviceOrientation;
|
|
114
|
-
Gyroscope: Gyroscope;
|
|
115
|
-
LocationManager: LocationManager;
|
|
116
|
-
DeviceStorage: DeviceStorage;
|
|
117
|
-
SecureStorage: SecureStorage;
|
|
118
|
-
isVersionAtLeast: (version: string) => boolean;
|
|
119
|
-
setHeaderColor: (color: string) => void;
|
|
120
|
-
setBackgroundColor: (color: string) => void;
|
|
121
|
-
setBottomBarColor: (color: string) => void;
|
|
122
|
-
enableClosingConfirmation: () => void;
|
|
123
|
-
disableClosingConfirmation: () => void;
|
|
124
|
-
enableVerticalSwipes: () => void;
|
|
125
|
-
disableVerticalSwipes: () => void;
|
|
126
|
-
requestFullscreen: () => void;
|
|
127
|
-
exitFullscreen: () => void;
|
|
128
|
-
lockOrientation: () => void;
|
|
129
|
-
unlockOrientation: () => void;
|
|
130
|
-
addToHomeScreen: () => void;
|
|
131
|
-
checkHomeScreenStatus: (callback?: (status: "unsupported" | "unknown" | "added" | "missed") => void) => void;
|
|
132
|
-
onEvent: BindOrUnbindEventHandler;
|
|
133
|
-
offEvent: BindOrUnbindEventHandler;
|
|
134
|
-
sendData: (data: string) => void;
|
|
135
|
-
switchInlineQuery: (query: string, chat_type?: "users" | "bots" | "groups" | "channels") => void;
|
|
136
|
-
openLink: (url: string, options?: {
|
|
137
|
-
try_instant_view: boolean;
|
|
138
|
-
}) => void;
|
|
139
|
-
openTelegramLink: (url: string) => void;
|
|
140
|
-
openInvoice: (url: string, callback?: (invoiceStatus: unknown) => void) => void;
|
|
141
|
-
shareToStory: (mediaUrl: string, options?: StoryShareParams) => void;
|
|
142
|
-
shareMessage: (msg_id: number, options?: (isSent: boolean) => void) => void;
|
|
143
|
-
setEmojiStatus: (custom_emoj_id: string, params?: EmojiStatusParams, callback?: (isStatusSet: boolean) => void) => void;
|
|
144
|
-
requestEmojiStatusAccess: (url: string, callback?: (invoiceStatus: unknown) => void) => void;
|
|
145
|
-
downloadFile: (params: DownloadFileParams, callback?: (isAccepted: boolean) => void) => void;
|
|
146
|
-
hideKeyboard: () => void;
|
|
147
|
-
showPopup: (params: PopupParams, callback?: (buttonId: string) => void) => void;
|
|
148
|
-
showAlert: (message: string, callback?: () => void) => void;
|
|
149
|
-
showConfirm: (message: string, callback?: (isOk: boolean) => void) => void;
|
|
150
|
-
showScanQrPopup: (params: ScanQrPopupParams, callback?: (data: string) => boolean) => void;
|
|
151
|
-
closeScanQrPopup: () => void;
|
|
152
|
-
readTextFromClipboard: (callback?: (text: string) => void) => void;
|
|
153
|
-
requestWriteAccess: (callback?: (isGranted: boolean) => void) => void;
|
|
154
|
-
requestContact: (callback?: (isShared: boolean) => void) => void;
|
|
155
|
-
ready: () => void;
|
|
156
|
-
expand: () => void;
|
|
157
|
-
close: () => void;
|
|
158
|
-
}
|
|
159
|
-
interface Accelerometer {
|
|
160
|
-
isStarted: boolean;
|
|
161
|
-
x: number;
|
|
162
|
-
y: number;
|
|
163
|
-
z: number;
|
|
164
|
-
start: (params: AccelerometerStartParams, callback?: (isStarted: boolean) => void) => Accelerometer;
|
|
165
|
-
stop: (callback?: (isStopped: boolean) => void) => Accelerometer;
|
|
166
|
-
}
|
|
167
|
-
interface AccelerometerStartParams {
|
|
168
|
-
refresh_rate?: number;
|
|
169
|
-
}
|
|
170
|
-
interface BackButton {
|
|
171
|
-
isVisible: boolean;
|
|
172
|
-
onClick: EventHandlers["backButtonClicked"];
|
|
173
|
-
offClick: EventHandlers["backButtonClicked"];
|
|
174
|
-
show: () => BackButton;
|
|
175
|
-
hide: () => BackButton;
|
|
176
|
-
}
|
|
177
|
-
interface BiometricAuthenticateParams {
|
|
178
|
-
reason?: string;
|
|
179
|
-
}
|
|
180
|
-
interface BiometricManager {
|
|
181
|
-
isInited: boolean;
|
|
182
|
-
isBiometricAvailable: boolean;
|
|
183
|
-
biometricType: "finger" | "face" | "unknown";
|
|
184
|
-
isAccessRequested: boolean;
|
|
185
|
-
isAccessGranted: boolean;
|
|
186
|
-
isBiometricTokenSaved: boolean;
|
|
187
|
-
deviceId: string;
|
|
188
|
-
init: (callback?: () => void) => BiometricManager;
|
|
189
|
-
requestAccess: (params: BiometricRequestAccessParams, callback?: (isGranted: boolean) => void) => BiometricManager;
|
|
190
|
-
authenticate: (params: BiometricAuthenticateParams, callback?: (isAuthenticated: boolean) => void) => BiometricManager;
|
|
191
|
-
updateBiometricToken: (token: string, callback?: (isTokenUpdated: boolean) => void) => BiometricManager;
|
|
192
|
-
openSettings: () => BiometricManager;
|
|
193
|
-
}
|
|
194
|
-
interface BiometricRequestAccessParams {
|
|
195
|
-
reason?: string;
|
|
196
|
-
}
|
|
197
|
-
interface BottomButton {
|
|
198
|
-
type: string;
|
|
199
|
-
text: string;
|
|
200
|
-
color: string;
|
|
201
|
-
textColor: string;
|
|
202
|
-
isVisible: boolean;
|
|
203
|
-
isActive: boolean;
|
|
204
|
-
hasShineEffect: boolean;
|
|
205
|
-
position: string;
|
|
206
|
-
isProgressVisible: boolean;
|
|
207
|
-
setText: (text: string) => BottomButton;
|
|
208
|
-
onClick: (callback: () => void) => BottomButton;
|
|
209
|
-
offClick: (callback: () => void) => BottomButton;
|
|
210
|
-
show: () => BottomButton;
|
|
211
|
-
hide: () => BottomButton;
|
|
212
|
-
enable: () => BottomButton;
|
|
213
|
-
disable: () => BottomButton;
|
|
214
|
-
showProgress: (callback: (leaveActive: boolean) => void) => BottomButton;
|
|
215
|
-
hideProgress: () => BottomButton;
|
|
216
|
-
setParams: (params: {
|
|
217
|
-
text: string;
|
|
218
|
-
color: string;
|
|
219
|
-
has_shine_effect: boolean;
|
|
220
|
-
position: unknown;
|
|
221
|
-
is_active: boolean;
|
|
222
|
-
is_visible: boolean;
|
|
223
|
-
}) => BottomButton;
|
|
224
|
-
}
|
|
225
|
-
interface CloudStorage {
|
|
226
|
-
setItem: (key: string, value: string, callback?: (error: unknown | null) => void) => CloudStorage;
|
|
227
|
-
getItem: (key: string, callback: (error: unknown | null, value: string | null) => void) => CloudStorage;
|
|
228
|
-
getItems: (keys: string[], callback: (error: string | null, values: Record<string, string> | null) => void) => CloudStorage;
|
|
229
|
-
removeItem: (key: string, callback?: (error: string | null, isDeleted: boolean) => void) => CloudStorage;
|
|
230
|
-
removeItems: (keys: string[], callback?: (error: string | null, isDeleted: boolean) => void) => CloudStorage;
|
|
231
|
-
getKeys: (callback: (error: string | null, keys: string[] | null) => void) => CloudStorage;
|
|
232
|
-
}
|
|
233
|
-
interface ContentSafeAreaInset {
|
|
234
|
-
top: number;
|
|
235
|
-
bottom: number;
|
|
236
|
-
left: number;
|
|
237
|
-
right: number;
|
|
238
|
-
}
|
|
239
|
-
interface DeviceOrientation {
|
|
240
|
-
isStarted: boolean;
|
|
241
|
-
absolute: boolean;
|
|
242
|
-
alpha: number;
|
|
243
|
-
beta: number;
|
|
244
|
-
gamma: number;
|
|
245
|
-
start: (params: DeviceOrientationStartParams, callback?: (isTracking: boolean) => void) => void;
|
|
246
|
-
stop: (callback?: (isStopped: boolean) => void) => void;
|
|
247
|
-
}
|
|
248
|
-
interface DeviceOrientationStartParams {
|
|
249
|
-
refresh_rate?: number;
|
|
250
|
-
need_absolute?: boolean;
|
|
251
|
-
}
|
|
252
|
-
interface DeviceStorage {
|
|
253
|
-
setItem: (key: string, value: string, callback?: (error: unknown | null, isStored: boolean) => void) => DeviceStorage;
|
|
254
|
-
getItem: (key: string, callback: (error: unknown | null, value: string | null) => void) => DeviceStorage;
|
|
255
|
-
removeItem: (key: string, callback?: (error: unknown | null, isRemoved: boolean) => void) => DeviceStorage;
|
|
256
|
-
clear: (callback?: (error: unknown | null, isCleared: boolean) => void) => DeviceStorage;
|
|
257
|
-
}
|
|
258
|
-
interface DownloadFileParams {
|
|
259
|
-
url: string;
|
|
260
|
-
file_name: string;
|
|
261
|
-
}
|
|
262
|
-
interface EmojiStatusParams {
|
|
263
|
-
duration?: number;
|
|
264
|
-
}
|
|
265
|
-
interface Gyroscope {
|
|
266
|
-
isStarted: boolean;
|
|
267
|
-
x: number;
|
|
268
|
-
y: number;
|
|
269
|
-
z: number;
|
|
270
|
-
start: (params: GyroscopeStartParams, callback?: (isTracking: boolean) => void) => void;
|
|
271
|
-
stop: (callback?: (isStopped: boolean) => void) => void;
|
|
272
|
-
}
|
|
273
|
-
interface GyroscopeStartParams {
|
|
274
|
-
refresh_rate?: number;
|
|
275
|
-
}
|
|
276
|
-
interface HapticFeedback {
|
|
277
|
-
impactOccurred: (style: "light" | "medium" | "heavy" | "rigid" | "soft") => void;
|
|
278
|
-
notificationOccurred: (type: "error" | "success" | "warning") => void;
|
|
279
|
-
selectionChanged: () => HapticFeedback;
|
|
280
|
-
}
|
|
281
|
-
interface LocationData {
|
|
282
|
-
latitude: number;
|
|
283
|
-
longitude: number;
|
|
284
|
-
altitude: number;
|
|
285
|
-
course: number;
|
|
286
|
-
speed: number;
|
|
287
|
-
horizontal_accuracy: number;
|
|
288
|
-
vertical_accuracy: number;
|
|
289
|
-
course_accuracy: number;
|
|
290
|
-
speed_accuracy: number;
|
|
291
|
-
}
|
|
292
|
-
interface LocationManager {
|
|
293
|
-
isInited: boolean;
|
|
294
|
-
isLocationAvailable: boolean;
|
|
295
|
-
isAccessRequested: boolean;
|
|
296
|
-
isAccessGranted: boolean;
|
|
297
|
-
init: (callback?: () => void) => LocationManager;
|
|
298
|
-
getLocation: (callback: (location: LocationData | null) => void) => LocationManager;
|
|
299
|
-
openSettings: () => LocationManager;
|
|
300
|
-
}
|
|
301
|
-
interface PopupButton {
|
|
302
|
-
id?: string;
|
|
303
|
-
type?: "OK" | "Close" | "Cancel";
|
|
304
|
-
text?: string;
|
|
305
|
-
}
|
|
306
|
-
interface PopupParams {
|
|
307
|
-
message: string;
|
|
308
|
-
title?: string;
|
|
309
|
-
buttons?: PopupButton[];
|
|
310
|
-
}
|
|
311
|
-
interface SafeAreaInset {
|
|
312
|
-
top: number;
|
|
313
|
-
bottom: number;
|
|
314
|
-
left: number;
|
|
315
|
-
right: number;
|
|
316
|
-
}
|
|
317
|
-
interface ScanQrPopupParams {
|
|
318
|
-
text?: string;
|
|
319
|
-
}
|
|
320
|
-
interface SecureStorage {
|
|
321
|
-
setItem: (key: string, value: string, callback?: (error: unknown | null, isStored: boolean) => void) => SecureStorage;
|
|
322
|
-
getItem: (key: string, callback: (error: unknown | null, value: string | null, canBeRestored: boolean) => void) => SecureStorage;
|
|
323
|
-
restoreItem: (key: string, callback?: (error: unknown | null, value: string | null) => void) => SecureStorage;
|
|
324
|
-
removeItem: (key: string, callback?: (error: unknown | null, isRemoved: boolean) => void) => SecureStorage;
|
|
325
|
-
clear: (callback?: (error: unknown | null, isCleared: boolean) => void) => SecureStorage;
|
|
326
|
-
}
|
|
327
|
-
interface SettingsButton {
|
|
328
|
-
isVisible: boolean;
|
|
329
|
-
onClick: (callback: () => void) => SettingsButton;
|
|
330
|
-
offClick: (callback: () => void) => SettingsButton;
|
|
331
|
-
show: () => SettingsButton;
|
|
332
|
-
hide: () => SettingsButton;
|
|
333
|
-
}
|
|
334
|
-
interface StoryShareParams {
|
|
335
|
-
text?: string;
|
|
336
|
-
widget_link?: StoryWidgetLink;
|
|
337
|
-
}
|
|
338
|
-
interface StoryWidgetLink {
|
|
339
|
-
url: string;
|
|
340
|
-
name?: string;
|
|
341
|
-
}
|
|
342
|
-
interface ThemeParams {
|
|
343
|
-
bg_color?: string;
|
|
344
|
-
text_color?: string;
|
|
345
|
-
hint_color?: string;
|
|
346
|
-
link_color?: string;
|
|
347
|
-
button_color?: string;
|
|
348
|
-
button_text_color?: string;
|
|
349
|
-
secondary_bg_color?: string;
|
|
350
|
-
header_bg_color?: string;
|
|
351
|
-
bottom_bar_bg_color?: string;
|
|
352
|
-
accent_text_color?: string;
|
|
353
|
-
section_bg_color?: string;
|
|
354
|
-
section_header_text_color?: string;
|
|
355
|
-
section_separator_color?: string;
|
|
356
|
-
subtitle_text_color?: string;
|
|
357
|
-
destructive_text_color?: string;
|
|
358
|
-
}
|
|
359
|
-
interface WebAppChat {
|
|
360
|
-
id: number;
|
|
361
|
-
type: "group" | "supergroup" | "channel";
|
|
362
|
-
title: string;
|
|
363
|
-
username?: string;
|
|
364
|
-
photo_url?: "in";
|
|
365
|
-
}
|
|
366
|
-
interface WebAppInitData {
|
|
367
|
-
auth_date: number;
|
|
368
|
-
hash: string;
|
|
369
|
-
signature: string;
|
|
370
|
-
query_id?: string;
|
|
371
|
-
user?: WebAppUser;
|
|
372
|
-
receiver?: WebAppUser;
|
|
373
|
-
chat?: WebAppChat;
|
|
374
|
-
chat_type?: string;
|
|
375
|
-
chat_instance?: string;
|
|
376
|
-
start_param?: string;
|
|
377
|
-
can_send_after?: number;
|
|
378
|
-
}
|
|
379
|
-
interface WebAppUser {
|
|
380
|
-
id: number;
|
|
381
|
-
first_name: string;
|
|
382
|
-
is_bot?: boolean;
|
|
383
|
-
last_name?: string;
|
|
384
|
-
username?: string;
|
|
385
|
-
language_code?: string;
|
|
386
|
-
is_premium?: boolean;
|
|
387
|
-
added_to_attachment_menu?: boolean;
|
|
388
|
-
allows_write_to_pm?: boolean;
|
|
389
|
-
photo_url?: "in";
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
export type { Accelerometer, AccelerometerStartParams, BackButton, BiometricAuthenticateParams, BiometricManager, BiometricRequestAccessParams, BottomButton, CloudStorage, ContentSafeAreaInset, DeviceOrientation, DeviceOrientationStartParams, DeviceStorage, DownloadFileParams, EmojiStatusParams, Gyroscope, GyroscopeStartParams, HapticFeedback, LocationData, LocationManager, PopupButton, PopupParams, SafeAreaInset, ScanQrPopupParams, SecureStorage, SettingsButton, StoryShareParams, StoryWidgetLink, ThemeParams, WebApp, WebAppChat, WebAppInitData, WebAppUser };
|
package/dist/webapp.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var m=Object.defineProperty;var t=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var a=Object.prototype.hasOwnProperty;var b=(r,o,p,f)=>{if(o&&typeof o=="object"||typeof o=="function")for(let e of x(o))!a.call(r,e)&&e!==p&&m(r,e,{get:()=>o[e],enumerable:!(f=t(o,e))||f.enumerable});return r};var c=r=>b(m({},"__esModule",{value:!0}),r);var d={};module.exports=c(d);
|
package/dist/webapp.mjs
DELETED
|
File without changes
|
package/readme.md
DELETED
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
[](https://www.npmjs.com/package/@effect-ak/tg-bot-client)
|
|
2
|
-

|
|
3
|
-

|
|
4
|
-
[](https://effect-ak.github.io/telegram-bot-api/)
|
|
5
|
-

|
|
6
|
-

|
|
7
|
-
|
|
8
|
-
## Motivation
|
|
9
|
-
**Telegram** does not offer an official TypeScript **SDK** for their **API** but they provide documentation in HTML format.
|
|
10
|
-
|
|
11
|
-
This package aims to parse official documentation of [Bot Api](https://core.telegram.org/bots/api) and [Telegram.Webapp](https://core.telegram.org/bots/api) and generate **TypeScript types**!
|
|
12
|
-
|
|
13
|
-
## Highlights:
|
|
14
|
-
- **[Client](#client)**: Light TypeScript client
|
|
15
|
-
- **Complete and Up-to-Date Telegram Bot API**: The entire API is generated from [the official documentation](https://core.telegram.org/bots/api) using a [code generator](./codegen/main.ts), ensuring this client remains in sync and supports every method and type provided by the **Telegram Bot API**.
|
|
16
|
-
- **[Types for Webapps](#webapps-typings)** Types that describe `Telegram.WebApp`. Created by [code generator](./codegen/main.ts) as well.
|
|
17
|
-
- **[ChatBot runner](#chatbot-runner)**: Focus on the logic of your chat bot
|
|
18
|
-
- **Type Mapping**: Types from the documentation are converted to TypeScript types:
|
|
19
|
-
- `Integer` → `number`
|
|
20
|
-
- `True` → `boolean`
|
|
21
|
-
- `String or Number` → `string | number`
|
|
22
|
-
- Enumerated types, such as `"Type of the chat can be either “private”, “group”, “supergroup” or “channel”"`, are converted to a standard union of literal types `"private" | "group" | "supergroup" | "channel"`
|
|
23
|
-
- And more...
|
|
24
|
-
|
|
25
|
-
## Client
|
|
26
|
-
|
|
27
|
-
```typescript
|
|
28
|
-
import { makeTgBotClient } from "@effect-ak/tg-bot-client"
|
|
29
|
-
|
|
30
|
-
const client = makeTgBotClient({
|
|
31
|
-
bot_token: "" //your token taken from bot father
|
|
32
|
-
});
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### Executing api methods (Promise based)
|
|
36
|
-
|
|
37
|
-
`client` has an `execute` method which requires two arguments
|
|
38
|
-
|
|
39
|
-
- the first is the API method, e.g. `send_message`
|
|
40
|
-
- the second is an object containing the arguments for that method, e.g. `text`
|
|
41
|
-
|
|
42
|
-
> Method names, such as `setChatAdministratorCustomTitle`, are converted to snake_case for easier code readability, e.g., `set_chat_administrator_custom_title`.
|
|
43
|
-
|
|
44
|
-
#### 1. Sending a Message with an Effect
|
|
45
|
-
|
|
46
|
-
```typescript
|
|
47
|
-
import { MESSAGE_EFFECTS } from "@effect-ak/tg-bot-client"
|
|
48
|
-
|
|
49
|
-
await client.execute("send_message", {
|
|
50
|
-
chat_id: "???", // replace ??? with the chat number
|
|
51
|
-
text: "hey again",
|
|
52
|
-
message_effect_id: MESSAGE_EFFECTS["🔥"]
|
|
53
|
-
});
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
#### 2. Sending a Dice
|
|
57
|
-
|
|
58
|
-
```typescript
|
|
59
|
-
import { MESSAGE_EFFECTS } from "@effect-ak/tg-bot-client"
|
|
60
|
-
|
|
61
|
-
await client.execute("send_dice", {
|
|
62
|
-
chat_id: "???", // replace ??? with the chat number
|
|
63
|
-
emoji: "🎲"
|
|
64
|
-
});
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
#### 3. Sending a Document
|
|
68
|
-
|
|
69
|
-
```typescript
|
|
70
|
-
import { MESSAGE_EFFECTS } from "@effect-ak/tg-bot-client"
|
|
71
|
-
|
|
72
|
-
await client.execute("send_document", {
|
|
73
|
-
chat_id: "???", // replace ??? with the chat number
|
|
74
|
-
message_effect_id: MESSAGE_EFFECTS["🎉"],
|
|
75
|
-
document: {
|
|
76
|
-
file_content: new TextEncoder().encode("Hello!"),
|
|
77
|
-
file_name: "hello.txt"
|
|
78
|
-
},
|
|
79
|
-
caption: "simple text file"
|
|
80
|
-
})
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
#### 4. Getting a file
|
|
85
|
-
|
|
86
|
-
In order to download file from Telegram server we need to send two http requests:
|
|
87
|
-
1. execute `get_file` and get `remote_path`
|
|
88
|
-
2. get file content via GET request with different url
|
|
89
|
-
|
|
90
|
-
`client.getFile` does exactly that. It returns [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File)
|
|
91
|
-
|
|
92
|
-
```typescript
|
|
93
|
-
const file =
|
|
94
|
-
await client.getFile({
|
|
95
|
-
file_id: fileId
|
|
96
|
-
});
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Executing api methods (Effect based)
|
|
100
|
-
|
|
101
|
-
If you want to use [Effect](https://effect.website/) instead of `Promise`:
|
|
102
|
-
```typescript
|
|
103
|
-
import { executeTgBotMethod, TgBotApiToken } from "@effect-ak/tg-bot-client";
|
|
104
|
-
import { Effect } from "effect";
|
|
105
|
-
|
|
106
|
-
executeTgBotMethod("send_message", {
|
|
107
|
-
text: "hello",
|
|
108
|
-
chat_id: config.chat_id
|
|
109
|
-
}).pipe(
|
|
110
|
-
Effect.provideService(TgBotApiToken, 'your-token-from-bot-father'),
|
|
111
|
-
Effect.runPromiseExit
|
|
112
|
-
)
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## ChatBot runner
|
|
116
|
-
|
|
117
|
-
### How this library helps
|
|
118
|
-
|
|
119
|
-
A chatbot is essentially a **function** that is triggered by every user message, whether it's a text message, a reaction, or a payment update. Lets name this function as **handler function**
|
|
120
|
-
|
|
121
|
-
This library handles the task of reading these **updates** from the Telegram Bot API's **message queue**. It then invokes the appropriate **handler function** with the received update.
|
|
122
|
-
|
|
123
|
-
### Playground
|
|
124
|
-
|
|
125
|
-
Develop/Run chat bots in your browser via **[Chat Bot Playground](https://effect-ak.github.io/telegram-bot-playground/)**
|
|
126
|
-
|
|
127
|
-
### Local run
|
|
128
|
-
|
|
129
|
-
You can write the logic for your chatbot and **run it locally** and message to your bot via **Telegram** messenger.
|
|
130
|
-
|
|
131
|
-
Take a look at examples [here](example)
|
|
132
|
-
|
|
133
|
-
### Setup Instructions
|
|
134
|
-
|
|
135
|
-
1. **Create `bot.js` and Implement Your Bot's Logic**
|
|
136
|
-
|
|
137
|
-
Create a file (for example `bot.js`) and add your bot's logic as shown below:
|
|
138
|
-
|
|
139
|
-
```typescript
|
|
140
|
-
import { MESSAGE_EFFECTS } from "@effect-ak/tg-bot-client"
|
|
141
|
-
import { runTgChatBot, BotResponse, defineBot } from "@effect-ak/tg-bot-client/bot"
|
|
142
|
-
|
|
143
|
-
const BOT = defineBot({
|
|
144
|
-
on_message: (msg) => {
|
|
145
|
-
|
|
146
|
-
if (!msg.text) return BotResponse.ignore;
|
|
147
|
-
|
|
148
|
-
if (msg?.text === "bye") {
|
|
149
|
-
return BotResponse.make({
|
|
150
|
-
type: "message",
|
|
151
|
-
text: "See you later!",
|
|
152
|
-
message_effect_id: MESSAGE_EFFECTS["❤️"]
|
|
153
|
-
})
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return BotResponse.make({
|
|
157
|
-
type: "message",
|
|
158
|
-
text: "I'm a simple bot"
|
|
159
|
-
})
|
|
160
|
-
}
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
runTgChatBot({
|
|
164
|
-
bot_token: "your-token" // PUT YOUR TOKEN HERE
|
|
165
|
-
mode: {
|
|
166
|
-
type: "single",
|
|
167
|
-
...BOT
|
|
168
|
-
}
|
|
169
|
-
})
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
2. **Run the Bot**
|
|
173
|
-
|
|
174
|
-
To start your chatbot, execute the following command in your terminal:
|
|
175
|
-
|
|
176
|
-
```bash
|
|
177
|
-
node bot.js
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### How It Works: Pull Model
|
|
181
|
-
|
|
182
|
-
The Telegram bot supports both **push** and **pull** notification models for messages. This package uses the **pull** model for several reasons:
|
|
183
|
-
|
|
184
|
-
- **Run chat bots anywhere without exposing public ports or URLs:** The Telegram **push** model requires you as a developer to specify a public URL where updates will be sent.
|
|
185
|
-
For example, **pull** allows running chat bots in a web browser, which doesn't have a public URL.
|
|
186
|
-
|
|
187
|
-
- **Leveraging Telegram's infrastructure:** Telegram keeps new updates for 24 hours and gives you plenty of time to process them.
|
|
188
|
-
|
|
189
|
-
#### Few details and clarifications
|
|
190
|
-
|
|
191
|
-
Developer is responsible only for **Handler Function**.
|
|
192
|
-
|
|
193
|
-
**ChatBot runner** reads updates from the queue and shifts **ID** of last proceeded update so that **handler function** won't be triggered multiple times for the same update.
|
|
194
|
-
|
|
195
|
-
```mermaid
|
|
196
|
-
graph TD
|
|
197
|
-
HandlerFunction[/**Handler Function**/]
|
|
198
|
-
Library[**ChatBot runner**]
|
|
199
|
-
TgBot[Telegram chat bot]
|
|
200
|
-
MessageQueue[**Bot updates queue**<br>_api.telegram.org/bot/updates_]
|
|
201
|
-
User -->|Sends Update, e.g a text message| TgBot
|
|
202
|
-
TgBot -->|Stores Update for 24 hours | MessageQueue
|
|
203
|
-
|
|
204
|
-
subgraph Pull Updates
|
|
205
|
-
Library -->|Fetches Update | MessageQueue
|
|
206
|
-
Library -->|Invokes| HandlerFunction
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
## Webapps typings
|
|
213
|
-
|
|
214
|
-
Telegram provides a big [html](https://core.telegram.org/bots/webapps) page that describes `Telegram.WebApp`
|
|
215
|
-
|
|
216
|
-
`@effect-ak/tg-bot-client` leverages scrapper's functionality to generate TypeScript types.
|
|
217
|
-
|
|
218
|
-
```typescript
|
|
219
|
-
import type { WebApp } from "@effect-ak/tg-bot-client/webapp";
|
|
220
|
-
|
|
221
|
-
interface Telegram {
|
|
222
|
-
WebApp: TgWebApp
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
declare const Telegram: Telegram;
|
|
226
|
-
|
|
227
|
-
const saveData = () => {
|
|
228
|
-
|
|
229
|
-
Telegram.WebApp.CloudStorage.setItem("key1", "some data", (error) => {
|
|
230
|
-
if (error == null) {
|
|
231
|
-
console.log("Saved!")
|
|
232
|
-
}
|
|
233
|
-
})
|
|
234
|
-
|
|
235
|
-
}
|
|
236
|
-
```
|