nyx-bot-client 0.0.2

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.
Files changed (288) hide show
  1. package/.env.sample +4 -0
  2. package/.vscode/extensions.json +11 -0
  3. package/.vscode/settings.json +17 -0
  4. package/.zed/settings.json +20 -0
  5. package/@types/AcceptedGiftTypes.ts +26 -0
  6. package/@types/AffiliateInfo.ts +35 -0
  7. package/@types/Animation.ts +56 -0
  8. package/@types/Audio.ts +56 -0
  9. package/@types/BackgroundFill.ts +18 -0
  10. package/@types/BackgroundFillFreeformGradient.ts +16 -0
  11. package/@types/BackgroundFillGradient.ts +26 -0
  12. package/@types/BackgroundFillSolid.ts +16 -0
  13. package/@types/BackgroundType.ts +21 -0
  14. package/@types/BackgroundTypeChatTheme.ts +16 -0
  15. package/@types/BackgroundTypeFill.ts +23 -0
  16. package/@types/BackgroundTypePattern.ts +40 -0
  17. package/@types/BackgroundTypeWallpaper.ts +33 -0
  18. package/@types/Birthdate.ts +21 -0
  19. package/@types/BotCommand.ts +16 -0
  20. package/@types/BotCommandScope.ts +30 -0
  21. package/@types/BotCommandScopeAllChatAdministrators.ts +11 -0
  22. package/@types/BotCommandScopeAllGroupChats.ts +11 -0
  23. package/@types/BotCommandScopeAllPrivateChats.ts +11 -0
  24. package/@types/BotCommandScopeChat.ts +16 -0
  25. package/@types/BotCommandScopeChatAdministrators.ts +16 -0
  26. package/@types/BotCommandScopeChatMember.ts +21 -0
  27. package/@types/BotCommandScopeDefault.ts +12 -0
  28. package/@types/BotDescription.ts +11 -0
  29. package/@types/BotName.ts +11 -0
  30. package/@types/BotShortDescription.ts +11 -0
  31. package/@types/BusinessBotRights.ts +65 -0
  32. package/@types/BusinessConnection.ts +41 -0
  33. package/@types/BusinessIntro.ts +23 -0
  34. package/@types/BusinessLocation.ts +18 -0
  35. package/@types/BusinessMessagesDeleted.ts +24 -0
  36. package/@types/BusinessOpeningHours.ts +18 -0
  37. package/@types/BusinessOpeningHoursInterval.ts +18 -0
  38. package/@types/CallbackGame.ts +6 -0
  39. package/@types/CallbackQuery.ts +49 -0
  40. package/@types/Chat.ts +43 -0
  41. package/@types/ChatAdministratorRights.ts +84 -0
  42. package/@types/ChatBackground.ts +13 -0
  43. package/@types/ChatBoost.ts +29 -0
  44. package/@types/ChatBoostAdded.ts +11 -0
  45. package/@types/ChatBoostRemoved.ts +28 -0
  46. package/@types/ChatBoostSource.ts +18 -0
  47. package/@types/ChatBoostSourceGiftCode.ts +19 -0
  48. package/@types/ChatBoostSourceGiveaway.ts +35 -0
  49. package/@types/ChatBoostSourcePremium.ts +19 -0
  50. package/@types/ChatBoostUpdated.ts +18 -0
  51. package/@types/ChatFullInfo.ts +260 -0
  52. package/@types/ChatInviteLink.ts +66 -0
  53. package/@types/ChatJoinRequest.ts +42 -0
  54. package/@types/ChatLocation.ts +16 -0
  55. package/@types/ChatMember.ts +28 -0
  56. package/@types/ChatMemberAdministrator.ts +107 -0
  57. package/@types/ChatMemberBanned.ts +23 -0
  58. package/@types/ChatMemberLeft.ts +18 -0
  59. package/@types/ChatMemberMember.ts +23 -0
  60. package/@types/ChatMemberOwner.ts +28 -0
  61. package/@types/ChatMemberRestricted.ts +99 -0
  62. package/@types/ChatMemberUpdated.ts +49 -0
  63. package/@types/ChatPermissions.ts +78 -0
  64. package/@types/ChatPhoto.ts +30 -0
  65. package/@types/ChatShared.ts +36 -0
  66. package/@types/Checklist.ts +33 -0
  67. package/@types/ChecklistTask.ts +33 -0
  68. package/@types/ChecklistTasksAdded.ts +19 -0
  69. package/@types/ChecklistTasksDone.ts +24 -0
  70. package/@types/ChosenInlineResult.ts +34 -0
  71. package/@types/Contact.ts +33 -0
  72. package/@types/CopyTextButton.ts +11 -0
  73. package/@types/Dice.ts +17 -0
  74. package/@types/DirectMessagePriceChanged.ts +17 -0
  75. package/@types/Document.ts +41 -0
  76. package/@types/EncryptedCredentials.ts +23 -0
  77. package/@types/EncryptedPassportElement.ts +357 -0
  78. package/@types/ExternalReplyInfo.ts +159 -0
  79. package/@types/File.ts +33 -0
  80. package/@types/ForceReply.ts +26 -0
  81. package/@types/ForumTopic.ts +26 -0
  82. package/@types/ForumTopicClosed.ts +6 -0
  83. package/@types/ForumTopicCreated.ts +21 -0
  84. package/@types/ForumTopicEdited.ts +17 -0
  85. package/@types/ForumTopicReopened.ts +6 -0
  86. package/@types/Game.ts +41 -0
  87. package/@types/GameHighScore.ts +23 -0
  88. package/@types/GeneralForumTopicHidden.ts +7 -0
  89. package/@types/GeneralForumTopicUnhidden.ts +7 -0
  90. package/@types/Gift.ts +38 -0
  91. package/@types/GiftInfo.ts +52 -0
  92. package/@types/Gifts.ts +13 -0
  93. package/@types/Giveaway.ts +55 -0
  94. package/@types/GiveawayCompleted.ts +29 -0
  95. package/@types/GiveawayCreated.ts +11 -0
  96. package/@types/GiveawayWinners.ts +68 -0
  97. package/@types/InaccessibleMessage.ts +23 -0
  98. package/@types/InlineKeyboardButton.ts +88 -0
  99. package/@types/InlineKeyboardMarkup.ts +13 -0
  100. package/@types/InlineQuery.ts +41 -0
  101. package/@types/InlineQueryResult.ts +70 -0
  102. package/@types/InlineQueryResultArticle.ts +58 -0
  103. package/@types/InlineQueryResultAudio.ts +69 -0
  104. package/@types/InlineQueryResultCachedAudio.ts +55 -0
  105. package/@types/InlineQueryResultCachedDocument.ts +65 -0
  106. package/@types/InlineQueryResultCachedGif.ts +65 -0
  107. package/@types/InlineQueryResultCachedMpeg4Gif.ts +65 -0
  108. package/@types/InlineQueryResultCachedPhoto.ts +70 -0
  109. package/@types/InlineQueryResultCachedSticker.ts +34 -0
  110. package/@types/InlineQueryResultCachedVideo.ts +70 -0
  111. package/@types/InlineQueryResultCachedVoice.ts +60 -0
  112. package/@types/InlineQueryResultContact.ts +64 -0
  113. package/@types/InlineQueryResultDocument.ts +85 -0
  114. package/@types/InlineQueryResultGame.ts +29 -0
  115. package/@types/InlineQueryResultGif.ts +91 -0
  116. package/@types/InlineQueryResultLocation.ts +82 -0
  117. package/@types/InlineQueryResultMpeg4Gif.ts +91 -0
  118. package/@types/InlineQueryResultPhoto.ts +84 -0
  119. package/@types/InlineQueryResultVenue.ts +80 -0
  120. package/@types/InlineQueryResultVideo.ts +98 -0
  121. package/@types/InlineQueryResultVoice.ts +65 -0
  122. package/@types/InlineQueryResultsButton.ts +34 -0
  123. package/@types/InputChecklist.ts +39 -0
  124. package/@types/InputChecklistTask.ts +30 -0
  125. package/@types/InputContactMessageContent.ts +27 -0
  126. package/@types/InputFile.ts +10 -0
  127. package/@types/InputInvoiceMessageContent.ts +120 -0
  128. package/@types/InputLocationMessageContent.ts +39 -0
  129. package/@types/InputMedia.ts +24 -0
  130. package/@types/InputMediaAnimation.ts +68 -0
  131. package/@types/InputMediaAudio.ts +58 -0
  132. package/@types/InputMediaDocument.ts +49 -0
  133. package/@types/InputMediaPhoto.ts +45 -0
  134. package/@types/InputMediaVideo.ts +85 -0
  135. package/@types/InputMessageContent.ts +25 -0
  136. package/@types/InputPaidMedia.ts +11 -0
  137. package/@types/InputPaidMediaPhoto.ts +21 -0
  138. package/@types/InputPaidMediaVideo.ts +64 -0
  139. package/@types/InputPollOption.ts +25 -0
  140. package/@types/InputProfilePhoto.ts +10 -0
  141. package/@types/InputProfilePhotoAnimated.ts +23 -0
  142. package/@types/InputProfilePhotoStatic.ts +18 -0
  143. package/@types/InputSticker.ts +38 -0
  144. package/@types/InputStoryContent.ts +11 -0
  145. package/@types/InputStoryContentPhoto.ts +29 -0
  146. package/@types/InputStoryContentVideo.ts +49 -0
  147. package/@types/InputTextMessageContent.ts +28 -0
  148. package/@types/InputVenueMessageContent.ts +47 -0
  149. package/@types/Invoice.ts +35 -0
  150. package/@types/KeyboardButton.ts +61 -0
  151. package/@types/KeyboardButtonPollType.ts +13 -0
  152. package/@types/KeyboardButtonRequestChat.ts +68 -0
  153. package/@types/KeyboardButtonRequestUsers.ts +45 -0
  154. package/@types/LabeledPrice.ts +18 -0
  155. package/@types/LinkPreviewOptions.ts +32 -0
  156. package/@types/Location.ts +38 -0
  157. package/@types/LocationAddress.ts +26 -0
  158. package/@types/LoginUrl.ts +37 -0
  159. package/@types/MaskPosition.ts +28 -0
  160. package/@types/MaybeInaccessibleMessage.ts +8 -0
  161. package/@types/MenuButton.ts +20 -0
  162. package/@types/MenuButtonCommands.ts +11 -0
  163. package/@types/MenuButtonDefault.ts +11 -0
  164. package/@types/MenuButtonWebApp.ts +26 -0
  165. package/@types/Message.ts +608 -0
  166. package/@types/MessageAutoDeleteTimerChanged.ts +11 -0
  167. package/@types/MessageEntity.ts +109 -0
  168. package/@types/MessageId.ts +11 -0
  169. package/@types/MessageOrigin.ts +21 -0
  170. package/@types/MessageOriginChannel.ts +33 -0
  171. package/@types/MessageOriginChat.ts +28 -0
  172. package/@types/MessageOriginHiddenUser.ts +21 -0
  173. package/@types/MessageOriginUser.ts +23 -0
  174. package/@types/MessageReactionCountUpdated.ts +28 -0
  175. package/@types/MessageReactionUpdated.ts +43 -0
  176. package/@types/OrderInfo.ts +28 -0
  177. package/@types/OwnedGift.ts +11 -0
  178. package/@types/OwnedGiftRegular.ts +77 -0
  179. package/@types/OwnedGiftUnique.ts +57 -0
  180. package/@types/OwnedGifts.ts +23 -0
  181. package/@types/PaidMedia.ts +13 -0
  182. package/@types/PaidMediaInfo.ts +18 -0
  183. package/@types/PaidMediaPhoto.ts +18 -0
  184. package/@types/PaidMediaPreview.ts +26 -0
  185. package/@types/PaidMediaPurchased.ts +18 -0
  186. package/@types/PaidMediaVideo.ts +18 -0
  187. package/@types/PaidMessagePriceChanged.ts +16 -0
  188. package/@types/PassportData.ts +18 -0
  189. package/@types/PassportElementError.ts +37 -0
  190. package/@types/PassportElementErrorDataField.ts +39 -0
  191. package/@types/PassportElementErrorFile.ts +33 -0
  192. package/@types/PassportElementErrorFiles.ts +33 -0
  193. package/@types/PassportElementErrorFrontSide.ts +28 -0
  194. package/@types/PassportElementErrorReverseSide.ts +27 -0
  195. package/@types/PassportElementErrorSelfie.ts +28 -0
  196. package/@types/PassportElementErrorTranslationFile.ts +38 -0
  197. package/@types/PassportElementErrorTranslationFiles.ts +38 -0
  198. package/@types/PassportElementErrorUnspecified.ts +49 -0
  199. package/@types/PassportFile.ts +28 -0
  200. package/@types/PhotoSize.ts +32 -0
  201. package/@types/Poll.ts +81 -0
  202. package/@types/PollAnswer.ts +28 -0
  203. package/@types/PollOption.ts +24 -0
  204. package/@types/PreCheckoutQuery.ts +45 -0
  205. package/@types/ProximityAlertTriggered.ts +24 -0
  206. package/@types/ReactionCount.ts +18 -0
  207. package/@types/ReactionType.ts +18 -0
  208. package/@types/ReactionTypeCustomEmoji.ts +16 -0
  209. package/@types/ReactionTypeEmoji.ts +92 -0
  210. package/@types/ReactionTypePaid.ts +11 -0
  211. package/@types/RefundedPayment.ts +35 -0
  212. package/@types/ReplyKeyboardMarkup.ts +49 -0
  213. package/@types/ReplyKeyboardRemove.ts +25 -0
  214. package/@types/ReplyParameters.ts +48 -0
  215. package/@types/ResponseParameters.ts +19 -0
  216. package/@types/RevenueWithdrawalState.ts +13 -0
  217. package/@types/RevenueWithdrawalStateFailed.ts +11 -0
  218. package/@types/RevenueWithdrawalStatePending.ts +10 -0
  219. package/@types/RevenueWithdrawalStateSucceeded.ts +21 -0
  220. package/@types/SentWebAppMessage.ts +12 -0
  221. package/@types/SharedUser.ts +36 -0
  222. package/@types/ShippingAddress.ts +36 -0
  223. package/@types/ShippingOption.ts +23 -0
  224. package/@types/ShippingQuery.ts +28 -0
  225. package/@types/StarAmount.ts +17 -0
  226. package/@types/StarTransaction.ts +42 -0
  227. package/@types/StarTransactions.ts +13 -0
  228. package/@types/Sticker.ts +86 -0
  229. package/@types/StickerSet.ts +33 -0
  230. package/@types/Story.ts +18 -0
  231. package/@types/StoryArea.ts +18 -0
  232. package/@types/StoryAreaPosition.ts +36 -0
  233. package/@types/StoryAreaType.ts +24 -0
  234. package/@types/StoryAreaTypeLink.ts +16 -0
  235. package/@types/StoryAreaTypeLocation.ts +28 -0
  236. package/@types/StoryAreaTypeSuggestedReaction.ts +29 -0
  237. package/@types/StoryAreaTypeUniqueGift.ts +16 -0
  238. package/@types/StoryAreaTypeWeather.ts +26 -0
  239. package/@types/SuccessfulPayment.ts +60 -0
  240. package/@types/SwitchInlineQueryChosenChat.ts +33 -0
  241. package/@types/TextQuote.ts +30 -0
  242. package/@types/TransactionPartner.ts +31 -0
  243. package/@types/TransactionPartnerAffiliateProgram.ts +24 -0
  244. package/@types/TransactionPartnerChat.ts +21 -0
  245. package/@types/TransactionPartnerFragment.ts +18 -0
  246. package/@types/TransactionPartnerOther.ts +11 -0
  247. package/@types/TransactionPartnerTelegramAds.ts +11 -0
  248. package/@types/TransactionPartnerTelegramApi.ts +16 -0
  249. package/@types/TransactionPartnerUser.ts +70 -0
  250. package/@types/UniqueGift.ts +38 -0
  251. package/@types/UniqueGiftBackdrop.ts +23 -0
  252. package/@types/UniqueGiftBackdropColors.ts +26 -0
  253. package/@types/UniqueGiftInfo.ts +42 -0
  254. package/@types/UniqueGiftModel.ts +23 -0
  255. package/@types/UniqueGiftSymbol.ts +23 -0
  256. package/@types/Update.ts +177 -0
  257. package/@types/User.ts +74 -0
  258. package/@types/UserProfilePhotos.ts +18 -0
  259. package/@types/UsersShared.ts +19 -0
  260. package/@types/Venue.ts +48 -0
  261. package/@types/Video.ts +66 -0
  262. package/@types/VideoChatEnded.ts +11 -0
  263. package/@types/VideoChatParticipantsInvited.ts +13 -0
  264. package/@types/VideoChatScheduled.ts +11 -0
  265. package/@types/VideoChatStarted.ts +6 -0
  266. package/@types/VideoNote.ts +39 -0
  267. package/@types/Voice.ts +34 -0
  268. package/@types/WebAppData.ts +17 -0
  269. package/@types/WebAppInfo.ts +11 -0
  270. package/@types/WebhookInfo.ts +54 -0
  271. package/@types/WriteAccessAllowed.ts +23 -0
  272. package/@types/index.ts +395 -0
  273. package/@types/utils.ts +17 -0
  274. package/biome.json +58 -0
  275. package/bun.lock +105 -0
  276. package/cron/actions-server.ts +87 -0
  277. package/index.ts +9 -0
  278. package/nyx-client.ts +133 -0
  279. package/package.json +22 -0
  280. package/tsconfig.json +28 -0
  281. package/types.d.ts +35 -0
  282. package/utils/actions.ts +30 -0
  283. package/utils/api.ts +27 -0
  284. package/utils/enum.ts +5 -0
  285. package/utils/helpers.ts +71 -0
  286. package/utils/methods.ts +1943 -0
  287. package/utils/objects.ts +37 -0
  288. package/utils/table.ts +72 -0
