Discord サーバ運営を補助する Go 実装の Discord ボット

自分は Discord サーバの運営を行っているのですがその運営の補助をしてもらうためにボット開発を行っています。Go で Discord ボットを開発しメンバー数の推移やログ分析を行うシステムを構築している話とまたその他幾つか機能をもっていて日々の作業の効率化を図っています。この記事ではそのボットの紹介をさせて頂きます。 ※ 以前の記事 https://jedipunkz.github.io/post/discord-exporter/ の内容を含んでいます システム構成 このシステムは以下の3つの主要コンポーネントで構成されています。 Discord ボット(padawan) - Go 製の Discord ボット discord-exporter - Go 実装の Discord サーバメトリクス収集用 Prometheus Exporter 分析基盤 - DuckDB を用いた構造化ログの分析コンテナ 構成図は下記になります。Prometheus Exporter は Discord API から情報を取得し Prometheus Server にメトリクスを提供。Prometheus Server はそのメトリクスをポーリングしストレージにデータを蓄積。Grafana はそれをデータソースとして参照。padawan は Go 実装のボットで Discord API やその他ゲーム用 API 等を参照し機能提供。ボットと隣接してある DuckDB コンテナはボットのログを分析するための Go 実装の CLI を備える。 構成の詳細 ボットの構成 padawan と名前のボットとそのボットのログを分析する DuckDB コンテナで構成されています。 # padawan/docker-compose.yaml services: padawan: build: context: . dockerfile: Dockerfile volumes: - ./data:/root/data - ./logs:/logs restart: always duckdb: build: context: . dockerfile: Dockerfile.duckdb volumes: - ./logs:/logs:ro restart: "no" profiles: - tools discord-exporter の構成 Go 実装の Discord API から情報を収集する Exporter を中心とし Grafana, Prometheus Server を構成としても持っています。 ...

Claude Code から OpenCode へ移行した話

jedipunkz🚀 です。 最近、AI コーディングアシスタントとして使っていた Claude Code から OpenCode に移行しました。この記事では OpenCode の優れた機能と、なぜ移行を決めたのかの決めてを紹介します。 注記 (2025-12-28) OpenCode プロジェクトは、2024年7月に開発元の Charm 社による買収と運営方針を巡って、コントリビューター間で論争が発生しました。その後、Charm 版は Crush としてリブランドされ、現在の OpenCode は SST 組織によって https://github.com/sst/opencode で開発が継続されています。両プロジェクトは現在も別々のツールとして存在しており、この記事では SST 版の OpenCode について紹介しています。 OpenCode とは OpenCode は、ターミナルベースのオープンソース AI コーディングエージェントです。75以上の LLM プロバイダーをサポートし、高度にカスタマイズ可能なインターフェースを提供します。 公式サイト: https://opencode.ai/ 公式ドキュメント: https://opencode.ai/docs GitHub: https://github.com/opencode-ai/opencode Claude Code から移行した理由 1. 日本語入力 Claude Code では、日本語入力の変換中に文字が横にずれる現象が頻繁に発生し、非常にストレスでした。 OpenCode では、この問題が発生せず日本語入力が自然に行えます。地味ですが一番自分にとって大きいメリットだったかもしれません。 2. 柔軟なキーバインド設定 OpenCode の最大の魅力は、キーバインドを自由にカスタマイズできる点です。 日本語入力 Claude Code では、日本語入力の変換中に文字が横にずれる現象が頻繁に発生し、非常にストレスでした。 OpenCode では、この問題が発生せず、日本語入力が自然に行えます。TUI(Terminal User Interface)の実装が優れており、IME との相性も良好です。 Emacs 風のキーバインドをサポート Emacs 風のキーバインドが設定出来る点は自分にとっては大きかったです。設定せずとも自然に Emacs 風にバインドされているキーもあります。 Ctrl-a: 行頭に移動 Ctrl-e: 行末に移動 Ctrl-h: 一文字削除 Ctrl-k: カーソル位置から行末まで削除 Ctrl-f, Ctrl-b: 前後に移動 "keybinds": { "input_backspace": "backspace,shift+backspace,ctrl+h", "input_delete_to_line_end": "ctrl+k" }, Enter と Ctrl-Enter を使い分け可能 特に便利なのが、改行とメッセージ送信を分離できる点です: ...

