discord-bridge 0.2.0 → 0.2.1
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
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# Discord Bridge
|
|
2
|
+
# Discord Bridge ヘルスチェック(チャンネル登録込み)
|
|
3
3
|
# Usage: discord-status.sh
|
|
4
4
|
PORT="${DISCORD_BRIDGE_PORT:-13456}"
|
|
5
5
|
PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
6
6
|
CHANNEL_ID=""
|
|
7
|
+
ALLOWED_USER_IDS=""
|
|
7
8
|
if [ -n "$PROJECT_ROOT" ] && [ -f "$PROJECT_ROOT/.discord-bridge.json" ]; then
|
|
8
|
-
CHANNEL_ID=$(python3 -c "import json; print(json.load(open('$PROJECT_ROOT/.discord-bridge.json'))
|
|
9
|
+
CHANNEL_ID=$(python3 -c "import json; print(json.load(open('$PROJECT_ROOT/.discord-bridge.json')).get('channelId', ''))" 2>/dev/null)
|
|
10
|
+
ALLOWED_USER_IDS=$(python3 -c "import json; print(json.dumps(json.load(open('$PROJECT_ROOT/.discord-bridge.json')).get('allowedUserIds', [])))" 2>/dev/null)
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
# チャンネル設定をサーバーに登録
|
|
14
|
+
if [ -n "$CHANNEL_ID" ] && [ -n "$ALLOWED_USER_IDS" ]; then
|
|
15
|
+
curl -s -X POST "http://localhost:${PORT}/register-channel" \
|
|
16
|
+
-H "Content-Type: application/json" \
|
|
17
|
+
-d "{\"channelId\": \"${CHANNEL_ID}\", \"allowedUserIds\": ${ALLOWED_USER_IDS}}" > /dev/null
|
|
9
18
|
fi
|
|
10
19
|
|
|
11
20
|
if [ -n "$CHANNEL_ID" ]; then
|
package/server/index.js
CHANGED
|
@@ -14,7 +14,6 @@ import path from "path";
|
|
|
14
14
|
|
|
15
15
|
const CONFIG = {
|
|
16
16
|
token: process.env.DISCORD_BRIDGE_TOKEN,
|
|
17
|
-
allowedUserIds: [],
|
|
18
17
|
host: "127.0.0.1",
|
|
19
18
|
port: parseInt(process.env.DISCORD_BRIDGE_PORT || "13456", 10),
|
|
20
19
|
defaultTimeout: 5 * 60 * 1000,
|
|
@@ -24,17 +23,19 @@ const CONFIG = {
|
|
|
24
23
|
sseKeepAliveInterval: 30 * 1000,
|
|
25
24
|
};
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
// Per-channel allowed user IDs (registered via POST /register-channel)
|
|
27
|
+
const channelAllowedUsers = new Map();
|
|
28
|
+
|
|
29
|
+
function isAllowedUser(authorId, channelId) {
|
|
30
|
+
const allowed = channelAllowedUsers.get(channelId);
|
|
31
|
+
if (!allowed || allowed.length === 0) return true; // 未登録チャンネルは全員許可
|
|
32
|
+
return allowed.includes(authorId);
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
function validateConfig() {
|
|
32
36
|
if (!CONFIG.token) {
|
|
33
37
|
throw new Error("Missing required environment variable: DISCORD_BRIDGE_TOKEN");
|
|
34
38
|
}
|
|
35
|
-
if (CONFIG.allowedUserIds.length === 0) {
|
|
36
|
-
throw new Error("Missing required field in .discord-bridge.json: allowedUserIds (must have at least one entry)");
|
|
37
|
-
}
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
// ---------------------------------------------------------------------------
|
|
@@ -97,8 +98,8 @@ async function initDiscord() {
|
|
|
97
98
|
});
|
|
98
99
|
|
|
99
100
|
discordClient.on("messageCreate", (message) => {
|
|
100
|
-
if (!isAllowedUser(message.author.id)) return;
|
|
101
101
|
if (message.author.bot) return;
|
|
102
|
+
if (!isAllowedUser(message.author.id, message.channel.id)) return;
|
|
102
103
|
|
|
103
104
|
const chId = message.channel.id;
|
|
104
105
|
|
|
@@ -212,10 +213,25 @@ app.get("/health", (_req, res) => {
|
|
|
212
213
|
response.channel = channelId;
|
|
213
214
|
response.queuedMessages = getMessageQueue(channelId).length;
|
|
214
215
|
response.sseSubscribers = getSseSubscribers(channelId).size;
|
|
216
|
+
response.allowedUserIds = channelAllowedUsers.get(channelId) ?? [];
|
|
215
217
|
}
|
|
216
218
|
res.json(response);
|
|
217
219
|
});
|
|
218
220
|
|
|
221
|
+
// ---- POST /register-channel ----
|
|
222
|
+
app.post("/register-channel", (req, res) => {
|
|
223
|
+
const { channelId, allowedUserIds } = req.body;
|
|
224
|
+
if (!channelId) {
|
|
225
|
+
return res.status(400).json({ status: "error", error: "channelId is required" });
|
|
226
|
+
}
|
|
227
|
+
if (!Array.isArray(allowedUserIds)) {
|
|
228
|
+
return res.status(400).json({ status: "error", error: "allowedUserIds must be an array" });
|
|
229
|
+
}
|
|
230
|
+
const ids = allowedUserIds.filter((id) => typeof id === "string");
|
|
231
|
+
channelAllowedUsers.set(channelId, ids);
|
|
232
|
+
res.json({ status: "ok", channelId, allowedUserIds: ids });
|
|
233
|
+
});
|
|
234
|
+
|
|
219
235
|
// ---- GET /events (SSE) ----
|
|
220
236
|
app.get("/events", (req, res) => {
|
|
221
237
|
const channelId = req.query.channelId;
|
|
@@ -297,7 +313,8 @@ app.post("/ask", async (req, res) => {
|
|
|
297
313
|
fields,
|
|
298
314
|
});
|
|
299
315
|
|
|
300
|
-
|
|
316
|
+
const mentionUser = channelAllowedUsers.get(channelId)?.[0];
|
|
317
|
+
await sendMessage(channelId, mentionUser ? `<@${mentionUser}>` : null, [embed]);
|
|
301
318
|
|
|
302
319
|
try {
|
|
303
320
|
const reply = await waitForReply(channelId, timeoutMs);
|
|
@@ -453,25 +470,7 @@ app.get("/messages", async (req, res) => {
|
|
|
453
470
|
// Lifecycle
|
|
454
471
|
// ---------------------------------------------------------------------------
|
|
455
472
|
|
|
456
|
-
async function loadProjectConfig() {
|
|
457
|
-
const configPath = path.join(process.cwd(), ".discord-bridge.json");
|
|
458
|
-
let projectConfig;
|
|
459
|
-
try {
|
|
460
|
-
const raw = await readFile(configPath, "utf-8");
|
|
461
|
-
projectConfig = JSON.parse(raw);
|
|
462
|
-
} catch {
|
|
463
|
-
throw new Error(`.discord-bridge.json not found or invalid JSON in ${process.cwd()}`);
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
if (Array.isArray(projectConfig.allowedUserIds)) {
|
|
467
|
-
CONFIG.allowedUserIds = projectConfig.allowedUserIds.filter(
|
|
468
|
-
(id) => typeof id === "string"
|
|
469
|
-
);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
|
|
473
473
|
async function main() {
|
|
474
|
-
await loadProjectConfig();
|
|
475
474
|
validateConfig();
|
|
476
475
|
await initDiscord();
|
|
477
476
|
|