beast-agent 0.26.2 → 0.26.4
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/package.json +1 -1
- package/src/agent/discord.js +90 -26
- package/src/renderer/i18n.js +2 -0
- package/src/renderer/renderer.js +1 -0
package/package.json
CHANGED
package/src/agent/discord.js
CHANGED
|
@@ -23,9 +23,11 @@ const INTENTS = 1 | 512 | 4096 | 32768;
|
|
|
23
23
|
/* AĞ ARA YAZILIMI (antivirüs SSL taraması / proxy / ağ filtresi) Discord
|
|
24
24
|
trafiğine araya girip SELF-SIGNED sertifika sunarsa Node varsayılan olarak
|
|
25
25
|
bağlantıyı reddeder ("self signed certificate") ve bot hiç bağlanamaz.
|
|
26
|
-
Çözüm
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
Çözüm iki katman:
|
|
27
|
+
1) REST istekleri ÖNCE Electron/Chromium ağ yığınından (net.fetch) geçer —
|
|
28
|
+
sistem CA + sistem proxy otomatik tanınır (tarayıcının çalıştığı yol).
|
|
29
|
+
2) Zorlanırsa Node https'e düşülür; self-signed tespit edilirse bu köprü
|
|
30
|
+
için TLS doğrulaması esnetilir — YALNIZ Discord bağlantıları etkilenir. */
|
|
29
31
|
let tlsRelaxed = false;
|
|
30
32
|
const CERT_ERR_RE = /self[ -]?signed|unable to verify the first certificate|depth zero|err_tls|certificate has expired|cert_has_expired|unable_to_get_issuer|self signed certificate/i;
|
|
31
33
|
|
|
@@ -33,6 +35,33 @@ function isCertError(e) {
|
|
|
33
35
|
return CERT_ERR_RE.test(String((e && (e.message || e.code)) || e || ''));
|
|
34
36
|
}
|
|
35
37
|
|
|
38
|
+
/* Electron main process'te Chromium ağ yığını (sistem CA + proxy); düz Node
|
|
39
|
+
(testler) için require('electron') path string döndürür → net tanımsız kalır */
|
|
40
|
+
let _electronNet = null;
|
|
41
|
+
try {
|
|
42
|
+
const el = require('electron');
|
|
43
|
+
if (el && el.net && typeof el.net.fetch === 'function') _electronNet = el.net;
|
|
44
|
+
} catch {}
|
|
45
|
+
|
|
46
|
+
function bodySnippet(data) {
|
|
47
|
+
const s = String(data || '').replace(/\s+/g, ' ').trim();
|
|
48
|
+
return s ? ` — gövde: ${s.slice(0, 140)}` : '';
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* Ağ engel sayfası tespiti: Discord API her zaman JSON döner — text/html veya
|
|
52
|
+
erişim-engelle sayfası gelirse ağ seviyesinde blok var demektir (Türkiye'de
|
|
53
|
+
Discord erişimi zaman zaman engellenir). Kullanıcıya net VPN yönlendirmesi. */
|
|
54
|
+
const VPN_HINT = 'Discord bu ağdan ERİŞİME ENGELLİ görünüyor — VPN açıp tekrar dene (engel sayfası döndü)';
|
|
55
|
+
|
|
56
|
+
function looksBlocked(ctype, data) {
|
|
57
|
+
const ct = String(ctype || '');
|
|
58
|
+
const body = String(data || '').slice(0, 4000);
|
|
59
|
+
return (
|
|
60
|
+
ct.includes('text/html') ||
|
|
61
|
+
/erisime[_ ]?engelle|erişime engelle|blocked|block_page/i.test(body)
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
36
65
|
class DiscordBridge {
|
|
37
66
|
constructor({ token, emit, onIncoming }) {
|
|
38
67
|
this.token = String(token || '').trim();
|
|
@@ -54,18 +83,60 @@ class DiscordBridge {
|
|
|
54
83
|
this.emit({ type: 'status', status, user: user || null });
|
|
55
84
|
}
|
|
56
85
|
|
|
57
|
-
/* REST çağrısı — JSON (token: "Bot <token>").
|
|
58
|
-
|
|
86
|
+
/* REST çağrısı — JSON (token: "Bot <token>").
|
|
87
|
+
Yol 1: Chromium (net.fetch — sistem CA/proxy). Yol 2: Node https (+esnek TLS). */
|
|
59
88
|
api(method, path, body, attempt = 0) {
|
|
89
|
+
return this._api(method, path, body).catch((e) => {
|
|
90
|
+
if (isCertError(e) && !tlsRelaxed) {
|
|
91
|
+
tlsRelaxed = true;
|
|
92
|
+
this.emit({
|
|
93
|
+
type: 'warn',
|
|
94
|
+
text: 'ağ ara yazılımı (antivirüs/proxy) self-signed sertifikası tespit edildi — Discord bağlantısı esnek TLS ile devam ediyor',
|
|
95
|
+
});
|
|
96
|
+
if (attempt < 1) return this.api(method, path, body, attempt + 1);
|
|
97
|
+
}
|
|
98
|
+
throw e;
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async _api(method, path, body) {
|
|
103
|
+
const payload = body ? JSON.stringify(body) : null;
|
|
104
|
+
const headers = { 'Content-Type': 'application/json', Authorization: 'Bot ' + this.token };
|
|
105
|
+
const url = API_BASE + path;
|
|
106
|
+
|
|
107
|
+
/* YOL 1 — Chromium ağ yığını (varsa): sistem sertifikaları + sistem proxy */
|
|
108
|
+
if (_electronNet) {
|
|
109
|
+
try {
|
|
110
|
+
const res = await _electronNet.fetch(url, {
|
|
111
|
+
method,
|
|
112
|
+
headers,
|
|
113
|
+
...(payload ? { body: payload } : {}),
|
|
114
|
+
});
|
|
115
|
+
const data = await res.text();
|
|
116
|
+
let j = null;
|
|
117
|
+
try { j = data ? JSON.parse(data) : null; } catch {}
|
|
118
|
+
if (res.ok && j !== null) return j;
|
|
119
|
+
if (j === null && looksBlocked(res.headers.get('content-type'), data)) {
|
|
120
|
+
throw new Error(VPN_HINT + bodySnippet(data));
|
|
121
|
+
}
|
|
122
|
+
throw new Error(
|
|
123
|
+
`discord ${path}: HTTP ${res.status}${j && j.message ? ' ' + j.message : ''}${bodySnippet(data)}`
|
|
124
|
+
);
|
|
125
|
+
} catch (e) {
|
|
126
|
+
/* kendi formatladığımız API hatasıysa yukarı taşı; transport hatasıysa
|
|
127
|
+
Node https yoluna düş (orada esnek TLS şansı var) */
|
|
128
|
+
if (/^discord |Discord bu ağ/.test(String((e && e.message) || ''))) throw e;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* YOL 2 — Node https (+ gerektiğinde esnek TLS) */
|
|
60
133
|
return new Promise((resolve, reject) => {
|
|
61
|
-
const payload = body ? JSON.stringify(body) : null;
|
|
62
134
|
const req = https.request(
|
|
63
|
-
|
|
135
|
+
url,
|
|
64
136
|
{
|
|
65
137
|
method,
|
|
66
138
|
headers: {
|
|
67
|
-
|
|
68
|
-
Authorization: 'Bot ' + this.token,
|
|
139
|
+
...headers,
|
|
69
140
|
...(payload ? { 'Content-Length': Buffer.byteLength(payload) } : {}),
|
|
70
141
|
},
|
|
71
142
|
timeout: 15000,
|
|
@@ -76,13 +147,17 @@ class DiscordBridge {
|
|
|
76
147
|
res.setEncoding('utf8');
|
|
77
148
|
res.on('data', (c) => (data += c));
|
|
78
149
|
res.on('end', () => {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
reject(new Error(
|
|
150
|
+
const ctype = String(res.headers['content-type'] || '');
|
|
151
|
+
let j = null;
|
|
152
|
+
try { j = data ? JSON.parse(data) : null; } catch {}
|
|
153
|
+
if (res.statusCode >= 200 && res.statusCode < 300 && j !== null) return resolve(j);
|
|
154
|
+
if (looksBlocked(ctype, data)) {
|
|
155
|
+
return reject(new Error(VPN_HINT + bodySnippet(data)));
|
|
85
156
|
}
|
|
157
|
+
if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
158
|
+
return reject(new Error(`discord ${path}: bozuk yanıt (HTTP ${res.statusCode}${ctype ? ', ' + ctype : ''})${bodySnippet(data)}`));
|
|
159
|
+
}
|
|
160
|
+
reject(new Error(`discord ${path}: HTTP ${res.statusCode} ${(j && j.message) || ''}`.trim() + bodySnippet(data)));
|
|
86
161
|
});
|
|
87
162
|
}
|
|
88
163
|
);
|
|
@@ -90,17 +165,6 @@ class DiscordBridge {
|
|
|
90
165
|
req.on('error', reject);
|
|
91
166
|
if (payload) req.write(payload);
|
|
92
167
|
req.end();
|
|
93
|
-
}).catch((e) => {
|
|
94
|
-
/* ara yazılım sertifikası tespit: esnet ve aynı isteği bir kez daha dene */
|
|
95
|
-
if (isCertError(e) && !tlsRelaxed) {
|
|
96
|
-
tlsRelaxed = true;
|
|
97
|
-
this.emit({
|
|
98
|
-
type: 'warn',
|
|
99
|
-
text: 'ağ ara yazılımı (antivirüs/proxy) self-signed sertifikası tespit edildi — Discord bağlantısı esnek TLS ile devam ediyor',
|
|
100
|
-
});
|
|
101
|
-
if (attempt < 1) return this.api(method, path, body, attempt + 1);
|
|
102
|
-
}
|
|
103
|
-
throw e;
|
|
104
168
|
});
|
|
105
169
|
}
|
|
106
170
|
|
package/src/renderer/i18n.js
CHANGED
|
@@ -215,6 +215,7 @@
|
|
|
215
215
|
it_dc_token_bad: 'Token doğrulanamadı — Developer Portal\u2019dan aldığın tokenı kontrol et',
|
|
216
216
|
it_dc_id_ph: 'Kullanıcı ID veya @kullanıcı_adı',
|
|
217
217
|
it_dc_note: 'İzin listesi boşsa kimse cevap almaz. Bot oluşturma: discord.com/developers → New Application → Bot → Token. "MESSAGE CONTENT INTENT"i AÇ (yoksa mesajlar boş gelir). Sunucu daveti: OAuth2 → bot yetkisiyle. Kendi ID\u2019ni öğrenmek için geliştirici modunu açıp kendine sağ tıkla → ID\u2019yi kopyala.',
|
|
218
|
+
it_dc_vpn: 'Türkiye\u2019de Discord erişimi zaman zaman engellenir — bağlanamıyorsan VPN açıp tekrar dene.',
|
|
218
219
|
ev_h2: 'Olay Merkezi',
|
|
219
220
|
ev_sub: 'Cron\u2019suz canlı olaylar — kaynakları aç, abonelikleri agent kendisi kurar (event_subscribe). Tetiklenen olay ilgili sohbete düşer, cevap WhatsApp\u2019a gider.',
|
|
220
221
|
ev_on: 'Olay merkezi açık',
|
|
@@ -742,6 +743,7 @@
|
|
|
742
743
|
it_dc_token_bad: 'Token could not be verified — check the token from the Developer Portal',
|
|
743
744
|
it_dc_id_ph: 'User ID or @username',
|
|
744
745
|
it_dc_note: 'Empty allow list = nobody gets a reply. Create a bot: discord.com/developers → New Application → Bot → Token. Turn ON "MESSAGE CONTENT INTENT". Invite via OAuth2 bot URL. To learn your ID: enable developer mode, right-click yourself → Copy ID.',
|
|
746
|
+
it_dc_vpn: 'Discord may be blocked on some networks — if it won\u2019t connect, turn on a VPN and retry.',
|
|
745
747
|
ev_h2: 'Event Center',
|
|
746
748
|
ev_sub: 'Live events without cron — open sources, the agent sets up subscriptions itself (event_subscribe). The triggered event drops into the relevant chat, the reply goes to WhatsApp.',
|
|
747
749
|
ev_on: 'Event center on',
|
package/src/renderer/renderer.js
CHANGED
|
@@ -1557,6 +1557,7 @@ async function renderIntegrationsPane() {
|
|
|
1557
1557
|
<div class="wa-actions" style="margin-top:6px">
|
|
1558
1558
|
<button id="dcStopBtn" class="btn ghost">${_t('it_disconnect')}</button>
|
|
1559
1559
|
</div>
|
|
1560
|
+
<div class="sub" style="margin-top:6px">ⓘ ${_t('it_dc_vpn')}</div>
|
|
1560
1561
|
<div class="divider"></div>
|
|
1561
1562
|
<label class="mem-label" style="margin-top:0">${_t('it_allow_label')} — Discord</label>
|
|
1562
1563
|
<div id="dcAllowChips" class="chips-inline"></div>
|