@@ -2,142 +2,235 @@ import TelegramInlineQueryResultArticle from './types/TelegramInlineQueryResultA
22import TelegramInlineQueryResultPhoto from './types/TelegramInlineQueryResultPhoto.js' ;
33import TelegramInlineQueryResultVideo from './types/TelegramInlineQueryResultVideo.js' ;
44
5- /** Class representing the Telegram API and all it's methods */
5+ /** Interface for common Telegram API parameters */
6+ interface TelegramApiBaseParams {
7+ chat_id : number | string ;
8+ business_connection_id ?: string | number ;
9+ }
10+
11+ /** Interface for message parameters */
12+ interface SendMessageParams extends TelegramApiBaseParams {
13+ text : string ;
14+ parse_mode : string ;
15+ reply_to_message_id ?: number | string ;
16+ disable_web_page_preview ?: boolean ;
17+ disable_notification ?: boolean ;
18+ protect_content ?: boolean ;
19+ reply_markup ?: object ;
20+ }
21+
22+ /** Interface for photo parameters */
23+ interface SendPhotoParams extends TelegramApiBaseParams {
24+ photo : string ;
25+ caption ?: string ;
26+ parse_mode ?: string ;
27+ reply_to_message_id ?: number | string ;
28+ disable_notification ?: boolean ;
29+ protect_content ?: boolean ;
30+ reply_markup ?: object ;
31+ }
32+
33+ /** Interface for video parameters */
34+ interface SendVideoParams extends TelegramApiBaseParams {
35+ video : string ;
36+ caption ?: string ;
37+ parse_mode ?: string ;
38+ reply_to_message_id ?: number | string ;
39+ disable_notification ?: boolean ;
40+ protect_content ?: boolean ;
41+ reply_markup ?: object ;
42+ }
43+
44+ /** Interface for chat action parameters */
45+ interface SendChatActionParams extends TelegramApiBaseParams {
46+ action : string ;
47+ }
48+
49+ /** Interface for callback query parameters */
50+ interface AnswerCallbackParams {
51+ callback_query_id : number | string ;
52+ text ?: string ;
53+ show_alert ?: boolean ;
54+ url ?: string ;
55+ cache_time ?: number ;
56+ }
57+
58+ /** Interface for inline query parameters */
59+ interface AnswerInlineParams {
60+ inline_query_id : number | string ;
61+ results : TelegramInlineQueryResultArticle [ ] | TelegramInlineQueryResultPhoto [ ] | TelegramInlineQueryResultVideo [ ] ;
62+ cache_time ?: number ;
63+ is_personal ?: boolean ;
64+ next_offset ?: string ;
65+ }
66+
67+ /** Type for all possible API parameters */
68+ type TelegramApiParams =
69+ | SendMessageParams
70+ | SendPhotoParams
71+ | SendVideoParams
72+ | SendChatActionParams
73+ | AnswerCallbackParams
74+ | AnswerInlineParams
75+ | Record < string , unknown > ;
76+
77+ /** Class representing the Telegram API and all its methods */
678export default class TelegramApi {
7- /**
8- * Get the API URL for a given bot API and slug
9- * @param botApi - full URL to the telegram API without slug
10- * @param slug - slug to append to the API URL
11- * @param data - data to append to the request
12- */
13- getApiUrl ( botApi : string , slug : string , data : Record < string , number | string | boolean > ) {
14- const request = new URL ( botApi + ( slug . startsWith ( '/' ) || botApi . endsWith ( '/' ) ? '' : '/' ) + slug ) ;
15- const params = new URLSearchParams ( ) ;
16- for ( const i in data ) {
17- params . append ( i , data [ i ] . toString ( ) ) ;
18- }
19- return new Request ( `${ request . toString ( ) } ?${ params . toString ( ) } ` ) ;
20- }
21-
22- async sendChatAction ( botApi : string , data : { business_connection_id ?: string ; chat_id : number | string ; action : string } ) {
23- const url = this . getApiUrl ( botApi , 'sendChatAction' , data ) ;
24- const response = await fetch ( url ) ;
25- return response ;
26- }
27-
28- /**
29- * Get a file with a given file_id
30- * @param botApi - full URL to the telegram API without slug
31- * @param data - data to append to the request
32- * @param token - bot token
33- */
34- async getFile ( botApi : string , data : Record < string , number | string | boolean > , token : string ) {
35- if ( data . file_id === '' ) {
36- return new Response ( ) ;
37- }
38- const url = this . getApiUrl ( botApi , 'getFile' , data ) ;
39- const response = await fetch ( url ) ;
40- const json : { result : { file_path : string } } = await response . json ( ) ;
41- let file_path : string ;
42- try {
43- file_path = json . result . file_path ;
44- } catch ( e ) {
45- console . log ( `Error: ${ e as string } ` ) ;
46- return new Response ( 'cant read file_path. is the file too large?' ) ;
47- }
48- return await fetch ( `https://api.telegram.org/file/bot${ token } /${ file_path } ` ) ;
49- }
50-
51- /**
52- * Send a message to a given botApi
53- * @param botApi - full URL to the telegram API without slug
54- * @param data - data to append to the request
55- */
56- async sendMessage (
57- botApi : string ,
58- data : {
59- reply_to_message_id ?: number | string ;
60- chat_id : number | string ;
61- text : string ;
62- parse_mode : string ;
63- business_connection_id ?: number | string ;
64- } ,
65- ) {
66- const url = this . getApiUrl ( botApi , 'sendMessage' , data ) ;
67- console . log ( url . url ) ;
68- return await fetch ( url ) ;
69- }
70-
71- /**
72- * Send a video message to a given botApi
73- * @param botApi - full URL to the telegram API without slug
74- * @param data - data to append to the request
75- */
76- async sendVideo (
77- botApi : string ,
78- data : {
79- reply_to_message_id : number | string ;
80- chat_id : number | string ;
81- video : string ;
82- } ,
83- ) {
84- const url = this . getApiUrl ( botApi , 'sendVideo' , data ) ;
85- return await fetch ( url ) ;
86- }
87-
88- /**
89- * Send a photo message to a given botApi
90- * @param botApi - full URL to the telegram API without slug
91- * @param data - data to append to the request
92- */
93- async sendPhoto (
94- botApi : string ,
95- data : {
96- reply_to_message_id : number | string ;
97- chat_id : number | string ;
98- photo : string ;
99- caption : string ;
100- } ,
101- ) {
102- const url = this . getApiUrl ( botApi , 'sendPhoto' , data ) ;
103- return await fetch ( url ) ;
104- }
105-
106- /**
107- * Send an inline response to a given botApi
108- * @param botApi - full URL to the telegram API without slug
109- * @param data - data to append to the request
110- */
111- async answerInline (
112- botApi : string ,
113- data : {
114- inline_query_id : number | string ;
115- results : TelegramInlineQueryResultArticle [ ] | TelegramInlineQueryResultPhoto [ ] | TelegramInlineQueryResultVideo [ ] ;
116- } ,
117- ) {
118- const url = this . getApiUrl ( botApi , 'answerInlineQuery' , {
119- inline_query_id : data . inline_query_id ,
120- results : JSON . stringify ( data . results ) ,
121- } ) ;
122- return await fetch ( url ) ;
123- }
124-
125- /**
126- * Send an callback response to a given botApi
127- * @param botApi - full URL to the telegram API without slug
128- * @param data - data to append to the request
129- */
130- async answerCallback (
131- botApi : string ,
132- data : {
133- callback_query_id : number | string ;
134- text ?: string ;
135- show_alert ?: boolean ;
136- url ?: string ;
137- cache_time ?: number ;
138- } ,
139- ) {
140- const url = this . getApiUrl ( botApi , 'answerCallbackQuery' , data ) ;
141- return await fetch ( url ) ;
142- }
79+ /**
80+ * Get the API URL for a given bot API and slug
81+ * @param botApi - full URL to the telegram API without slug
82+ * @param slug - slug to append to the API URL
83+ * @param data - data to append to the request
84+ * @returns Request object with the full URL and parameters
85+ */
86+ getApiUrl ( botApi : string , slug : string , data : TelegramApiParams ) : Request {
87+ const request = new URL ( botApi + ( slug . startsWith ( '/' ) || botApi . endsWith ( '/' ) ? '' : '/' ) + slug ) ;
88+ const params = new URLSearchParams ( ) ;
89+
90+ for ( const [ key , value ] of Object . entries ( data ) ) {
91+ if ( value !== undefined ) {
92+ params . append ( key , typeof value === 'object' && value !== null ? JSON . stringify ( value ) : String ( value ) ) ;
93+ }
94+ }
95+
96+ return new Request ( `${ request . toString ( ) } ?${ params . toString ( ) } ` ) ;
97+ }
98+
99+ /**
100+ * Send a chat action to indicate the bot is doing something
101+ * @param botApi - full URL to the telegram API without slug
102+ * @param data - data to append to the request
103+ * @returns Promise with the API response
104+ */
105+ async sendChatAction ( botApi : string , data : SendChatActionParams ) : Promise < Response > {
106+ const url = this . getApiUrl ( botApi , 'sendChatAction' , data ) ;
107+ return await fetch ( url ) ;
108+ }
109+
110+ /**
111+ * Get a file with a given file_id
112+ * @param botApi - full URL to the telegram API without slug
113+ * @param data - data to append to the request
114+ * @param token - bot token
115+ * @returns Promise with the file response
116+ */
117+ async getFile ( botApi : string , data : { file_id : string } & Record < string , number | string | boolean > , token : string ) : Promise < Response > {
118+ if ( ! data . file_id || data . file_id === '' ) {
119+ return new Response ( 'No file_id provided' , { status : 400 } ) ;
120+ }
121+
122+ try {
123+ const url = this . getApiUrl ( botApi , 'getFile' , data ) ;
124+ const response = await fetch ( url ) ;
125+
126+ if ( ! response . ok ) {
127+ return new Response ( `API error: ${ String ( response . status ) } ${ response . statusText } ` , { status : response . status } ) ;
128+ }
129+
130+ const json : { ok : boolean ; result ?: { file_path : string } ; description ?: string } = await response . json ( ) ;
131+
132+ if ( ! json . ok || ! json . result ?. file_path ) {
133+ return new Response ( json . description ?? 'Failed to get file path' , { status : 400 } ) ;
134+ }
135+
136+ return await fetch ( `https://api.telegram.org/file/bot${ token } /${ json . result . file_path } ` ) ;
137+ } catch ( e ) {
138+ console . error ( `Error in getFile: ${ e instanceof Error ? e . message : String ( e ) } ` ) ;
139+ return new Response ( `Error retrieving file: ${ e instanceof Error ? e . message : String ( e ) } ` , { status : 500 } ) ;
140+ }
141+ }
142+
143+ /**
144+ * Send a message to a given botApi
145+ * @param botApi - full URL to the telegram API without slug
146+ * @param data - data to append to the request
147+ * @returns Promise with the API response
148+ */
149+ async sendMessage ( botApi : string , data : SendMessageParams ) : Promise < Response > {
150+ const url = this . getApiUrl ( botApi , 'sendMessage' , data ) ;
151+ return await fetch ( url ) ;
152+ }
153+
154+ /**
155+ * Send a video message to a given botApi
156+ * @param botApi - full URL to the telegram API without slug
157+ * @param data - data to append to the request
158+ * @returns Promise with the API response
159+ */
160+ async sendVideo ( botApi : string , data : SendVideoParams ) : Promise < Response > {
161+ const url = this . getApiUrl ( botApi , 'sendVideo' , data ) ;
162+ return await fetch ( url ) ;
163+ }
164+
165+ /**
166+ * Send a photo message to a given botApi
167+ * @param botApi - full URL to the telegram API without slug
168+ * @param data - data to append to the request
169+ * @returns Promise with the API response
170+ */
171+ async sendPhoto ( botApi : string , data : SendPhotoParams ) : Promise < Response > {
172+ const url = this . getApiUrl ( botApi , 'sendPhoto' , data ) ;
173+ return await fetch ( url ) ;
174+ }
175+
176+ /**
177+ * Send an inline response to a given botApi
178+ * @param botApi - full URL to the telegram API without slug
179+ * @param data - data to append to the request
180+ * @returns Promise with the API response
181+ */
182+ async answerInline ( botApi : string , data : AnswerInlineParams ) : Promise < Response > {
183+ const url = this . getApiUrl ( botApi , 'answerInlineQuery' , {
184+ inline_query_id : data . inline_query_id ,
185+ results : data . results ,
186+ cache_time : data . cache_time ,
187+ is_personal : data . is_personal ,
188+ next_offset : data . next_offset ,
189+ } ) ;
190+ return await fetch ( url ) ;
191+ }
192+
193+ /**
194+ * Send a callback response to a given botApi
195+ * @param botApi - full URL to the telegram API without slug
196+ * @param data - data to append to the request
197+ * @returns Promise with the API response
198+ */
199+ async answerCallback ( botApi : string , data : AnswerCallbackParams ) : Promise < Response > {
200+ const url = this . getApiUrl ( botApi , 'answerCallbackQuery' , data ) ;
201+ return await fetch ( url ) ;
202+ }
203+
204+ /**
205+ * Delete a message
206+ * @param botApi - full URL to the telegram API without slug
207+ * @param data - data to append to the request
208+ * @returns Promise with the API response
209+ */
210+ async deleteMessage ( botApi : string , data : { chat_id : number | string ; message_id : number } ) : Promise < Response > {
211+ const url = this . getApiUrl ( botApi , 'deleteMessage' , data ) ;
212+ return await fetch ( url ) ;
213+ }
214+
215+ /**
216+ * Edit a message text
217+ * @param botApi - full URL to the telegram API without slug
218+ * @param data - data to append to the request
219+ * @returns Promise with the API response
220+ */
221+ async editMessageText (
222+ botApi : string ,
223+ data : {
224+ chat_id ?: number | string ;
225+ message_id ?: number ;
226+ inline_message_id ?: string ;
227+ text : string ;
228+ parse_mode ?: string ;
229+ disable_web_page_preview ?: boolean ;
230+ reply_markup ?: object ;
231+ } ,
232+ ) : Promise < Response > {
233+ const url = this . getApiUrl ( botApi , 'editMessageText' , data ) ;
234+ return await fetch ( url ) ;
235+ }
143236}
0 commit comments