openclaw/scripts/list-discord-channels.ts
Shunsuke Hayashi 4d74fdf593 feat(aws): add ECS Fargate deployment for Clawdbot Discord bot
Add complete ECS Fargate infrastructure for Clawdbot Discord bot
deployment on AWS.

## Infrastructure (Terraform)
- **VPC**: 100.64.0.0/16 with DNS support
- **Public Subnets**: 2 subnets in different AZs
- **ECR Repository**: clawdbot/bot with lifecycle policy
- **IAM Roles**: Task Role (DynamoDB+S3) + Execution Role
- **ECS Resources**: Fargate (256 CPU, 2048 MB memory)
- **Security Group**: Outbound only
- **CloudWatch**: Log group with 7-day retention

## Security Improvements
- Discord Bot Token → AWS Secrets Manager
- IAM policy with least privilege principle
- No plaintext secrets in code

## Code Quality
- Fix all 22 lint errors
- Add *.d.ts to oxlint ignore patterns
- Fix Dockerfile .buildstamp for Linux compatibility

Closes #2049

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-26 13:38:43 +09:00

77 lines
2.4 KiB
JavaScript

#!/usr/bin/env node
/**
* List Discord Channels
* サーバー内の全チャンネルを一覧表示
*/
import { listGuildChannelsDiscord } from "../src/discord/send.guild.js";
import { loadConfig } from "../src/config/config.js";
import { resolveDiscordAccount } from "../src/discord/accounts.js";
import { createDiscordClient } from "../src/discord/send.shared.js";
async function main() {
const GUILD_ID = "1260121338811514880"; // PPAL Server
const cfg = loadConfig();
const accountInfo = resolveDiscordAccount({ cfg, accountId: "ppal" });
const { token } = createDiscordClient({}, cfg);
console.log(`\n📋 Discord Server: ${GUILD_ID}`);
console.log(`🤖 Bot: ${accountInfo.accountId} (${accountInfo.config.name || "PPAL Bot"})\n`);
try {
const channels = await listGuildChannelsDiscord(GUILD_ID, { token });
console.log("📺 チャンネル一覧:\n");
console.log("".padEnd(25), "タイプ".padEnd(15), "ID");
console.log("=".repeat(70));
for (const channel of channels) {
const type =
channel.type === 0 ? "テキスト" :
channel.type === 2 ? "音声" :
channel.type === 4 ? "カテゴリ" :
channel.type === 5 ? " announcements" :
channel.type === 15 ? "forum" : `type_${channel.type}`;
const indent = channel.type === 4 ? "" : " ";
console.log(
`${indent}${(channel.name || "").padEnd(25)} ` +
`${type.padEnd(15)} ` +
`${channel.id}`
);
}
console.log("\n");
// テキストチャンネルのみ抽出
const textChannels = channels.filter(ch => ch.type === 0);
console.log(`\n📝 テキストチャンネル (${textChannels.length}件):\n`);
textChannels.forEach(ch => {
console.log(` #${ch.name} → ID: ${ch.id}`);
});
console.log("\n✅ おすすめの通知チャンネル:\n");
const generalChannel = textChannels.find(ch =>
ch.name.toLowerCase().includes("general") ||
ch.name.toLowerCase().includes("通知") ||
ch.name.toLowerCase().includes("notify")
);
if (generalChannel) {
console.log(` 👉 #${generalChannel.name} (ID: ${generalChannel.id})`);
} else if (textChannels.length > 0) {
console.log(` 👉 #${textChannels[0].name} (ID: ${textChannels[0].id})`);
}
console.log("");
} catch (error: any) {
console.error("❌ エラー:", error.message);
process.exit(1);
}
}
main();