@@ -0,0 +1,87 @@
1
+ // Cron: @reboot
2
+
3
+ import dotenv from "dotenv";
4
+ import { Kysely, MysqlDialect } from "kysely";
5
+ import { createPool } from "mysql2";
6
+ import { createClient } from "redis";
7
+ import z from "zod";
8
+ import type { NyxAction } from "../utils/actions";
9
+ import * as methods from "../utils/methods";
10
+
11
+ const envScheme = z.object({
12
+ BROKER_MYSQL_USER: z.string().nonempty(),
13
+ BROKER_MYSQL_NAME: z.string().nonempty(),
14
+ BROKER_MYSQL_PASS: z.string().nonempty(),
15
+ BROKER_MYSQL_HOST: z.string().nonempty(),
16
+ });
17
+
18
+ const env: z.infer<typeof envScheme> = envScheme.parse(
19
+ dotenv.config({
20
+ path: `${__dirname}/../.env`,
21
+ quiet: true,
22
+ }).parsed,
23
+ );
24
+
25
+ const mysql = createPool({
26
+ user: env.BROKER_MYSQL_USER,
27
+ database: env.BROKER_MYSQL_NAME,
28
+ password: env.BROKER_MYSQL_PASS,
29
+ host: env.BROKER_MYSQL_HOST,
30
+ maxIdle: 2,
31
+ idleTimeout: 120_000,
32
+ });
33
+
34
+ const db = new Kysely<{
35
+ actions: {
36
+ id?: number;
37
+ params: NyxAction;
38
+ date: number;
39
+ };
40
+ }>({
41
+ dialect: new MysqlDialect({
42
+ pool: mysql,
43
+ }),
44
+ });
45
+
46
+ const redis = createClient();
47
+ await redis.connect();
48
+
49
+ redis.subscribe("nyx-action", async (input) => {
50
+ try {
51
+ const data: NyxAction = JSON.parse(input);
52
+
53
+ await db
54
+ .insertInto("actions")
55
+ .values({
56
+ params: JSON.stringify(data) as any,
57
+ date: data.date,
58
+ })
59
+ .execute();
60
+ } catch (e) {
61
+ console.error(e);
62
+ }
63
+ });
64
+
65
+ setInterval(async () => {
66
+ const tasks = await db
67
+ .selectFrom("actions")
68
+ .selectAll()
69
+ .where("date", "<=", Math.trunc(Date.now() / 1000))
70
+ .execute();
71
+
72
+ if (tasks.length > 0) {
73
+ await db
74
+ .deleteFrom("actions")
75
+ .where("date", "<=", Math.trunc(Date.now() / 1000))
76
+ .execute();
77
+
78
+ for (const task of tasks) {
79
+ const params: NyxAction = JSON.parse(task.params as any);
80
+
81
+ methods[params.type]({
82
+ bot_token: params.bot_token,
83
+ ...params.params,
84
+ } as any);
85
+ }
86
+ }
87
+ }, 60_000);
package/index.ts ADDED
@@ -0,0 +1,9 @@
1
+ export type * from "./@types/index.ts";
2
+ export * from "./nyx-client.ts";
3
+ export type * from "./types.d.ts";
4
+ export * from "./utils/actions.ts";
5
+ export * from "./utils/api.ts";
6
+ export * from "./utils/enum.ts";
7
+ export * from "./utils/helpers.ts";
8
+ export * from "./utils/methods.ts";
9
+ export * from "./utils/table.ts";
package/nyx-client.ts ADDED
@@ -0,0 +1,133 @@
1
+ import { createClient } from "redis";
2
+ import { z } from "zod";
3
+ import type { EventTypes } from "./@types";
4
+ import type {
5
+ BotConfig,
6
+ BotInjections,
7
+ BotPipelines,
8
+ SubscribeCallback,
9
+ } from "./types";
10
+ import { NyxResponse } from "./utils/enum";
11
+ import { encodeHTMLEntities } from "./utils/helpers";
12
+ import { sendMessage } from "./utils/methods";
13
+
14
+ type NyxConfig = {
15
+ botConfig: BotConfig;
16
+ pipelines: BotPipelines;
17
+ injections?: BotInjections;
18
+ onStartup?: () => Promise<void>;
19
+ onShutdown?: () => Promise<void>;
20
+ benchmark?: boolean;
21
+ };
22
+
23
+ class NyxClient {
24
+ public botConfig: BotConfig | undefined;
25
+ public pipelines: BotPipelines = {};
26
+ public subscriptions: { [key: string]: SubscribeCallback } = {};
27
+ public injections: BotInjections | undefined;
28
+ public benchmark: boolean | undefined;
29
+
30
+ private redis = createClient();
31
+
32
+ public async initialize(config: NyxConfig) {
33
+ this.botConfig = z
34
+ .object({
35
+ username: z.string().nonempty(),
36
+ token: z.string().nonempty(),
37
+ api: z.string().default("https://api.telegram.org"),
38
+ admin_id: z.coerce.number().optional(),
39
+ })
40
+ .parse(config.botConfig);
41
+ this.pipelines = config.pipelines;
42
+ this.injections = config.injections;
43
+ this.benchmark = config.benchmark;
44
+
45
+ await this.redis.connect();
46
+ this.redis.subscribe(
47
+ this.botConfig.username,
48
+ this.handleUpdateRequest.bind(this),
49
+ );
50
+
51
+ config.onStartup?.();
52
+
53
+ process.on("SIGTERM", async () => {
54
+ await config.onShutdown?.();
55
+ process.exit(0);
56
+ });
57
+ }
58
+
59
+ public async handleUpdateRequest(update: string | object) {
60
+ if (this.benchmark) {
61
+ console.time("benchmark-request");
62
+ }
63
+
64
+ const inject = await this.injections?.();
65
+
66
+ try {
67
+ const data = typeof update === "string" ? JSON.parse(update) : update;
68
+
69
+ if ("update_id" in data) {
70
+ delete data.update_id;
71
+ const update_type: keyof EventTypes = Object.keys(data)[0] as any;
72
+
73
+ if (!this.pipelines[update_type]) return;
74
+
75
+ for (const handler of this.pipelines[update_type]) {
76
+ const result = await handler(data[update_type], inject?.injections);
77
+
78
+ if (result === NyxResponse.Finish) {
79
+ break;
80
+ }
81
+ }
82
+ } else if ("type" in data && "data" in data) {
83
+ for (const type in this.subscriptions) {
84
+ if (data.type === type) {
85
+ this.subscriptions[type]!(data.data);
86
+ break;
87
+ }
88
+ }
89
+ }
90
+ } catch (e: any) {
91
+ console.error(e);
92
+
93
+ if (this.botConfig?.admin_id) {
94
+ sendMessage({
95
+ chat_id: this.botConfig?.admin_id,
96
+ text: `🚫 <b>Error Reporting</b>\n\n<pre>${encodeHTMLEntities(e.stack || e.toString())}</pre>`,
97
+ });
98
+ }
99
+ } finally {
100
+ await inject?.onFinish?.();
101
+ }
102
+
103
+ if (this.benchmark) {
104
+ console.timeEnd("benchmark-request");
105
+
106
+ console.log(
107
+ "Memory Usage:",
108
+ Object.fromEntries(
109
+ Object.entries(process.memoryUsage()).map(([k, v]) => [
110
+ k,
111
+ `${Math.trunc((v / 1024 / 1024) * 100) / 100}MB`,
112
+ ]),
113
+ ),
114
+ );
115
+
116
+ console.log("------------------------------");
117
+ }
118
+ }
119
+
120
+ public subscribe(event: string, callback: SubscribeCallback) {
121
+ this.subscriptions[event] = callback;
122
+ }
123
+
124
+ public unsubscribe(event: string) {
125
+ if (event in this.subscriptions) {
126
+ delete this.subscriptions[event];
127
+ }
128
+ }
129
+ }
130
+
131
+ const client = new NyxClient();
132
+
133
+ export default client;
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "nyx-bot-client",
3
+ "version": "0.0.2",
4
+ "module": "index.ts",
5
+ "type": "module",
6
+ "devDependencies": {
7
+ "@types/bun": "latest"
8
+ },
9
+ "peerDependencies": {
10
+ "typescript": "^5"
11
+ },
12
+ "dependencies": {
13
+ "@biomejs/biome": "^2.2.4",
14
+ "@types/node": "^24.5.2",
15
+ "dotenv": "^17.2.2",
16
+ "kysely": "^0.28.7",
17
+ "mysql2": "^3.15.0",
18
+ "redis": "^5.8.2",
19
+ "ts-debounce": "^4.0.0",
20
+ "zod": "^4.1.9"
21
+ }
22
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "compilerOptions": {
3
+ // Environment setup & latest features
4
+ "lib": ["ESNext"],
5
+ "target": "ESNext",
6
+ "module": "ESNext",
7
+ "moduleDetection": "force",
8
+ "jsx": "react-jsx",
9
+ "allowJs": true,
10
+
11
+ // Bundler mode
12
+ "moduleResolution": "bundler",
13
+ "allowImportingTsExtensions": true,
14
+ "verbatimModuleSyntax": true,
15
+ "noEmit": true,
16
+
17
+ // Best practices
18
+ "strict": true,
19
+ "skipLibCheck": true,
20
+ "noFallthroughCasesInSwitch": true,
21
+ "noUncheckedIndexedAccess": true,
22
+
23
+ // Some stricter flags (disabled by default)
24
+ "noUnusedLocals": false,
25
+ "noUnusedParameters": false,
26
+ "noPropertyAccessFromIndexSignature": false
27
+ }
28
+ }
package/types.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ import type { Kysely } from "kysely";
2
+ import type { Connection, Pool } from "mysql2";
3
+ import type { RedisClientType } from "redis";
4
+ import type { EventTypes } from "./@types";
5
+ import type { NyxResponse } from "./utils/enum";
6
+
7
+ export type BotConfig = {
8
+ username: string;
9
+ token: string;
10
+ api?: string;
11
+ admin_id?: number;
12
+ };
13
+
14
+ export type BotPipeline<K extends keyof EventTypes, T> = (
15
+ data: EventTypes[K],
16
+ injections?: Injections<T>,
17
+ ) => Promise<NyxResponse>;
18
+
19
+ export type BotPipelines = {
20
+ [K in keyof EventTypes]?: BotPipeline<K>[];
21
+ };
22
+
23
+ export type SubscribeCallback = (params: any) => void;
24
+
25
+ export type BotInjections = () => Promise<{
26
+ injections: Injections;
27
+ onFinish?: () => Promise<void>;
28
+ }>;
29
+
30
+ export type Injections<T> = {
31
+ mysql?: Connection | Pool;
32
+ redis?: RedisClientType;
33
+ db?: Kysely<T>;
34
+ [key: string]: any;
35
+ };
@@ -0,0 +1,30 @@
1
+ import { createClient, type RedisClientType } from "redis";
2
+ import type * as methods from "./methods.ts";
3
+
4
+ type MethodName = keyof typeof methods;
5
+
6
+ type ParamsOf<T extends MethodName> = T extends MethodName
7
+ ? Parameters<(typeof methods)[T]>[0]
8
+ : never;
9
+
10
+ export type NyxAction<T extends MethodName = MethodName> = {
11
+ type: T;
12
+ params: ParamsOf<T>;
13
+ date: number;
14
+ bot_token: string;
15
+ bot_api_server?: string;
16
+ redis?: RedisClientType;
17
+ };
18
+
19
+ export const actionBroker = async <T extends MethodName>(
20
+ action: NyxAction<T>,
21
+ ) => {
22
+ if (action.redis) {
23
+ await action.redis.publish("nyx-action", JSON.stringify(action));
24
+ } else {
25
+ const redis = createClient();
26
+ await redis.connect();
27
+ await redis.publish("nyx-action", JSON.stringify(action));
28
+ await redis.close();
29
+ }
30
+ };
package/utils/api.ts ADDED
@@ -0,0 +1,27 @@
1
+ import client from "../nyx-client";
2
+
3
+ export const requestTelegramAPI = async (
4
+ method: string,
5
+ params: any,
6
+ ): Promise<any> => {
7
+ const token = params.bot_token ?? client.botConfig!.token;
8
+ const api =
9
+ params.bot_api_server ??
10
+ client.botConfig?.api ??
11
+ "https://api.telegram.org";
12
+ const request_method = params.request_method ?? "POST";
13
+
14
+ delete params.bot_token;
15
+ delete params.bot_api_server;
16
+ delete params.request_method;
17
+
18
+ const request = await fetch(`${api}/bot${token}/${method}`, {
19
+ method: request_method,
20
+ body: JSON.stringify(params),
21
+ headers: {
22
+ "Content-Type": "application/json",
23
+ },
24
+ });
25
+
26
+ return await request.json();
27
+ };
package/utils/enum.ts ADDED
@@ -0,0 +1,5 @@
1
+ export const NyxResponse = {
2
+ Ok: 200,
3
+ Finish: 299,
4
+ Error: 500,
5
+ };
@@ -0,0 +1,71 @@
1
+ import {
2
+ getChatMember,
3
+ type getChatMemberParams,
4
+ type methodParams,
5
+ } from "./methods";
6
+
7
+ export const isUserMemberOf = async (params: getChatMemberParams) => {
8
+ const result = await getChatMember(params);
9
+
10
+ if (result.ok) {
11
+ return !["left", "kicked"].includes(result.result.status);
12
+ }
13
+
14
+ return false;
15
+ };
16
+
17
+ export const isUserAdminOf = async (params: getChatMemberParams) => {
18
+ const result = await getChatMember(params);
19
+
20
+ if (result.ok) {
21
+ return ["creator", "administrator"].includes(result.result.status);
22
+ }
23
+
24
+ return false;
25
+ };
26
+
27
+ export const mentionUserEntity = (text: string, user_id: number) =>
28
+ `<a href='tg://user?id=${user_id}'>${text}</a>`;
29
+
30
+ export type SponsorChat = {
31
+ chat_id: number;
32
+ username?: string;
33
+ title?: string;
34
+ };
35
+
36
+ export type getRemainingSponsorChatsParams = {
37
+ user_id: number;
38
+ sponsors: SponsorChat[];
39
+ } & methodParams;
40
+
41
+ export const getRemainingSponsorChats = async (
42
+ params: getRemainingSponsorChatsParams,
43
+ ) => {
44
+ const result = await Promise.all(
45
+ params.sponsors.map(
46
+ (sponsor) =>
47
+ new Promise<[boolean, SponsorChat]>((resolve) => {
48
+ isUserMemberOf({
49
+ chat_id: sponsor.chat_id,
50
+ user_id: params.user_id,
51
+ bot_api_server: params.bot_api_server,
52
+ bot_token: params.bot_token,
53
+ })
54
+ .then((result) => {
55
+ resolve([result, sponsor]);
56
+ })
57
+ .catch(() => {
58
+ resolve([false, sponsor]);
59
+ });
60
+ }),
61
+ ),
62
+ );
63
+
64
+ return result.filter(([joined]) => !joined).map(([, sponsor]) => sponsor);
65
+ };
66
+
67
+ export const encodeHTMLEntities = (str: string): string => {
68
+ return str.replace(/[\u00A0-\u9999<>&"'`]/g, (char) => {
69
+ return `&#${char.charCodeAt(0)};`;
70
+ });
71
+ };