opencrush 0.3.9 → 0.3.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +64 -32
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -234588,6 +234588,21 @@ function debugLog3(msg) {
|
|
|
234588
234588
|
} catch {
|
|
234589
234589
|
}
|
|
234590
234590
|
}
|
|
234591
|
+
async function loadVoice() {
|
|
234592
|
+
if (voice) return voice;
|
|
234593
|
+
if (voiceLoadError) return null;
|
|
234594
|
+
try {
|
|
234595
|
+
voice = await import("@discordjs/voice");
|
|
234596
|
+
return voice;
|
|
234597
|
+
} catch (err) {
|
|
234598
|
+
voiceLoadError = err instanceof Error ? err.message : String(err);
|
|
234599
|
+
console.warn(`[Discord] @discordjs/voice not available \u2014 voice features disabled (${voiceLoadError})`);
|
|
234600
|
+
return null;
|
|
234601
|
+
}
|
|
234602
|
+
}
|
|
234603
|
+
function getVoiceSync() {
|
|
234604
|
+
return voice;
|
|
234605
|
+
}
|
|
234591
234606
|
async function loadPrism() {
|
|
234592
234607
|
if (!prism) {
|
|
234593
234608
|
prism = await import("prism-media");
|
|
@@ -234610,15 +234625,16 @@ function splitMessage(text, maxLength = 1900) {
|
|
|
234610
234625
|
if (current) chunks.push(current.trim());
|
|
234611
234626
|
return chunks;
|
|
234612
234627
|
}
|
|
234613
|
-
var import_discord, import_fs15,
|
|
234628
|
+
var import_discord, import_fs15, import_stream4, DEBUG_LOG, voice, voiceLoadError, prism, DiscordBridge;
|
|
234614
234629
|
var init_dist5 = __esm({
|
|
234615
234630
|
"../bridges/discord/dist/index.mjs"() {
|
|
234616
234631
|
"use strict";
|
|
234617
234632
|
import_discord = __toESM(require_src3(), 1);
|
|
234618
234633
|
import_fs15 = require("fs");
|
|
234619
|
-
import_voice = require("@discordjs/voice");
|
|
234620
234634
|
import_stream4 = require("stream");
|
|
234621
234635
|
DEBUG_LOG = "/tmp/opencrush-debug.log";
|
|
234636
|
+
voice = null;
|
|
234637
|
+
voiceLoadError = null;
|
|
234622
234638
|
prism = null;
|
|
234623
234639
|
DiscordBridge = class {
|
|
234624
234640
|
client;
|
|
@@ -234839,6 +234855,8 @@ var init_dist5 = __esm({
|
|
|
234839
234855
|
}
|
|
234840
234856
|
async handleVoiceState(oldState, newState) {
|
|
234841
234857
|
var _a3;
|
|
234858
|
+
const v2 = await loadVoice();
|
|
234859
|
+
if (!v2) return;
|
|
234842
234860
|
if (((_a3 = newState.member) == null ? void 0 : _a3.id) !== this.config.ownerId) return;
|
|
234843
234861
|
const userJoinedVoice = !oldState.channelId && newState.channelId;
|
|
234844
234862
|
const userLeftVoice = oldState.channelId && !newState.channelId;
|
|
@@ -234868,7 +234886,9 @@ var init_dist5 = __esm({
|
|
|
234868
234886
|
* Creates a loop: listen → transcribe → LLM → TTS → speak → repeat.
|
|
234869
234887
|
*/
|
|
234870
234888
|
startVoiceConversation(guildId) {
|
|
234871
|
-
const
|
|
234889
|
+
const v2 = getVoiceSync();
|
|
234890
|
+
if (!v2) return;
|
|
234891
|
+
const connection = v2.getVoiceConnection(guildId);
|
|
234872
234892
|
if (!connection) return;
|
|
234873
234893
|
this.voiceConversationActive.set(guildId, true);
|
|
234874
234894
|
console.log(`[Discord/Voice] Starting voice conversation in guild ${guildId}`);
|
|
@@ -234881,7 +234901,9 @@ var init_dist5 = __esm({
|
|
|
234881
234901
|
}
|
|
234882
234902
|
async listenForNextUtterance(guildId) {
|
|
234883
234903
|
if (!this.voiceConversationActive.get(guildId)) return;
|
|
234884
|
-
const
|
|
234904
|
+
const v2 = getVoiceSync();
|
|
234905
|
+
if (!v2) return;
|
|
234906
|
+
const connection = v2.getVoiceConnection(guildId);
|
|
234885
234907
|
if (!connection) return;
|
|
234886
234908
|
if (this.isSpeaking.get(guildId)) {
|
|
234887
234909
|
setTimeout(() => this.listenForNextUtterance(guildId), 500);
|
|
@@ -234891,7 +234913,7 @@ var init_dist5 = __esm({
|
|
|
234891
234913
|
const receiver = connection.receiver;
|
|
234892
234914
|
const opusStream = receiver.subscribe(this.config.ownerId, {
|
|
234893
234915
|
end: {
|
|
234894
|
-
behavior:
|
|
234916
|
+
behavior: v2.EndBehaviorType.AfterSilence,
|
|
234895
234917
|
duration: 1500
|
|
234896
234918
|
}
|
|
234897
234919
|
});
|
|
@@ -234990,36 +235012,42 @@ var init_dist5 = __esm({
|
|
|
234990
235012
|
}
|
|
234991
235013
|
// ── Voice Channel Management ───────────────────────────────
|
|
234992
235014
|
async joinVoiceChannel(channelId, guildId, adapterCreator) {
|
|
235015
|
+
const v2 = getVoiceSync();
|
|
235016
|
+
if (!v2) return;
|
|
234993
235017
|
try {
|
|
234994
|
-
const connection =
|
|
235018
|
+
const connection = v2.joinVoiceChannel({
|
|
234995
235019
|
channelId,
|
|
234996
235020
|
guildId,
|
|
234997
235021
|
adapterCreator,
|
|
234998
235022
|
selfDeaf: false,
|
|
234999
235023
|
selfMute: false
|
|
235000
235024
|
});
|
|
235001
|
-
await
|
|
235025
|
+
await v2.entersState(connection, v2.VoiceConnectionStatus.Ready, 3e4);
|
|
235002
235026
|
console.log(`[Discord] Joined voice channel ${channelId}`);
|
|
235003
235027
|
} catch (err) {
|
|
235004
235028
|
console.error("[Discord] Failed to join voice channel:", err);
|
|
235005
235029
|
}
|
|
235006
235030
|
}
|
|
235007
235031
|
leaveVoiceChannel(guildId) {
|
|
235008
|
-
const
|
|
235032
|
+
const v2 = getVoiceSync();
|
|
235033
|
+
if (!v2) return;
|
|
235034
|
+
const connection = v2.getVoiceConnection(guildId);
|
|
235009
235035
|
if (connection) {
|
|
235010
235036
|
connection.destroy();
|
|
235011
235037
|
console.log(`[Discord] Left voice channel in guild ${guildId}`);
|
|
235012
235038
|
}
|
|
235013
235039
|
}
|
|
235014
235040
|
async playAudio(guildId, audioBuffer) {
|
|
235015
|
-
const
|
|
235041
|
+
const v2 = getVoiceSync();
|
|
235042
|
+
if (!v2) return;
|
|
235043
|
+
const connection = v2.getVoiceConnection(guildId);
|
|
235016
235044
|
if (!connection) return;
|
|
235017
|
-
const player =
|
|
235045
|
+
const player = v2.createAudioPlayer();
|
|
235018
235046
|
const readable = import_stream4.Readable.from(audioBuffer);
|
|
235019
|
-
const resource =
|
|
235047
|
+
const resource = v2.createAudioResource(readable);
|
|
235020
235048
|
player.play(resource);
|
|
235021
235049
|
connection.subscribe(player);
|
|
235022
|
-
await
|
|
235050
|
+
await v2.entersState(player, v2.AudioPlayerStatus.Idle, 6e4);
|
|
235023
235051
|
}
|
|
235024
235052
|
// ── Message Handling ───────────────────────────────────────
|
|
235025
235053
|
/**
|
|
@@ -235215,6 +235243,7 @@ var init_dist5 = __esm({
|
|
|
235215
235243
|
}
|
|
235216
235244
|
}
|
|
235217
235245
|
async start() {
|
|
235246
|
+
await loadVoice();
|
|
235218
235247
|
await this.client.login(this.config.token);
|
|
235219
235248
|
}
|
|
235220
235249
|
async stop() {
|
|
@@ -236377,10 +236406,10 @@ var require_context = __commonJS({
|
|
|
236377
236406
|
*
|
|
236378
236407
|
* **Official reference:** https://core.telegram.org/bots/api#sendvoice
|
|
236379
236408
|
*/
|
|
236380
|
-
replyWithVoice(
|
|
236409
|
+
replyWithVoice(voice2, other, signal) {
|
|
236381
236410
|
var _a3;
|
|
236382
236411
|
const msg = this.msg;
|
|
236383
|
-
return this.api.sendVoice(orThrow(this.chatId, "sendVoice"),
|
|
236412
|
+
return this.api.sendVoice(orThrow(this.chatId, "sendVoice"), voice2, {
|
|
236384
236413
|
business_connection_id: this.businessConnectionId,
|
|
236385
236414
|
...(msg === null || msg === void 0 ? void 0 : msg.is_topic_message) ? { message_thread_id: msg.message_thread_id } : {},
|
|
236386
236415
|
direct_messages_topic_id: (_a3 = msg === null || msg === void 0 ? void 0 : msg.direct_messages_topic) === null || _a3 === void 0 ? void 0 : _a3.topic_id,
|
|
@@ -239463,8 +239492,8 @@ var require_api3 = __commonJS({
|
|
|
239463
239492
|
*
|
|
239464
239493
|
* **Official reference:** https://core.telegram.org/bots/api#sendvoice
|
|
239465
239494
|
*/
|
|
239466
|
-
sendVoice(chat_id,
|
|
239467
|
-
return this.raw.sendVoice({ chat_id, voice, ...other }, signal);
|
|
239495
|
+
sendVoice(chat_id, voice2, other, signal) {
|
|
239496
|
+
return this.raw.sendVoice({ chat_id, voice: voice2, ...other }, signal);
|
|
239468
239497
|
}
|
|
239469
239498
|
/**
|
|
239470
239499
|
* Use this method to send video messages. On success, the sent Message is returned.
|
|
@@ -245490,7 +245519,8 @@ function parseIdentity(identityPath) {
|
|
|
245490
245519
|
const ageMatch = content.match(/\*\*Age:\*\*\s*(\d+)/i);
|
|
245491
245520
|
const age = (ageMatch == null ? void 0 : ageMatch[1]) ?? "??";
|
|
245492
245521
|
const fromMatch = content.match(/\*\*From:\*\*\s*(.+)/i);
|
|
245493
|
-
const
|
|
245522
|
+
const locationRaw = ((_b2 = fromMatch == null ? void 0 : fromMatch[1]) == null ? void 0 : _b2.trim()) ?? "Unknown";
|
|
245523
|
+
const location = locationRaw.replace(/\s*\(.*\)\s*$/, "").trim();
|
|
245494
245524
|
const hobbiesMatch = content.match(/\*\*Hobbies:\*\*\s*(.+)/i);
|
|
245495
245525
|
const hobbiesRaw = (hobbiesMatch == null ? void 0 : hobbiesMatch[1]) ?? "";
|
|
245496
245526
|
const tags = hobbiesRaw.split(",").map((t2) => t2.trim()).filter(Boolean).slice(0, 5);
|
|
@@ -245521,27 +245551,29 @@ function pickGradient(name) {
|
|
|
245521
245551
|
function createSvgOverlay(data, gradient) {
|
|
245522
245552
|
const textX = PORTRAIT_X + PORTRAIT_SIZE + 60;
|
|
245523
245553
|
const tagY = 280;
|
|
245524
|
-
const
|
|
245525
|
-
const x2 = textX + i2 * 0;
|
|
245526
|
-
const inlineX = textX;
|
|
245527
|
-
const inlineY = tagY + i2 * 36;
|
|
245528
|
-
return `
|
|
245529
|
-
<rect x="${inlineX - 4}" y="${inlineY - 18}" width="${tag.length * 10 + 24}" height="28" rx="14" fill="rgba(255,255,255,0.12)" />
|
|
245530
|
-
<text x="${inlineX + 8}" y="${inlineY}" font-family="system-ui, -apple-system, sans-serif" font-size="14" fill="#e0e0e0">${escapeXml(tag)}</text>
|
|
245531
|
-
`;
|
|
245532
|
-
}).join("\n");
|
|
245554
|
+
const maxTagX = WIDTH - 40;
|
|
245533
245555
|
let inlineTags = "";
|
|
245534
245556
|
let offsetX = textX;
|
|
245535
|
-
|
|
245557
|
+
let rowY = tagY;
|
|
245558
|
+
const rowHeight = 34;
|
|
245559
|
+
const maxRows = 2;
|
|
245560
|
+
let currentRow = 1;
|
|
245536
245561
|
for (const tag of data.tags) {
|
|
245537
|
-
const
|
|
245562
|
+
const label = tag.length > 22 ? tag.slice(0, 21) + "\u2026" : tag;
|
|
245563
|
+
const w2 = label.length * 8.5 + 24;
|
|
245564
|
+
if (offsetX + w2 > maxTagX) {
|
|
245565
|
+
if (currentRow >= maxRows) break;
|
|
245566
|
+
currentRow++;
|
|
245567
|
+
offsetX = textX;
|
|
245568
|
+
rowY += rowHeight;
|
|
245569
|
+
}
|
|
245538
245570
|
inlineTags += `
|
|
245539
|
-
<rect x="${offsetX - 2}" y="${
|
|
245540
|
-
<text x="${offsetX + 10}" y="${
|
|
245571
|
+
<rect x="${offsetX - 2}" y="${rowY - 16}" width="${w2}" height="26" rx="13" fill="rgba(255,255,255,0.10)" />
|
|
245572
|
+
<text x="${offsetX + 10}" y="${rowY}" font-family="system-ui, -apple-system, sans-serif" font-size="13" fill="#c0c0c0">${escapeXml(label)}</text>
|
|
245541
245573
|
`;
|
|
245542
245574
|
offsetX += w2 + 8;
|
|
245543
|
-
if (offsetX > WIDTH - 40) break;
|
|
245544
245575
|
}
|
|
245576
|
+
const descriptionY = tagY + currentRow * rowHeight + 16;
|
|
245545
245577
|
return `<svg width="${WIDTH}" height="${HEIGHT}" xmlns="http://www.w3.org/2000/svg">
|
|
245546
245578
|
<defs>
|
|
245547
245579
|
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
|
@@ -245569,7 +245601,7 @@ function createSvgOverlay(data, gradient) {
|
|
|
245569
245601
|
${inlineTags}
|
|
245570
245602
|
|
|
245571
245603
|
<!-- One-line description -->
|
|
245572
|
-
<text x="${textX}" y="${
|
|
245604
|
+
<text x="${textX}" y="${descriptionY}" font-family="system-ui, -apple-system, sans-serif" font-size="15" fill="#b0b0b0" font-style="italic">${escapeXml(truncate(data.description, 70))}</text>
|
|
245573
245605
|
|
|
245574
245606
|
<!-- Bottom bar -->
|
|
245575
245607
|
<rect x="0" y="${HEIGHT - 50}" width="${WIDTH}" height="50" fill="rgba(0,0,0,0.3)" />
|