apexify.js 3.2.5 → 3.3.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.
Files changed (75) hide show
  1. package/.tsbuildinfo +1 -1
  2. package/README.md +4 -802
  3. package/change logs.md +19 -0
  4. package/dist/ai/ApexAI.d.ts +15 -6
  5. package/dist/ai/ApexAI.d.ts.map +1 -1
  6. package/dist/ai/ApexAI.js +102 -29
  7. package/dist/ai/ApexAI.js.map +1 -1
  8. package/dist/ai/buttons/tools.d.ts.map +1 -1
  9. package/dist/ai/buttons/tools.js +1 -1
  10. package/dist/ai/buttons/tools.js.map +1 -1
  11. package/dist/ai/functions/aivoice.d.ts +1 -0
  12. package/dist/ai/functions/aivoice.d.ts.map +1 -0
  13. package/dist/ai/functions/aivoice.js +2 -0
  14. package/dist/ai/functions/aivoice.js.map +1 -0
  15. package/dist/ai/functions/draw.d.ts +1 -1
  16. package/dist/ai/functions/draw.d.ts.map +1 -1
  17. package/dist/ai/functions/draw.js +12 -1
  18. package/dist/ai/functions/draw.js.map +1 -1
  19. package/dist/ai/functions/generateVoiceResponse.d.ts +1 -1
  20. package/dist/ai/functions/generateVoiceResponse.d.ts.map +1 -1
  21. package/dist/ai/functions/generateVoiceResponse.js +3 -3
  22. package/dist/ai/functions/generateVoiceResponse.js.map +1 -1
  23. package/dist/ai/models.d.ts +1 -1
  24. package/dist/ai/models.d.ts.map +1 -1
  25. package/dist/ai/models.js +46 -28
  26. package/dist/ai/models.js.map +1 -1
  27. package/dist/ai/utils.d.ts.map +1 -1
  28. package/dist/ai/utils.js.map +1 -1
  29. package/dist/canvas/ApexPainter.d.ts +10 -10
  30. package/dist/canvas/ApexPainter.d.ts.map +1 -1
  31. package/dist/canvas/ApexPainter.js +21 -26
  32. package/dist/canvas/ApexPainter.js.map +1 -1
  33. package/dist/canvas/utils/bg.d.ts +1 -2
  34. package/dist/canvas/utils/bg.d.ts.map +1 -1
  35. package/dist/canvas/utils/bg.js +2 -5
  36. package/dist/canvas/utils/bg.js.map +1 -1
  37. package/dist/canvas/utils/charts.js +26 -26
  38. package/dist/canvas/utils/charts.js.map +1 -1
  39. package/dist/canvas/utils/general functions.d.ts +7 -7
  40. package/dist/canvas/utils/general functions.d.ts.map +1 -1
  41. package/dist/canvas/utils/general functions.js +47 -52
  42. package/dist/canvas/utils/general functions.js.map +1 -1
  43. package/dist/canvas/utils/types.d.ts +1 -3
  44. package/dist/canvas/utils/types.d.ts.map +1 -1
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +45 -1
  47. package/dist/index.js.map +1 -1
  48. package/lib/ai/ApexAI.ts +550 -0
  49. package/lib/ai/buttons/drawMenu.ts +361 -0
  50. package/lib/ai/buttons/tools.ts +550 -0
  51. package/lib/ai/functions/chunkString.ts +3 -0
  52. package/lib/ai/functions/draw.ts +440 -0
  53. package/lib/ai/functions/generateVoiceResponse.ts +177 -0
  54. package/lib/ai/functions/imageReader.ts +24 -0
  55. package/lib/ai/functions/readFiles.ts +34 -0
  56. package/lib/ai/functions/readImagess.ts +41 -0
  57. package/lib/ai/functions/shouldDrawImage.ts +7 -0
  58. package/lib/ai/functions/typeWriter.ts +24 -0
  59. package/lib/ai/models.ts +589 -0
  60. package/lib/ai/utils.ts +23 -0
  61. package/lib/canvas/ApexPainter.ts +572 -0
  62. package/lib/canvas/utils/bg.ts +79 -0
  63. package/lib/canvas/utils/charts.ts +524 -0
  64. package/lib/canvas/utils/circular.ts +17 -0
  65. package/lib/canvas/utils/customLines.ts +49 -0
  66. package/lib/canvas/utils/general functions.ts +434 -0
  67. package/lib/canvas/utils/imageProperties.ts +403 -0
  68. package/lib/canvas/utils/radius.ts +26 -0
  69. package/lib/canvas/utils/textProperties.ts +68 -0
  70. package/lib/canvas/utils/types.ts +417 -0
  71. package/lib/canvas/utils/utils.ts +59 -0
  72. package/lib/index.ts +88 -0
  73. package/lib/utils.ts +8 -0
  74. package/package.json +15 -2
  75. package/tsconfig.json +21 -0