Redirect for Infrastructure Page 35

このページは存在しないページネーション(page/35/)のためのリダイレクト設定です。 Infrastructure カテゴリの最初のページに自動的にリダイレクトされます。

Redirect for Report Page 3

このページは存在しないページネーション(page/3/)のためのリダイレクト設定です。 Report カテゴリの最初のページに自動的にリダイレクトされます。

Conftest OPA で Terraform コード開発に制約を設ける

こんにちは。jedipunkz🚀 です。 Conftest と Open Policy Agent (OPA) を使った Terraform のポリシー検証を行ったのでそれを記事にしたいと思います。ポリシを書くことで Terraform コードに制約を加え、セキュリティ要件(例えば暗号化要件やポート開放要件等) を満たしたりベストプラクティスにそったインフラを構築できます。毎回レビューで人にチェックさせるよりも確実に制約を守れるようになるのでおすすめです。 この記事では、Conftest と OPA を使って、Terraform コードに自動的にポリシーチェックを適用する方法をチュートリアル形式で解説します。 1. Conftest 概要と基本チュートリアル 1.1 Conftest とは? Conftest は、構造化された設定データに対してポリシーをテストするためのツールです。Open Policy Agent (OPA) の Rego 言語を使用してポリシーを記述し、さまざまな設定ファイルを検証できます。 Conftest の特徴 汎用性が高い Terraform(.tf、tfplan.json) Kubernetes(YAML、JSON) Dockerfile その他の JSON/YAML ファイル シンプルで軽量 単一のバイナリで動作 外部依存なし CI/CD に簡単に統合可能 OPA の Rego 言語を採用 宣言的なポリシー記述 強力なパターンマッチング テスト可能なポリシーコード なぜ Conftest が必要なのか? 従来のインフラ管理では、以下のような課題がありました。 レビューで毎回同じ指摘(「暗号化を有効にしてください」など) 人的ミスによるセキュリティホール 環境間での設定の不整合 コンプライアンス違反の見落とし Conftest を使うことで、これらの課題を解決できます。 ポリシーをコードで自動チェック デプロイ前に問題を検出 一貫したガバナンスの実現 レビュー負荷の軽減 1.2 セットアップ 1.2.1 Conftest のインストール macOS の場合: ...

Prometheus Exporter 開発で Discord サーバ運営の健全化を図る

自分は Discord でゲームコミュニティを運営していて Discord サーバを管理しています。運営のために必要な情報を集めようと思い、ボット開発や Prometheus Exporter の開発をしています。この記事では Prometheus Exporter について書こうと思います。 Discord Exporter の概要 Discord Exporter は、Discord サーバの統計情報を Prometheus メトリクスとしてエクスポートするツールです。メンバー数と各チャネルのメッセージ数を収集し Prometheus Exporter としてメトリクスを Promehteus Server に提供するものです。 https://github.com/jedipunkz/discord-exporter コードの要所説明 Discord Exporter の主要な処理を解説していきます。 Discord API 呼び出し処理 メンバー情報の取得 updateMemberCount 関数では、Discord の GuildMembers API エンドポイントを呼び出してメンバー情報を取得します。API の制限により最大1000件単位でメンバーを取得し、取得したメンバー数を Prometheus のゲージメトリクスに設定します。 func updateMemberCount(s *discordgo.Session, guildID string) { members, err := s.GuildMembers(guildID, "", 1000) if err != nil { log.Printf("Error fetching members: %v", err) return } memberCountGauge.Set(float64(len(members))) log.Printf("Updated member count: %d", len(members)) } メッセージカウント処理 countChannelMessages 関数では、チャネルのメッセージを段階的に取得します。ChannelMessages API で100件ずつメッセージを取得し、最終メッセージの ID を次のリクエストのアンカーとして使用することで、全メッセージを数え上げるまでループ処理を行います。 func countChannelMessages(s *discordgo.Session, channelID string) (int, error) { count := 0 lastID := "" for { messages, err := s.ChannelMessages(channelID, 100, lastID, "", "") if err != nil { return 0, err } if len(messages) == 0 { break } count += len(messages) lastID = messages[len(messages)-1].ID } return count, nil } メトリクス収集の実装 並行処理とレート制限 Discord API への過度な呼び出しを防ぐため、セマフォを使用した並行処理制御を実装しています。最大5チャネルを同時処理できるように制限し各ゴルーチンが処理前にセマフォを取得、完了後に解放する仕組みで効率的かつ安全に複数チャネルを並行処理します。 ...

