discord-bridge 0.1.5 → 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/README.md +6 -4
- package/package.json +1 -1
- package/plugin/skills/discord-comm/scripts/discord-status.sh +11 -2
- package/server/index.js +30 -11
package/README.md
CHANGED
|
@@ -100,7 +100,6 @@ npm update -g discord-bridge
|
|
|
100
100
|
|
|
101
101
|
```bash
|
|
102
102
|
export DISCORD_BRIDGE_TOKEN="your_bot_token_here"
|
|
103
|
-
export DISCORD_BRIDGE_USER_ID="your_user_id_here"
|
|
104
103
|
```
|
|
105
104
|
|
|
106
105
|
設定後、`source ~/.zshrc` で反映してください(新しいターミナルを開く場合は不要です)。
|
|
@@ -111,11 +110,14 @@ Claude Code / Codex CLI を使うプロジェクトのルートに `.discord-bri
|
|
|
111
110
|
|
|
112
111
|
```json
|
|
113
112
|
{
|
|
114
|
-
"channelId": "your_channel_id_here"
|
|
113
|
+
"channelId": "your_channel_id_here",
|
|
114
|
+
"allowedUserIds": ["your_user_id_here"]
|
|
115
115
|
}
|
|
116
116
|
```
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
`allowedUserIds` に複数のユーザー ID を指定すると、全員の発言に応答します。1人目のユーザーが質問通知(`/ask`)のメンション対象になります。
|
|
119
|
+
|
|
120
|
+
> **Note**: `channelId` と `allowedUserIds` は秘密情報ではありませんが、プロジェクト固有の設定です。チームで共有する場合はそのままコミットし、個人用の場合は `.gitignore` に追加してください。
|
|
119
121
|
|
|
120
122
|
### 4. スキルのインストール
|
|
121
123
|
|
|
@@ -190,7 +192,7 @@ Discord で「戻ったよ」と伝えます。
|
|
|
190
192
|
| Bot がオフライン | `DISCORD_BRIDGE_TOKEN` が正しいか |
|
|
191
193
|
| メッセージが届かない | MESSAGE CONTENT INTENT が有効か |
|
|
192
194
|
| チャンネルが見つからない | `.discord-bridge.json` の `channelId` が正しいか |
|
|
193
|
-
| 返答が受信されない | `
|
|
195
|
+
| 返答が受信されない | `.discord-bridge.json` の `allowedUserIds` が正しいか |
|
|
194
196
|
|
|
195
197
|
## ライセンス
|
|
196
198
|
|
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
|
-
userId: process.env.DISCORD_BRIDGE_USER_ID,
|
|
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,14 +23,18 @@ const CONFIG = {
|
|
|
24
23
|
sseKeepAliveInterval: 30 * 1000,
|
|
25
24
|
};
|
|
26
25
|
|
|
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);
|
|
33
|
+
}
|
|
34
|
+
|
|
27
35
|
function validateConfig() {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if (!CONFIG.userId) missing.push("DISCORD_BRIDGE_USER_ID");
|
|
31
|
-
if (missing.length > 0) {
|
|
32
|
-
throw new Error(
|
|
33
|
-
`Missing required environment variables: ${missing.join(", ")}`
|
|
34
|
-
);
|
|
36
|
+
if (!CONFIG.token) {
|
|
37
|
+
throw new Error("Missing required environment variable: DISCORD_BRIDGE_TOKEN");
|
|
35
38
|
}
|
|
36
39
|
}
|
|
37
40
|
|
|
@@ -95,8 +98,8 @@ async function initDiscord() {
|
|
|
95
98
|
});
|
|
96
99
|
|
|
97
100
|
discordClient.on("messageCreate", (message) => {
|
|
98
|
-
if (message.author.id !== CONFIG.userId) return;
|
|
99
101
|
if (message.author.bot) return;
|
|
102
|
+
if (!isAllowedUser(message.author.id, message.channel.id)) return;
|
|
100
103
|
|
|
101
104
|
const chId = message.channel.id;
|
|
102
105
|
|
|
@@ -210,10 +213,25 @@ app.get("/health", (_req, res) => {
|
|
|
210
213
|
response.channel = channelId;
|
|
211
214
|
response.queuedMessages = getMessageQueue(channelId).length;
|
|
212
215
|
response.sseSubscribers = getSseSubscribers(channelId).size;
|
|
216
|
+
response.allowedUserIds = channelAllowedUsers.get(channelId) ?? [];
|
|
213
217
|
}
|
|
214
218
|
res.json(response);
|
|
215
219
|
});
|
|
216
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
|
+
|
|
217
235
|
// ---- GET /events (SSE) ----
|
|
218
236
|
app.get("/events", (req, res) => {
|
|
219
237
|
const channelId = req.query.channelId;
|
|
@@ -295,7 +313,8 @@ app.post("/ask", async (req, res) => {
|
|
|
295
313
|
fields,
|
|
296
314
|
});
|
|
297
315
|
|
|
298
|
-
|
|
316
|
+
const mentionUser = channelAllowedUsers.get(channelId)?.[0];
|
|
317
|
+
await sendMessage(channelId, mentionUser ? `<@${mentionUser}>` : null, [embed]);
|
|
299
318
|
|
|
300
319
|
try {
|
|
301
320
|
const reply = await waitForReply(channelId, timeoutMs);
|
|
@@ -428,7 +447,7 @@ app.get("/messages", async (req, res) => {
|
|
|
428
447
|
const ch = await fetchChannel(channelId);
|
|
429
448
|
const fetched = await ch.messages.fetch({ limit: remaining });
|
|
430
449
|
const history = fetched
|
|
431
|
-
.filter((m) => m.author.id
|
|
450
|
+
.filter((m) => isAllowedUser(m.author.id) && !m.author.bot)
|
|
432
451
|
.map((m) => ({
|
|
433
452
|
content: m.content,
|
|
434
453
|
attachments: m.attachments.map((a) => ({
|