@@ -0,0 +1,440 @@
1
+ import translate from "@iamtraction/google-translate";
2
+ import sharp from "sharp";
3
+ import { ButtonBuilder, StringSelectMenuBuilder, StringSelectMenuOptionBuilder, ButtonStyle, ActionRowBuilder, AttachmentBuilder, AttachmentData } from "discord.js";
4
+ import axios from "axios";
5
+ import api from "api";
6
+
7
+ const sdk: any = api("@prodia/v1.3.0#be019b2kls0gqss3");
8
+ sdk.auth("43435e1c-cab1-493f-a224-f51e4b97ce8d");
9
+
10
+ const validHercaiModals = [
11
+ "v1",
12
+ "v2",
13
+ "v2-beta",
14
+ "lexica",
15
+ "prodia",
16
+ "animefy",
17
+ "raava",
18
+ "shonin",
19
+ "v3",
20
+ ];
21
+
22
+ const validProdiaModals = [
23
+ "3Guofeng3_v34.safetensors [50f420de]",
24
+ "absolutereality_V16.safetensors [37db0fc3]",
25
+ "absolutereality_v181.safetensors [3d9d4d2b]",
26
+ "amIReal_V41.safetensors [0a8a2e61]",
27
+ "analog-diffusion-1.0.ckpt [9ca13f02]",
28
+ "anythingv3_0-pruned.ckpt [2700c435]",
29
+ "anything-v4.5-pruned.ckpt [65745d25]",
30
+ "anythingV5_PrtRE.safetensors [893e49b9]",
31
+ "AOM3A3_orangemixs.safetensors [9600da17]",
32
+ "blazing_drive_v10g.safetensors [ca1c1eab]",
33
+ "cetusMix_Version35.safetensors [de2f2560]",
34
+ "childrensStories_v13D.safetensors [9dfaabcb]",
35
+ "childrensStories_v1SemiReal.safetensors [a1c56dbb]",
36
+ "childrensStories_v1ToonAnime.safetensors [2ec7b88b]",
37
+ "Counterfeit_v30.safetensors [9e2a8f19]",
38
+ "cuteyukimixAdorable_midchapter3.safetensors [04bdffe6]",
39
+ "cyberrealistic_v33.safetensors [82b0d085]",
40
+ "dalcefo_v4.safetensors [425952fe]",
41
+ "deliberate_v2.safetensors [10ec4b29]",
42
+ "deliberate_v3.safetensors [afd9d2d4]",
43
+ "dreamlike-anime-1.0.safetensors [4520e090]",
44
+ "dreamlike-diffusion-1.0.safetensors [5c9fd6e0]",
45
+ "dreamlike-photoreal-2.0.safetensors [fdcf65e7]",
46
+ "dreamshaper_6BakedVae.safetensors [114c8abb]",
47
+ "dreamshaper_7.safetensors [5cf5ae06]",
48
+ "dreamshaper_8.safetensors [9d40847d]",
49
+ "edgeOfRealism_eorV20.safetensors [3ed5de15]",
50
+ "EimisAnimeDiffusion_V1.ckpt [4f828a15]",
51
+ "elldreths-vivid-mix.safetensors [342d9d26]",
52
+ "epicrealism_naturalSinRC1VAE.safetensors [90a4c676]",
53
+ "ICantBelieveItsNotPhotography_seco.safetensors [4e7a3dfd]",
54
+ "juggernaut_aftermath.safetensors [5e20c455]",
55
+ "lofi_v4.safetensors [ccc204d6]",
56
+ "lyriel_v16.safetensors [68fceea2]",
57
+ "majicmixRealistic_v4.safetensors [29d0de58]",
58
+ "mechamix_v10.safetensors [ee685731]",
59
+ "meinamix_meinaV9.safetensors [2ec66ab0]",
60
+ "meinamix_meinaV11.safetensors [b56ce717]",
61
+ "neverendingDream_v122.safetensors [f964ceeb]",
62
+ "openjourney_V4.ckpt [ca2f377f]",
63
+ "pastelMixStylizedAnime_pruned_fp16.safetensors [793a26e8]",
64
+ "portraitplus_V1.0.safetensors [1400e684]",
65
+ "protogenx34.safetensors [5896f8d5]",
66
+ "Realistic_Vision_V1.4-pruned-fp16.safetensors [8d21810b]",
67
+ "Realistic_Vision_V2.0.safetensors [79587710]",
68
+ "Realistic_Vision_V4.0.safetensors [29a7afaa]",
69
+ "Realistic_Vision_V5.0.safetensors [614d1063]",
70
+ "redshift_diffusion-V10.safetensors [1400e684]",
71
+ "revAnimated_v122.safetensors [3f4fefd9]",
72
+ "rundiffusionFX25D_v10.safetensors [cd12b0ee]",
73
+ "rundiffusionFX_v10.safetensors [cd4e694d]",
74
+ "sdv1_4.ckpt [7460a6fa]",
75
+ "v1-5-pruned-emaonly.safetensors [d7049739]",
76
+ "v1-5-inpainting.safetensors [21c7ab71]",
77
+ "shoninsBeautiful_v10.safetensors [25d8c546]",
78
+ "theallys-mix-ii-churned.safetensors [5d9225a4]",
79
+ "timeless-1.0.ckpt [7c4971d4]",
80
+ "toonyou_beta6.safetensors [980f6b15]",
81
+ ];
82
+ async function aiImagine(
83
+ message: any,
84
+ numOfImages: number,
85
+ textToDraw: string,
86
+ hercai: any,
87
+ imageModel: string,
88
+ nsfw: boolean,
89
+ nsfwKeyWords: string[],
90
+ ) {
91
+ const maxRetryAttempts = 3;
92
+ const retryInterval = 10000;
93
+ let response: any;
94
+ async function retry(fn: any, retriesLeft = maxRetryAttempts) {
95
+ try {
96
+ return await fn();
97
+ } catch (error: any) {
98
+ if (retriesLeft === 0) {
99
+ throw error;
100
+ }
101
+ console.error(
102
+ `Retry failed, ${retriesLeft} attempts left. Error: ${error.message}`,
103
+ );
104
+ await new Promise((resolve) => setTimeout(resolve, retryInterval));
105
+ return retry(fn, retriesLeft - 1);
106
+ }
107
+ }
108
+
109
+ try {
110
+ if (numOfImages > 4 || numOfImages <= 0) {
111
+ throw new Error(
112
+ `Number of images can't be greater than 4 or smaller than 0.`,
113
+ );
114
+ }
115
+
116
+ await message.channel?.sendTyping();
117
+
118
+ const translatedText = await retry(() =>
119
+ translate(textToDraw, {
120
+ from: "auto",
121
+ to: "en",
122
+ }),
123
+ );
124
+
125
+ const attachData: AttachmentData[] = [];
126
+ const buttonsRow1: ButtonBuilder[] = [];
127
+ const imageUrls: any = [];
128
+
129
+ for (let _0x4d7fb6 = 0x0; _0x4d7fb6 < numOfImages; _0x4d7fb6++) {
130
+ try {
131
+ if (validHercaiModals.includes(imageModel)) {
132
+ response = await retry(() =>
133
+ hercai.drawImage({
134
+ model: imageModel,
135
+ prompt: translatedText.text,
136
+ }),
137
+ );
138
+ } else if (validProdiaModals.includes(imageModel)) {
139
+ const generateResponse = await sdk.generate({
140
+ model: imageModel,
141
+ prompt: translatedText.text,
142
+ });
143
+
144
+ await message.channel?.sendTyping();
145
+
146
+ const generatedJobId = generateResponse.data.job;
147
+ response = await checkJobStatus(generatedJobId);
148
+ } else {
149
+ throw new Error("Invalid modal name.");
150
+ }
151
+ } catch (error: any) {
152
+ if (error.response && error.response.status === 429) {
153
+ console.error("Too many requests. Please try again later.");
154
+ return message.reply(`Please wait i am in a cool down for a minute`);
155
+ } else if (error.response && error.response.status === 500) {
156
+ console.error("Internal server error. Please try again later.");
157
+ return message.reply(`Please wait i am in a cool down for a minute`);
158
+ } else {
159
+ await message.reply(`Please wait i am in a cool down for a minute`);
160
+ throw new Error("Error processing message in file");
161
+ }
162
+ }
163
+ let buffferedImage: any;
164
+
165
+ if (imageModel === "v3") {
166
+ const res = await retry(() =>
167
+ axios.get(response.url, {
168
+ responseType: "arraybuffer",
169
+ }),
170
+ );
171
+
172
+ await message.channel?.sendTyping();
173
+
174
+ buffferedImage = Buffer.from(res.data, "binary");
175
+
176
+ const resizedImage = await sharp(buffferedImage)
177
+ .resize({
178
+ width: 0x320,
179
+ })
180
+ .toBuffer();
181
+
182
+ const attachment = {
183
+ file: resizedImage,
184
+ name: `image_${_0x4d7fb6 + 1}.png`,
185
+ } as AttachmentData;
186
+
187
+ attachData.push(attachment);
188
+
189
+ const urlButton = new ButtonBuilder()
190
+ .setStyle(ButtonStyle.Link)
191
+ .setLabel(`Image ${_0x4d7fb6 + 1}`)
192
+ .setURL(response.url);
193
+
194
+ buttonsRow1.push(urlButton);
195
+
196
+ imageUrls.push(response.url);
197
+ } else {
198
+ const imageUrl = response.url || response;
199
+
200
+ await message.channel?.sendTyping();
201
+
202
+ if (nsfw) {
203
+ const textToCheck = await attemptImageCaptioning(imageUrl);
204
+
205
+ const nsfwWords: string[] = [
206
+ "anal",
207
+ "arousal",
208
+ "balls",
209
+ "blowjob",
210
+ "busty",
211
+ "butt",
212
+ "cameltoe",
213
+ "climax",
214
+ "clitoris",
215
+ "cock",
216
+ "crotch",
217
+ "cum",
218
+ "cumshot",
219
+ "cunnilingus",
220
+ "dirty",
221
+ "dirtytalk",
222
+ "dildo",
223
+ "erect",
224
+ "erogenous",
225
+ "escort",
226
+ "explicit",
227
+ "facial",
228
+ "fetish",
229
+ "flirt",
230
+ "foreplay",
231
+ "genitals",
232
+ "groin",
233
+ "hardcore",
234
+ "hardon",
235
+ "horniness",
236
+ "horny",
237
+ "kamasutra",
238
+ "kinky",
239
+ "lewd",
240
+ "lingerie",
241
+ "lust",
242
+ "lustful",
243
+ "masturbate",
244
+ "mature",
245
+ "milf",
246
+ "naughty",
247
+ "naked",
248
+ "nipples",
249
+ "nude",
250
+ "obscene",
251
+ "oral",
252
+ "orgasm",
253
+ "penetration",
254
+ "penis",
255
+ "pleasure",
256
+ "porn",
257
+ "prostitute",
258
+ "provocative",
259
+ "pubic",
260
+ "pussy",
261
+ "seduce",
262
+ "seductive",
263
+ "sensual",
264
+ "sex",
265
+ "sexual",
266
+ "sperm",
267
+ "strip",
268
+ "striptease",
269
+ "swinger",
270
+ "testicles",
271
+ "thong",
272
+ "threesome",
273
+ "undies",
274
+ "undress",
275
+ "vagina",
276
+ "vibrator",
277
+ "wank",
278
+ "wet",
279
+ "hentai",
280
+ "bdsm",
281
+ "gay",
282
+ "lesbian",
283
+ "femboy",
284
+ "ass",
285
+ ];
286
+
287
+ if (nsfwKeyWords.length > 0) {
288
+ if (textToCheck && nsfwKeyWords.some(word => textToCheck?.includes(word))) {
289
+ return message.reply("Warning ⚠️. The generated image contatining nsfw content. Turn off nsfw to sedn nsfw images.");
290
+ }
291
+ }
292
+ if (textToCheck && nsfwWords.some(word => textToCheck?.includes(word))) {
293
+ return message.reply("Warning ⚠️. The generated image contatining nsfw content. Turn off nsfw to sedn nsfw images.");
294
+ }
295
+ }
296
+
297
+ const attach = new AttachmentBuilder(
298
+ imageUrl,
299
+ { name: `image_${_0x4d7fb6 + 1}.png` },
300
+ ) as AttachmentData;
301
+
302
+ attachData.push(attach);
303
+
304
+ const urlButton = new ButtonBuilder()
305
+ .setStyle(ButtonStyle.Link)
306
+ .setLabel(`Image ${_0x4d7fb6 + 1}`)
307
+ .setURL(imageUrl);
308
+
309
+ buttonsRow1.push(urlButton);
310
+
311
+ imageUrls.push(imageUrl);
312
+ }
313
+
314
+ await new Promise((resolve) => setTimeout(resolve, 0x7d0));
315
+ }
316
+
317
+ const selectMenu = new StringSelectMenuBuilder()
318
+ .setCustomId("image_processing_select")
319
+ .setPlaceholder("Select Image Process");
320
+
321
+ const options = [
322
+ "Resizing",
323
+ "Color Filters",
324
+ "Convert Image Extension",
325
+ "Brightness",
326
+ "Sepia",
327
+ "Pixelate",
328
+ "Blur",
329
+ "Fade",
330
+ "Opaque",
331
+ "Grayscale",
332
+ "Contrast",
333
+ ];
334
+
335
+ options.forEach((option, index) => {
336
+ const selectOption = new StringSelectMenuOptionBuilder()
337
+ .setLabel(option)
338
+ .setValue(`process_${index + 1}`);
339
+
340
+ selectMenu.addOptions(selectOption);
341
+ });
342
+
343
+ await message.channel?.sendTyping();
344
+
345
+ const row1 = new ActionRowBuilder().addComponents(
346
+ ...buttonsRow1,
347
+ );
348
+ const row2 = new ActionRowBuilder().addComponents(selectMenu);
349
+
350
+ await message.reply({
351
+ files: attachData,
352
+ components: [row1, row2],
353
+ allowedMentions: { repliedUser: false },
354
+ });
355
+
356
+ return imageUrls;
357
+ } catch (error: any) {
358
+ console.error("Error in drawImage:", error.message);
359
+ if (error.response) {
360
+ console.error("Status code:", error.response.status);
361
+ console.error("Response data:", error.response.data);
362
+ }
363
+ message.reply({
364
+ content: "An error occurred while processing the images.",
365
+ allowedMentions: { repliedUser: false },
366
+ });
367
+ return [];
368
+ }
369
+ }
370
+
371
+ async function checkJobStatus(jobId: number | string | any) {
372
+ try {
373
+ const getJobResponse = await sdk.getJob({ jobId });
374
+ const jobData = getJobResponse.data;
375
+ if (jobData.status === "generating" || jobData.status === "queued") {
376
+ await new Promise((resolve) => setTimeout(resolve, 3000));
377
+ return checkJobStatus(jobId);
378
+ } else if (jobData.status === "succeeded") {
379
+ return jobData.imageUrl;
380
+ } else {
381
+ console.error("Job failed:", jobData);
382
+ return null;
383
+ }
384
+ } catch (error) {
385
+ console.error(error);
386
+ return null;
387
+ }
388
+ }
389
+
390
+ async function attemptImageCaptioning(imageUrl: string) {
391
+ try {
392
+ let retryCount = 0;
393
+ const maxRetries = 3;
394
+
395
+ const fetchData = async () => {
396
+ try {
397
+ const response = await axios.post(
398
+ `https://api-inference.huggingface.co/models/Salesforce/blip-image-captioning-base`,
399
+ { image: imageUrl },
400
+ {
401
+ headers: {
402
+ "Content-Type": "application/json",
403
+ Authorization: `Bearer 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`,
404
+ },
405
+ },
406
+ );
407
+
408
+ if (response.status === 200) {
409
+ return response.data[0].generated_text;
410
+ } else {
411
+ console.error(
412
+ `Failed to fetch image captioning API: ${response.statusText}`,
413
+ );
414
+ return null;
415
+ }
416
+ } catch (error: any) {
417
+ console.error(`Error fetching data: ${error.message}`);
418
+ throw error;
419
+ }
420
+ };
421
+
422
+ while (retryCount < maxRetries) {
423
+ try {
424
+ return await fetchData();
425
+ } catch (error: any) {
426
+ console.error(
427
+ `Error fetching data (Retry ${retryCount + 1}): ${error.message}`,
428
+ );
429
+ retryCount++;
430
+ }
431
+ }
432
+
433
+ return null;
434
+ } catch (error: any) {
435
+ console.error(`Error in attemptImageCaptioning: ${error.message}`);
436
+ return null;
437
+ }
438
+ }
439
+
440
+ export { aiImagine };
@@ -0,0 +1,177 @@
1
+ import { Hercai } from "hercai";
2
+ import translate from "@iamtraction/google-translate";
3
+ import axios from "axios";
4
+ import { createWorker, recognize } from "tesseract.js";
5
+ import { chunkString } from "./chunkString";
6
+ import { aiImagine } from "./draw";
7
+ import fs from "fs";
8
+
9
+ const herc = new Hercai();
10
+ let isProcessing = false;
11
+ type ChatModelOption = "v3" | "v3-32k" | "turbo" | "turbo-16k" | "gemini" ;
12
+
13
+ async function aiVoice(
14
+ message: any,
15
+ numOfImages: number,
16
+ finalText: string,
17
+ hercai: any,
18
+ drawValid: any,
19
+ imageModal: string,
20
+ chatModal: string | "v3" | "v3-32k" | "turbo" | "turbo-16k" | "gemini" | "starChat" | "apexChat" | 'gemma-v3' | 'gemma-v4' | 'zephyr-beta' | undefined,
21
+ voiceModal: string,
22
+ voice_code: string,
23
+ type: string,
24
+ apiKey: string,
25
+ nsfw: boolean,
26
+ nsfwKeyWords: string[]
27
+ ) {
28
+ if (message.author.bot || isProcessing || !message.guild) {
29
+ return;
30
+ }
31
+
32
+ isProcessing = true;
33
+
34
+ try {
35
+ let msg = message.content;
36
+
37
+ if (drawValid) {
38
+ return await aiImagine(message, numOfImages, finalText, hercai, imageModal, nsfw, nsfwKeyWords);
39
+ }
40
+
41
+ if (message.attachments.size > 0) {
42
+ const attachment = message.attachments.first();
43
+ const imageUrl = attachment.url;
44
+ const worker = await createWorker();
45
+ const { data: { text } } = await recognize(imageUrl);
46
+ await worker.terminate();
47
+ msg += "\n" + text;
48
+ }
49
+
50
+ msg = (await herc.question({
51
+ model: chatModal as ChatModelOption,
52
+ content: msg,
53
+ })).reply.replace(/\n/g, " ");
54
+
55
+ if (voiceModal === "google") {
56
+ if (!isEnglish(msg)) {
57
+ const translationResult = await translate(msg, {
58
+ from: "auto",
59
+ to: "en",
60
+ });
61
+ msg = translationResult.text;
62
+ }
63
+
64
+ const chunks = chunkString(msg, 200);
65
+ let delay = 0;
66
+
67
+ for (const chunk of chunks) {
68
+ setTimeout(async () => {
69
+ const encodedChunk = encodeURIComponent(chunk);
70
+ const url = `https://translate.google.com/translate_tts?ie=UTF-8&tl=en&client=tw-ob&q=${encodedChunk}`;
71
+ const mp3Stream = await axios.get(url, {
72
+ responseType: "stream",
73
+ headers: {
74
+ Referer: "http://translate.google.com/",
75
+ "User-Agent": "stagefright/1.2 (Linux;Android 5.0)",
76
+ },
77
+ });
78
+ await message.reply({
79
+ files: [
80
+ {
81
+ attachment: mp3Stream.data,
82
+ name: "respond.mp3",
83
+ },
84
+ ],
85
+ allowedMentions: { repliedUser: false },
86
+ });
87
+ }, delay);
88
+ delay += 3000;
89
+ }
90
+ } else if (voiceModal === "apexAI") {
91
+ if (!apiKey) {
92
+ throw new Error('Error: The apexAI model requires a premium account for generation. Please visit our support server at https://discord.gg/4uhpr7w8wW for assistance.');
93
+ }
94
+
95
+ const options = {
96
+ method: "POST",
97
+ url: "https://text-to-speech-neural-google.p.rapidapi.com/generateAudioFiles",
98
+ headers: {
99
+ "content-type": "application/json",
100
+ "X-RapidAPI-Key": apiKey,
101
+ "X-RapidAPI-Host": "text-to-speech-neural-google.p.rapidapi.com",
102
+ },
103
+ data: {
104
+ audioFormat: "ogg",
105
+ paragraphChunks: [msg],
106
+ voiceParams: {
107
+ name: `Wavenet-${type || "c"}`,
108
+ engine: "google",
109
+ languageCode: "en-US",
110
+ },
111
+ },
112
+ };
113
+
114
+ try {
115
+ const response = await axios.request(options);
116
+ const audioData = response.data.audioStream;
117
+ fs.writeFileSync("output.ogg", Buffer.from(audioData, "base64"));
118
+ await message.reply({
119
+ files: [
120
+ {
121
+ attachment: "output.ogg",
122
+ name: "respond.ogg",
123
+ },
124
+ ],
125
+ allowedMentions: { repliedUser: false },
126
+ });
127
+ } catch (error) {
128
+ console.error(error);
129
+ throw new Error('Error generating audio file.');
130
+ }
131
+ } else if (imageModal === "zenithAi") {
132
+ if (!apiKey) {
133
+ throw new Error('Error: The zenithAi model requires a premium account for generation. Please visit our support server at https://discord.gg/4uhpr7w8wW for assistance.');
134
+ }
135
+
136
+ const encodedParams = new URLSearchParams();
137
+ encodedParams.set("voice_code", voice_code || "en-US-3");
138
+ encodedParams.set("text", msg);
139
+ encodedParams.set("speed", "1.00");
140
+ encodedParams.set("pitch", "1.00");
141
+ encodedParams.set("output_type", "audio_url");
142
+
143
+ const options = {
144
+ method: "POST",
145
+ url: "https://cloudlabs-text-to-speech.p.rapidapi.com/synthesize",
146
+ headers: {
147
+ "content-type": "application/x-www-form-urlencoded",
148
+ "X-RapidAPI-Key": apiKey,
149
+ "X-RapidAPI-Host": "cloudlabs-text-to-speech.p.rapidapi.com",
150
+ },
151
+ data: encodedParams,
152
+ };
153
+
154
+ try {
155
+ const response = await axios.request(options);
156
+ const audioUrl = response.data.result.audio_url;
157
+ await message.reply(audioUrl, {
158
+ allowedMentions: { repliedUser: false },
159
+ });
160
+ } catch (error) {
161
+ console.error(error);
162
+ throw new Error('Error generating audio URL.');
163
+ }
164
+ }
165
+ } catch (error: any) {
166
+ console.error(error.message);
167
+ message.reply("The response of the bot was too long and couldn't be sent as a voice.");
168
+ } finally {
169
+ isProcessing = false;
170
+ }
171
+ }
172
+
173
+ function isEnglish(str: string) {
174
+ return /^[A-Za-z0-9!@#$%^&()_+\-=\[\]{};':"\\|,.<>\/?]+$/.test(str);
175
+ }
176
+
177
+ export { aiVoice };
@@ -0,0 +1,24 @@
1
+ import { createWorker } from 'tesseract.js';
2
+
3
+ async function imageReader(imageURL: string): Promise<string> {
4
+ try {
5
+
6
+ if (imageURL === null) return '';
7
+
8
+ const worker = await createWorker();
9
+ const ret = await worker.recognize(imageURL);
10
+ await worker.terminate();
11
+
12
+ const text = ret.data.text;
13
+
14
+ if (text.length <= 0) {
15
+ return `No text found on image`
16
+ }
17
+
18
+ return text;
19
+ } catch (error: any) {
20
+ return `Error occurred while processing image: ${error.message}`;
21
+ }
22
+ }
23
+
24
+ export { imageReader };
@@ -0,0 +1,34 @@
1
+ import pdf from "pdf-parse";
2
+ import * as fs from "fs";
3
+ import * as https from "https";
4
+
5
+ export async function readPdf(url: string): Promise<string> {
6
+ const pdfBuffer = await downloadFile(url);
7
+ const data = await pdf(pdfBuffer);
8
+ return data.text;
9
+ }
10
+
11
+ export async function readTextFile(url: string): Promise<string> {
12
+ const textBuffer = await downloadFile(url);
13
+ return textBuffer.toString();
14
+ }
15
+
16
+ function downloadFile(url: string): Promise<Buffer> {
17
+ return new Promise((resolve, reject) => {
18
+ const tempFilePath = 'temp';
19
+ const file = fs.createWriteStream(tempFilePath);
20
+
21
+ https.get(url, (response) => {
22
+ response.pipe(file);
23
+ file.on('finish', () => {
24
+ file.close();
25
+ const fileBuffer = fs.readFileSync(tempFilePath);
26
+ fs.unlinkSync(tempFilePath);
27
+ resolve(fileBuffer);
28
+ });
29
+ }).on('error', (err) => {
30
+ fs.unlinkSync(tempFilePath);
31
+ reject(err.message);
32
+ });
33
+ });
34
+ }