DuckDB に入門してみた

こんにちは。jedipunkz🚀 です。 今回は DuckDB について理解したことをまとめようと思います。 DuckDB は PostgreSQL 互換の SQL を使って、JSON や CSV、Parquet などのファイルを直接クエリできるデータベースエンジンです。サーバーのセットアップが不要で、Node.js や Python などのアプリケーションに組み込んで使えるため、データ分析やログ解析の用途で注目されています。 DuckDB の特徴 DuckDB は以下の特徴を持ちます。 組み込み型データベース: サーバー不要で、プロセス内で動作 高速な分析処理: 列指向ストレージとベクトル化実行により OLAP に最適化 多様なフォーマット対応: JSON、CSV、Parquet などを直接読み込み PostgreSQL 互換 SQL: 標準的な SQL で操作可能 軽量: SQLite のように単一バイナリで動作 環境セットアップ 今回は Node.js (TypeScript) で DuckDB を使用します。 基本的なセットアップコードは以下の通りです。 :memory: を指定することで、メモリ上にデータベースを作成します。永続化が必要な場合は、ファイルパスを指定することもできます。 import duckdb from "duckdb"; import { promisify } from "util"; const db = new duckdb.Database(":memory:"); const dbAll = promisify(db.all.bind(db)); const dbClose = promisify(db.close.bind(db)); 基本的な SELECT 操作 まずは基本的な SELECT 操作から見ていきます。 サンプルデータ 従業員データを JSON ファイルで用意します (employees.json)。 [ {"id": 1, "name": "Alice", "age": 28, "department": "Sales", "salary": 50000}, {"id": 2, "name": "Bob", "age": 35, "department": "Engineering", "salary": 75000}, {"id": 3, "name": "Charlie", "age": 42, "department": "Sales", "salary": 65000}, {"id": 4, "name": "Diana", "age": 31, "department": "Engineering", "salary": 80000}, {"id": 5, "name": "Eve", "age": 29, "department": "HR", "salary": 55000} ] クエリ実行 DuckDB では、JSON ファイルを直接 FROM 句で指定できます。 ポイントは、CREATE TABLE などの事前準備なしに、ファイルパスを指定するだけでクエリを実行できる点です。DuckDB が自動的にスキーマを推論し、データを読み込みます。 ...

Zig 入門: 構文集

こんにちは @jedipunkz です。 コーディングを学習する機会を増やしている最中なのですが、自分は底レイヤが好きなのを思い出し、またたまに Mitchell Hashimoto 氏が Zig のことを呟いてるのを覚えていたので、突然 Zig に入門したくなりました。 ということで後に自分でも読み返せる形にしようと思い Zig の構文集を記します。 NOTICE ※ 現時点で Stable な 0.15.1 を前提に記します。 ※ 気が向いたときに言語仕様の変化に対応して修正していこうと思います。 はじめに このドキュメントは、Zig 言語の主要な構文を網羅的にまとめたチュートリアルです。すべてのサンプルコードは記事の修正時点で Stable なリリースバージョンの Zig で動作確認しています。 目次 基本構文 演算子 制御構文 関数 配列とスライス 構造体 列挙型とユニオン ポインタ エラーハンドリング オプショナル型 コンパイル時計算 メモリアロケータ テスト モジュール 1. 基本構文 変数宣言 Zig には 2 種類の変数宣言があります。const は不変変数(再代入不可)、var は可変変数(再代入可能)を表します。 const cat: i32 = 5; // const: 不変変数(再代入不可) var dog: i32 = 10; // var: 可変変数(再代入可能) dog = 15; // OK // cat = 10; // エラー: const は変更不可 型推論 型を明示的に指定しなくても、コンパイラが自動的に型を推論してくれます。 ...