Conversation
feat 公式グローバルチャットを追加 feat: Redisを追加
📝 WalkthroughWalkthroughRedis を導入し、ボット側でメッセージ送信・編集・削除のグローバル中継を実装。API 起動時にデフォルトルームとオーナー紐付けを初期化し、Docker Compose と開発スクリプトを追加。ダッシュボードにルーム説明を表示。 Changes
Sequence Diagram(s)sequenceDiagram
participant User as User
participant Bot as Source Bot
participant Redis as Redis
participant Webhook as Destination Webhook
participant API as API
User->>Bot: メッセージ送信
Bot->>Bot: ルーム検証・整形
Bot->>Webhook: Webhookで送信 (wait)
Webhook-->>Bot: message_id / ack
Bot->>Redis: 保存 (gc:{room}:msg:{mid} -> {webhook_url, message_id})
Bot->>API: 必要に応じルーム/統計更新
Note over Bot,Redis: 編集/削除の同期フロー
User->>Bot: メッセージ編集
Bot->>Redis: 保存済み webhook 情報取得
Bot->>Webhook: 対応メッセージを編集
Bot->>API: 編集通知(中継 JSON)
User->>Bot: メッセージ削除
Bot->>Redis: 保存済み webhook 情報取得
Bot->>Webhook: 対応メッセージを削除
Bot->>Redis: キー削除
Bot->>API: 削除通知(中継 JSON)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 14
🧹 Nitpick comments (6)
src/dashboard/src/app/dashboard/[guildId]/globalchat/GlobalChatClient.tsx (1)
259-260: 公式ルーム名の固定文字列は単一ソース化を推奨しますLine 259-260 の
main, sgc, dsgc, ads, shiritori, artは、バックエンドのデフォルトルーム定義(src/api/src/cmd/main.goLine 41-125)と二重管理です。将来的な追加/改名時にUI表示だけズレるため、API取得または共有定数化に寄せるのが安全です。🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/dashboard/src/app/dashboard/`[guildId]/globalchat/GlobalChatClient.tsx around lines 259 - 260, GlobalChatClient.tsx にハードコーディングされている部屋名文字列 ("main, sgc, dsgc, ads, shiritori, art") をそのまま表示する代わりに、UI がバックエンド定義と常に一致するように単一ソース化してください。具体的には GlobalChatClient コンポーネント内の該当テキストを削除し、バックエンドのデフォルトルーム定義を返す API を呼び出して表示する(例: GET でデフォルトルーム一覧を取得する)か、プロジェクト共通の定数(例: DEFAULT_ROOMS / defaultRooms 配列)を新規作成してインポートする方法のいずれかを採用し、表示箇所はその取得結果を map/join してレンダリングするように修正してください。src/bot/cogs/globalchat.py (1)
97-105: (任意)例外処理をより具体的にすることを検討してください。
_edit_webhook_messageでExceptionをキャッチしていますが、discord.HTTPExceptionなど、より具体的な例外をキャッチすることで、予期しないエラーを早期に検出できます。_delete_webhook_messageでのNotFoundとForbiddenの明示的なハンドリングは良いパターンです。🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/bot/cogs/globalchat.py` around lines 97 - 105, _edit_webhook_message currently catches a blanket Exception; change it to handle specific discord errors (e.g., catch discord.NotFound and discord.Forbidden like in _delete_webhook_message, and catch discord.HTTPException and asyncio.TimeoutError for request failures) around the webhook creation and webhook.edit_message call; log detailed context (dest["message_id"], webhook URL or identifier) for each specific except block and re-raise or let unexpected exceptions bubble so truly unexpected errors are not silently swallowed.src/bot/cogs/sgc.py (4)
197-204: bareexcept:を使用せず、適切な例外をキャッチしてください。history ループ内での JSON パースエラーは
json.JSONDecodeErrorを明示的にキャッチすべきです。また、except: continueは1行に収めず、可読性のために分けることを推奨します。🔧 修正案
async for past_message in message.channel.history(limit=100): try: p_dic = json.loads(past_message.content) if p_dic.get("messageId") == str(ref_mid): ref_author = f"{p_dic.get('userName')}#{p_dic.get('userDiscriminator')}" ref_content = p_dic.get("content", "内容なし") break - except: continue + except json.JSONDecodeError: + continue🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/bot/cogs/sgc.py` around lines 197 - 204, Replace the bare except in the history loop around json.loads(past_message.content) with an explicit catch for json.JSONDecodeError (i.e., wrap json.loads in try/except json.JSONDecodeError) and move the continue onto its own line for readability; ensure this change is applied where json.loads(...) is called in the message.channel.history async for loop (inside sgc.py) so only JSON parsing errors are suppressed and other exceptions are allowed to surface.
17-18: チャンネル ID を環境変数に移動することを検討してください。
DEBUGとMAINのチャンネル ID がハードコードされています。環境変数または設定ファイルに移動することで、環境ごとの切り替えが容易になります。🔧 修正案
def __init__(self, bot: NewSharkBot): self.bot = bot self.msg_expiry = 86400 - self.DEBUG = 707158343952629780 - self.MAIN = 707158257818664991 + self.DEBUG = int(os.environ.get("SGC_DEBUG_CHANNEL_ID", "707158343952629780")) + self.MAIN = int(os.environ.get("SGC_MAIN_CHANNEL_ID", "707158257818664991")) print("init -> SuperGlobalChatCog")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/bot/cogs/sgc.py` around lines 17 - 18, Replace the hardcoded channel IDs assigned to self.DEBUG and self.MAIN in the SGC class with values read from environment variables (e.g., SGC_DEBUG_CHANNEL_ID and SGC_MAIN_CHANNEL_ID); use os.getenv to read them, convert to int before assignment, and provide a sensible fallback (either the current literal IDs or raise a clear error) so runtime behavior is preserved and environments can override the IDs. Ensure the change is made where self.DEBUG and self.MAIN are defined so all references continue to work.
316-330: bareexcept:を使用せず、エラーをログに記録してください。webhook 操作の例外を握りつぶすと、デバッグが困難になります。最低限、例外をログに記録することを推奨します。
🔧 修正案
try: webhooks = await channel_obj.webhooks() webhook = discord.utils.get(webhooks, name="SharkBot-GlobalChat") if not webhook: webhook = await channel_obj.create_webhook(name="SharkBot-GlobalChat") await self.bot.api.globalchat_update_connect_channel( channel_id=str(channel_id), guild_id=str(guild_id), room_name=channel_info["room_name"], webhook_url=webhook.url ) return webhook.url - except: + except Exception as e: + logging.error(f"Failed to fix webhook for channel {channel_id}: {e}") return None🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/bot/cogs/sgc.py` around lines 316 - 330, Replace the bare except in the webhook creation/update block with a proper exception handler: catch Exception as e (e.g. except Exception as e:) and log the error before returning None; for example call self.logger.exception or self.bot.logger.exception with a descriptive message referencing the failing operation (e.g. when calling channel_obj.webhooks(), channel_obj.create_webhook(...) or self.bot.api.globalchat_update_connect_channel(...)) so the exception and stack trace are recorded, then return None as before.
332-332: (任意)型ヒントを PEP 484 に準拠させてください。
sgc_data: dict = Noneとref_info: dict = Noneは暗黙的なOptionalを使用しています。明示的にdict | None = NoneまたはOptional[dict] = Noneと記述することを推奨します。同様に358行目のsend_webhookも同じ問題があります。🔧 修正案
- async def relay_message(self, message: discord.Message, config: dict, room: dict, isother_bot: bool = False, sgc_data: dict = None, ref_info: dict = None): + async def relay_message(self, message: discord.Message, config: dict, room: dict, isother_bot: bool = False, sgc_data: dict | None = None, ref_info: dict | None = None):🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/bot/cogs/sgc.py` at line 332, Change implicit Optional dict type hints to explicit PEP 484 forms: update function signatures like relay_message(...) where parameters are declared as sgc_data: dict = None and ref_info: dict = None to either sgc_data: dict | None = None and ref_info: dict | None = None (for Python 3.10+) or sgc_data: Optional[dict] = None and ref_info: Optional[dict] = None and add "from typing import Optional" (for older versions); do the same change for send_webhook's parameters that use the implicit Optional pattern so all optional dict types are explicitly annotated.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@dev.sh`:
- Around line 1-2: Add a POSIX bash shebang and fail-fast settings to the top of
the script: prepend "#!/usr/bin/env bash" and "set -euo pipefail" to dev.sh (and
mirror the same change in run.sh) so the existing commands (sudo docker compose
build bot api and sudo docker compose up bot redis api) run with defined shell
semantics and exit on errors/unset variables/pipe failures.
In `@docker-compose.yaml`:
- Around line 18-20: Add a healthcheck block to the redis service (e.g.,
healthcheck: with test ["CMD", "redis-cli", "ping"], interval, timeout, retries,
start_period) so Docker can report when redis is healthy, and update the bot
service's depends_on to the conditional form using condition: service_healthy
for redis (replace the simple list entry "- redis" with a depends_on mapping
referencing redis: condition: service_healthy) so bot waits until redis reports
healthy before starting.
- Line 59: Change the redis image from the floating tag to a fixed version
(e.g., replace "image: redis:latest" with a specific major.minor[.patch] tag
such as "redis:7.2") and add a proper healthcheck to the redis service (similar
to the postgres healthcheck pattern) so the container reports healthy only when
ready; then update the bot service's depends_on to use condition:
service_healthy for the "redis" dependency (i.e., ensure the "redis" service has
a healthcheck and the "bot" service lists redis under depends_on with condition:
service_healthy).
In `@src/api/src/cmd/main.go`:
- Around line 232-233: InitDefaultRooms currently returns an error but its
return value is ignored where it’s called with InitDefaultRooms(db,
config.OWNER_ID); update the call site to capture the error (err :=
InitDefaultRooms(db, config.OWNER_ID)) and handle it: if non-nil, log the error
(including the error value) via the existing logger and decide whether to exit
the process (e.g., os.Exit(1)) or return the error up the call chain so startup
aborts; ensure you reference InitDefaultRooms, db and config.OWNER_ID when
making the change so the correct call is updated.
In `@src/bot/cogs/globalchat.py`:
- Around line 138-142: The code calls
self.bot.redis.delete(f"gc:{name}:msg:{message.id}") twice (once inside the if
tasks: block and once immediately after), causing redundant Redis deletes;
remove the duplicate so the key is deleted exactly once after any awaited tasks.
Update the method in the GlobalChat cog where the tasks list is handled (the if
tasks: block and the following line) to ensure only a single call to
self.bot.redis.delete(f"gc:{name}:msg:{message.id}") remains (preferably the one
after awaiting asyncio.gather), and remove the other occurrence.
- Around line 300-305: relay_message 内で self.bot.redis の存在チェックが抜けており、Redis 未利用時に
AttributeError が発生する可能性があります。修正は relay_message 関数の先頭で if not self.bot.redis:
ロギングして早期 return するか、relay_message を呼ぶ前(例: on_message リスナー内)で同様の存在チェックを行って
redis.set を呼ばないようにしてください;参照箇所は relay_message、on_message_edit、on_message_delete と
self.bot.redis / redis.set 呼び出しです。
In `@src/bot/cogs/sgc.py`:
- Around line 183-186: Replace the bare except around
json.loads(message.content) with an explicit JSONDecodeError handler: catch
json.JSONDecodeError (e.g., except json.JSONDecodeError as e:) instead of a bare
except so only JSON parsing failures are handled; keep the same behavior of
returning on error (and optionally log or debug the exception using the variable
e). Ensure the try block still assigns dic from json.loads(message.content).
- Around line 374-381: The conditional currently checks ref_info.get('author')
twice; change it to verify both keys exist (e.g., ref_info.get('author') and
ref_info.get('content')) before constructing re_embed and appending to embeds so
you only build the discord.Embed when both author and content are present (look
for the block that creates re_embed and appends to embeds in sgc.py).
- Around line 50-55: The code assumes message.author.primary_guild is not None
when accessing .tag/.badge/.id; change the block around the dict population (in
sgc.py where message.author.primary_guild is referenced) to first assign the
value to a local (e.g., pg = message.author.primary_guild) and guard with if pg
(or if pg and pg.tag) before using pg.tag, pg.badge.key, and pg.id so you avoid
AttributeError when primary_guild is None.
- Around line 219-228: The edit branch calls self.bot.redis.get without ensuring
a Redis client exists; add a guard before using Redis in the m_type == "edit"
branch (and mirror the same check in the m_type == "delete" branch) inside
on_message_others_bot: if self.bot.redis is falsy (e.g., None) skip the Redis
logic or return early, so you don't call .get on a missing client; apply this
check around the calls that use self.bot.redis (refer to the m_type == "edit"
block that calls self.bot.redis.get and the delete block that similarly uses
Redis) and only proceed to json.loads and _edit_webhook_message/_delete handling
when the Redis client is present.
In `@src/bot/main.py`:
- Around line 81-87: 現在の Redis 初期化は on_ready のみで行っており競合が発生するため、setup_hook 内で必ず
Redis クライアントを初期化して bot.redis を設定するよう移動してください(参照: setup_hook、bot.redis、Cog
側アクセス箇所 e.g. src/bot/cogs/sgc.py and src/bot/cogs/globalchat.py)。on_ready は
Redis 接続の疎通確認と例外処理のみに限定し、既に初期化済みなら再初期化しないようにしてください。またクラスの close()
実装では親クラスのクリーンアップを確実に行うため最後に await super().close()(または super().close() が同期なら
super().close() を呼ぶ)を追加してください。
- Around line 39-46: The custom close() currently closes Redis and the aiohttp
session but omits calling the parent cleanup; update the close method (async def
close(self):) to call await super().close() at the end so the Bot/AutoShardedBot
teardown (WebSocket/gateway cleanup) runs—ensure this call occurs after closing
self.redis and self.session and handle any exceptions consistently with existing
cleanup logic.
In `@src/dashboard/src/app/dashboard/`[guildId]/globalchat/GlobalChatClient.tsx:
- Line 257: The div in GlobalChatClient.tsx uses an undefined Tailwind class
"back-gray" (className="back-gray text-black rounded-lg"); fix this by replacing
"back-gray" with a valid Tailwind background class such as "bg-gray-100" (or
another appropriate bg-* utility) or add a corresponding custom CSS class in
your stylesheet and reference that class name; update the className on the div
in GlobalChatClient.tsx where "back-gray" appears to apply the correct
background styling.
In `@src/dashboard/src/constants/gc/default_gc.ts`:
- Around line 54-56: The UserIds constant currently hardcodes the owner ID
(UserIds with key "owner"), which duplicates OWNER_ID in docker-compose; change
it to fetch the owner ID from a single source (e.g., environment injection or
shared config) instead of a literal string: replace the hardcoded value in
UserIds (or convert UserIds into a getter/function) to read from the centralized
config or process.env (OWNER_ID) and fall back to a safe default or throw if
missing; ensure references to UserIds["owner"] throughout the code continue to
work with the new getter/lookup approach.
---
Nitpick comments:
In `@src/bot/cogs/globalchat.py`:
- Around line 97-105: _edit_webhook_message currently catches a blanket
Exception; change it to handle specific discord errors (e.g., catch
discord.NotFound and discord.Forbidden like in _delete_webhook_message, and
catch discord.HTTPException and asyncio.TimeoutError for request failures)
around the webhook creation and webhook.edit_message call; log detailed context
(dest["message_id"], webhook URL or identifier) for each specific except block
and re-raise or let unexpected exceptions bubble so truly unexpected errors are
not silently swallowed.
In `@src/bot/cogs/sgc.py`:
- Around line 197-204: Replace the bare except in the history loop around
json.loads(past_message.content) with an explicit catch for json.JSONDecodeError
(i.e., wrap json.loads in try/except json.JSONDecodeError) and move the continue
onto its own line for readability; ensure this change is applied where
json.loads(...) is called in the message.channel.history async for loop (inside
sgc.py) so only JSON parsing errors are suppressed and other exceptions are
allowed to surface.
- Around line 17-18: Replace the hardcoded channel IDs assigned to self.DEBUG
and self.MAIN in the SGC class with values read from environment variables
(e.g., SGC_DEBUG_CHANNEL_ID and SGC_MAIN_CHANNEL_ID); use os.getenv to read
them, convert to int before assignment, and provide a sensible fallback (either
the current literal IDs or raise a clear error) so runtime behavior is preserved
and environments can override the IDs. Ensure the change is made where
self.DEBUG and self.MAIN are defined so all references continue to work.
- Around line 316-330: Replace the bare except in the webhook creation/update
block with a proper exception handler: catch Exception as e (e.g. except
Exception as e:) and log the error before returning None; for example call
self.logger.exception or self.bot.logger.exception with a descriptive message
referencing the failing operation (e.g. when calling channel_obj.webhooks(),
channel_obj.create_webhook(...) or
self.bot.api.globalchat_update_connect_channel(...)) so the exception and stack
trace are recorded, then return None as before.
- Line 332: Change implicit Optional dict type hints to explicit PEP 484 forms:
update function signatures like relay_message(...) where parameters are declared
as sgc_data: dict = None and ref_info: dict = None to either sgc_data: dict |
None = None and ref_info: dict | None = None (for Python 3.10+) or sgc_data:
Optional[dict] = None and ref_info: Optional[dict] = None and add "from typing
import Optional" (for older versions); do the same change for send_webhook's
parameters that use the implicit Optional pattern so all optional dict types are
explicitly annotated.
In `@src/dashboard/src/app/dashboard/`[guildId]/globalchat/GlobalChatClient.tsx:
- Around line 259-260: GlobalChatClient.tsx にハードコーディングされている部屋名文字列 ("main, sgc,
dsgc, ads, shiritori, art") をそのまま表示する代わりに、UI
がバックエンド定義と常に一致するように単一ソース化してください。具体的には GlobalChatClient
コンポーネント内の該当テキストを削除し、バックエンドのデフォルトルーム定義を返す API を呼び出して表示する(例: GET
でデフォルトルーム一覧を取得する)か、プロジェクト共通の定数(例: DEFAULT_ROOMS / defaultRooms
配列)を新規作成してインポートする方法のいずれかを採用し、表示箇所はその取得結果を map/join してレンダリングするように修正してください。
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: eaefc3e8-1c27-42ee-80f7-1c2083817897
⛔ Files ignored due to path filters (2)
src/api/src/go.sumis excluded by!**/*.sumsrc/bot/uv.lockis excluded by!**/*.lock
📒 Files selected for processing (11)
dev.shdocker-compose.yamlsrc/api/src/cmd/main.gosrc/api/src/go.modsrc/api/src/internal/config.gosrc/bot/cogs/globalchat.pysrc/bot/cogs/sgc.pysrc/bot/main.pysrc/bot/pyproject.tomlsrc/dashboard/src/app/dashboard/[guildId]/globalchat/GlobalChatClient.tsxsrc/dashboard/src/constants/gc/default_gc.ts
| sudo docker compose build bot api | ||
| sudo docker compose up bot redis api No newline at end of file |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# 先頭行と shebang 有無を確認
sed -n '1,5p' dev.shRepository: SharkBot-Dev/NewSharkBot
Length of output: 138
🏁 Script executed:
# Find all shell scripts in the repository
find . -type f -name "*.sh" | head -20Repository: SharkBot-Dev/NewSharkBot
Length of output: 138
🏁 Script executed:
# Check if dev.sh is referenced in any configuration files (Makefile, GitHub Actions, etc.)
rg -l "dev\.sh" --type json --type yaml --type toml --type makefileRepository: SharkBot-Dev/NewSharkBot
Length of output: 100
🏁 Script executed:
# Look at other shell scripts to see if they have shebangs
find . -type f -name "*.sh" -exec head -1 {} \; -print | head -40Repository: SharkBot-Dev/NewSharkBot
Length of output: 244
🏁 Script executed:
# Check run.sh content (first 5 lines)
head -5 run.shRepository: SharkBot-Dev/NewSharkBot
Length of output: 118
🏁 Script executed:
# Search for references to how dev.sh should be executed
rg "dev\.sh" -A 2 -B 2Repository: SharkBot-Dev/NewSharkBot
Length of output: 50
🏁 Script executed:
# Check README for usage instructions
find . -type f \( -name "README*" -o -name "readme*" \) -exec cat {} \;Repository: SharkBot-Dev/NewSharkBot
Length of output: 2734
シェバンと fail-fast 設定を追加してください
dev.sh と同じく run.sh も実行シェルが不明で、エラー時の継続実行が発生します。先頭に #!/usr/bin/env bash と set -euo pipefail を追加すると、ポータビリティとエラーハンドリングが改善されます。
修正案
+#!/usr/bin/env bash
+set -euo pipefail
+
sudo docker compose build bot api
sudo docker compose up bot redis api📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| sudo docker compose build bot api | |
| sudo docker compose up bot redis api | |
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| sudo docker compose build bot api | |
| sudo docker compose up bot redis api |
🧰 Tools
🪛 Shellcheck (0.11.0)
[error] 1-1: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.
(SC2148)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@dev.sh` around lines 1 - 2, Add a POSIX bash shebang and fail-fast settings
to the top of the script: prepend "#!/usr/bin/env bash" and "set -euo pipefail"
to dev.sh (and mirror the same change in run.sh) so the existing commands (sudo
docker compose build bot api and sudo docker compose up bot redis api) run with
defined shell semantics and exit on errors/unset variables/pipe failures.
| InitDefaultRooms(db, config.OWNER_ID) | ||
|
|
There was a problem hiding this comment.
InitDefaultRooms のエラーハンドリングが欠落しています。
InitDefaultRooms は error を返しますが、戻り値が無視されています。デフォルトルームの初期化が失敗した場合、サーバーは起動しますが、ルームが存在しない状態で動作する可能性があります。
🔧 修正案
- InitDefaultRooms(db, config.OWNER_ID)
+ if err := InitDefaultRooms(db, config.OWNER_ID); err != nil {
+ log.Printf("Warning: Failed to initialize default rooms: %v", err)
+ }または、起動を中断する場合:
- InitDefaultRooms(db, config.OWNER_ID)
+ if err := InitDefaultRooms(db, config.OWNER_ID); err != nil {
+ panic(fmt.Sprintf("failed to initialize default rooms: %v", err))
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| InitDefaultRooms(db, config.OWNER_ID) | |
| if err := InitDefaultRooms(db, config.OWNER_ID); err != nil { | |
| panic(fmt.Sprintf("failed to initialize default rooms: %v", err)) | |
| } | |
| InitDefaultRooms(db, config.OWNER_ID) | |
| if err := InitDefaultRooms(db, config.OWNER_ID); err != nil { | |
| log.Printf("Warning: Failed to initialize default rooms: %v", err) | |
| } | |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/api/src/cmd/main.go` around lines 232 - 233, InitDefaultRooms currently
returns an error but its return value is ignored where it’s called with
InitDefaultRooms(db, config.OWNER_ID); update the call site to capture the error
(err := InitDefaultRooms(db, config.OWNER_ID)) and handle it: if non-nil, log
the error (including the error value) via the existing logger and decide whether
to exit the process (e.g., os.Exit(1)) or return the error up the call chain so
startup aborts; ensure you reference InitDefaultRooms, db and config.OWNER_ID
when making the change so the correct call is updated.
| if not bot.redis: | ||
| pool = ConnectionPool.from_url("redis://redis:6379/0", decode_responses=True) | ||
| bot.redis = Redis(connection_pool=pool) | ||
|
|
||
| if bot.redis: | ||
| await bot.redis.set("bot_status", "online") | ||
| print("Redis status updated.") |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Redis 初期化位置と、Cog側の未ガード参照を確認
rg -n 'ConnectionPool\.from_url|bot\.redis|async def on_ready|async def setup_hook' src/bot/main.py -C3
rg -nP 'self\.bot\.redis\.(get|set|delete)\(' src/bot/cogs -C2Repository: SharkBot-Dev/NewSharkBot
Length of output: 4436
🏁 Script executed:
# bot.redis の初期値確認
rg -n 'class.*bot|self\.redis|bot\.redis\s*=' src/bot/main.py -B2 -A2 | head -40
cat -n src/bot/main.py | head -65Repository: SharkBot-Dev/NewSharkBot
Length of output: 2778
Redis 初期化を on_ready のみで行うと競合が発生します
Line 81-87 の初期化だと、setup_hook で Cog が登録された直後、ログイン前に他のイベントが到達した場合、self.bot.redis が None のまま Cog 側から未ガードでアクセスされます(src/bot/cogs/sgc.py L107, 144, 158, 220, 234, 239, 356 および src/bot/cogs/globalchat.py L84, 128, 140, 142, 301)。setup_hook で Redis クライアントを初期化し、on_ready は疎通確認と例外処理に専念してください。
また、L39-42 の close() メソッドで super().close() を呼び出していません。親クラスの適切なシャットダウン処理がスキップされるため、必ず呼び出してください。
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/bot/main.py` around lines 81 - 87, 現在の Redis 初期化は on_ready
のみで行っており競合が発生するため、setup_hook 内で必ず Redis クライアントを初期化して bot.redis
を設定するよう移動してください(参照: setup_hook、bot.redis、Cog 側アクセス箇所 e.g. src/bot/cogs/sgc.py
and src/bot/cogs/globalchat.py)。on_ready は Redis
接続の疎通確認と例外処理のみに限定し、既に初期化済みなら再初期化しないようにしてください。またクラスの close()
実装では親クラスのクリーンアップを確実に行うため最後に await super().close()(または super().close() が同期なら
super().close() を呼ぶ)を追加してください。
| export const UserIds = { | ||
| "owner": "1335428061541437531" | ||
| } No newline at end of file |
There was a problem hiding this comment.
owner IDのハードコードは分離してください
Line 54-56 の固定値は、docker-compose.yaml の OWNER_ID と重複管理になっており、環境ごとの差し替え時に不整合を招きます。APIレスポンスまたは環境注入(共通設定)から取得する形に寄せるのが安全です。
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/dashboard/src/constants/gc/default_gc.ts` around lines 54 - 56, The
UserIds constant currently hardcodes the owner ID (UserIds with key "owner"),
which duplicates OWNER_ID in docker-compose; change it to fetch the owner ID
from a single source (e.g., environment injection or shared config) instead of a
literal string: replace the hardcoded value in UserIds (or convert UserIds into
a getter/function) to read from the centralized config or process.env (OWNER_ID)
and fall back to a safe default or throw if missing; ensure references to
UserIds["owner"] throughout the code continue to work with the new getter/lookup
approach.
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
src/bot/cogs/sgc.py (1)
332-332: 型ヒントでOptionalを明示してください。PEP 484 に準拠し、デフォルト値が
NoneのパラメータにはOptional[T]またはT | Noneを使用してください。♻️ 修正案
- async def relay_message(self, message: discord.Message, config: dict, room: dict, isother_bot: bool = False, sgc_data: dict = None, ref_info: dict = None): + async def relay_message(self, message: discord.Message, config: dict, room: dict, isother_bot: bool = False, sgc_data: Optional[dict] = None, ref_info: Optional[dict] = None): - async def send_webhook(self, url: str, message: discord.Message, isother_bot: bool, sgc_data: dict = None, ref_info: dict = None): + async def send_webhook(self, url: str, message: discord.Message, isother_bot: bool, sgc_data: Optional[dict] = None, ref_info: Optional[dict] = None):Also applies to: 358-358
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/bot/cogs/sgc.py` at line 332, 関数 relay_message のシグネチャでデフォルト値が None のパラメータ sgc_data と ref_info に型ヒントが明示されていないため、PEP 484 準拠で Optional を使って型を明示してください;具体的には relay_message の定義を見つけて sgc_data: Optional[dict] または dict | None、ref_info: Optional[dict] または dict | None のいずれかの表記で修正し、必要なら from typing import Optional をインポートしてください(また同様の修正を別の位置で同関数のオーバーロードや同ファイル内の定義があれば合わせて行ってください)。
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/bot/cogs/sgc.py`:
- Around line 353-356: relay_message currently calls self.bot.redis.set(...)
unguarded which raises AttributeError when Redis isn't available; before calling
self.bot.redis.set (after computing msg_id and synced_data), add the same
Redis-availability guard used in globalchat.py — e.g. check getattr(self.bot,
"redis", None) (or hasattr(self.bot, "redis") and self.bot.redis) and that it
has a callable set method, then call
self.bot.redis.set(f"gc:{name}:msg:{msg_id}", json.dumps(synced_data),
ex=self.msg_expiry); otherwise skip the Redis write. Ensure you reference the
existing variables synced_data, msg_id, name, self.msg_expiry and the
relay_message function when making this change.
- Around line 197-204: このループの裸の except と単一行の try/except をやめ、json.JSONDecodeError
を明示的に捕捉してログを残すよう修正してください: 在る箇所は async for past_message in
message.channel.history(limit=100): 内の try: p_dic =
json.loads(past_message.content) ... except: continue を、複数行に展開して except
json.JSONDecodeError as e: logger.warning(...)(または既存のロガー名)とし、デコード失敗時は continue
するようにし、その他の例外は再スローまたは別の明示的な except ブロックで扱う(参照シンボル: past_message, p_dic,
message.channel.history, ref_mid, ref_author, ref_content)。
- Around line 326-330: Replace the bare except that follows the webhook creation
(the try block that returns webhook.url where webhook_url=webhook.url) with
explicit exception handling: catch discord.Forbidden and discord.HTTPException
(and optionally other specific discord exceptions) as e, call the module/class
logger to record a descriptive error including the exception object and context
(e.g., which channel/guild/webhook action failed), then return None; if you want
a last-resort catch, add an except Exception as e to log unexpected errors but
prefer the specific discord exceptions first.
---
Nitpick comments:
In `@src/bot/cogs/sgc.py`:
- Line 332: 関数 relay_message のシグネチャでデフォルト値が None のパラメータ sgc_data と ref_info
に型ヒントが明示されていないため、PEP 484 準拠で Optional を使って型を明示してください;具体的には relay_message
の定義を見つけて sgc_data: Optional[dict] または dict | None、ref_info: Optional[dict] または
dict | None のいずれかの表記で修正し、必要なら from typing import Optional
をインポートしてください(また同様の修正を別の位置で同関数のオーバーロードや同ファイル内の定義があれば合わせて行ってください)。
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: da776f23-ee6f-48b3-ac57-1a571d5b32ea
📒 Files selected for processing (6)
dev.shdocker-compose.yamlsrc/bot/cogs/globalchat.pysrc/bot/cogs/sgc.pysrc/bot/main.pysrc/dashboard/src/app/dashboard/[guildId]/globalchat/GlobalChatClient.tsx
✅ Files skipped from review due to trivial changes (2)
- dev.sh
- src/dashboard/src/app/dashboard/[guildId]/globalchat/GlobalChatClient.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- docker-compose.yaml
- src/bot/main.py
| webhook_url=webhook.url | ||
| ) | ||
| return webhook.url | ||
| except: | ||
| return None |
There was a problem hiding this comment.
bare except を避け、具体的な例外を指定してください。
Webhook の作成・更新処理で発生しうる具体的な例外(discord.Forbidden, discord.HTTPException など)をキャッチし、エラーをログに記録することを推奨します。
🔧 修正案
await self.bot.api.globalchat_update_connect_channel(
channel_id=str(channel_id),
guild_id=str(guild_id),
room_name=channel_info["room_name"],
webhook_url=webhook.url
)
return webhook.url
- except:
+ except (discord.Forbidden, discord.HTTPException) as e:
+ logging.error(f"Failed to fix webhook for channel {channel_id}: {e}")
return None🧰 Tools
🪛 Ruff (0.15.7)
[error] 329-329: Do not use bare except
(E722)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/bot/cogs/sgc.py` around lines 326 - 330, Replace the bare except that
follows the webhook creation (the try block that returns webhook.url where
webhook_url=webhook.url) with explicit exception handling: catch
discord.Forbidden and discord.HTTPException (and optionally other specific
discord exceptions) as e, call the module/class logger to record a descriptive
error including the exception object and context (e.g., which
channel/guild/webhook action failed), then return None; if you want a
last-resort catch, add an except Exception as e to log unexpected errors but
prefer the specific discord exceptions first.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (4)
src/bot/cogs/sgc.py (4)
219-228:⚠️ Potential issue | 🟠 MajorRedis の存在チェックが欠落しています。
m_type == "edit"の処理時にself.bot.redis.get()を呼び出していますが、Redis の存在チェックがありません。on_message_editやon_raw_message_deleteと同様のチェックを追加してください。🔧 修正案
elif m_type == "edit": + if not self.bot.redis: + return data = await self.bot.redis.get(f"gc:{name}:msg:{dic.get('messageId')}")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/bot/cogs/sgc.py` around lines 219 - 228, The edit branch lacks a Redis client existence check before calling self.bot.redis.get; modify the m_type == "edit" block in sgc.py to first verify the Redis client exists (e.g., check hasattr(self.bot, "redis") and that self.bot.redis is not None or falsey) and return/skip processing if missing, mirroring the checks used in on_message_edit/on_raw_message_delete, then proceed to call self.bot.redis.get, json.loads and gather the _edit_webhook_message tasks as before.
183-186:⚠️ Potential issue | 🟡 Minorbare
except:を使用しないでください。JSON パースエラーをキャッチする場合は、
json.JSONDecodeErrorを明示的に指定してください。bareexcept:はKeyboardInterruptやSystemExitなどもキャッチしてしまいます。前回のレビューで指摘された問題が未修正です。🔧 修正案
try: dic = json.loads(message.content) - except: + except json.JSONDecodeError: return🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/bot/cogs/sgc.py` around lines 183 - 186, Replace the bare except in the JSON parsing block so only JSON parsing errors are swallowed: change the try/except around json.loads(message.content) to catch json.JSONDecodeError (not a bare except) and return on that specific exception; keep the surrounding logic and the variable name dic and ensure json is imported where sgc.py uses json.
50-55:⚠️ Potential issue | 🟠 Major
primary_guildがNoneの場合にAttributeErrorが発生します。
message.author.primary_guildはNoneになる可能性があり、その場合.tagへのアクセスで例外が発生します。前回のレビューで指摘された問題が未修正です。🔧 修正案
- if message.author.primary_guild.tag: + if message.author.primary_guild and message.author.primary_guild.tag: dic["x-userPrimaryGuild"] = { "badge": message.author.primary_guild.badge.key, "tag": message.author.primary_guild.tag, "id": str(message.author.primary_guild.id) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/bot/cogs/sgc.py` around lines 50 - 55, The code currently checks message.author.primary_guild.tag which raises AttributeError when primary_guild is None; change the guard to verify primary_guild exists (e.g., if message.author.primary_guild:) before accessing its attributes and then safely populate dic["x-userPrimaryGuild"] with primary_guild.badge.key, primary_guild.tag, and str(primary_guild.id), optionally guarding badge (e.g., primary_guild.badge and primary_guild.badge.key) to avoid further None dereferences; update the block around message.author.primary_guild and dic to perform these null checks.
232-239:⚠️ Potential issue | 🟠 Major
delete処理にも Redis の存在チェックを追加してください。
m_type == "delete"の処理でも同様に Redis チェックが必要です。🔧 修正案
elif m_type == "delete": + if not self.bot.redis: + return msg_id = dic.get('messageId') data = await self.bot.redis.get(f"gc:{name}:msg:{msg_id}")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/bot/cogs/sgc.py` around lines 232 - 239, The delete branch uses self.bot.redis without confirming Redis is available; update the m_type == "delete" block to first check that self.bot.redis is truthy (or connected) before calling self.bot.redis.get(...) and self.bot.redis.delete(...), and skip or return early if Redis is not present; keep the existing logic for msg_id, json.loads on data, creating tasks from self._delete_webhook_message(dest), awaiting asyncio.gather(..., return_exceptions=True), and deleting the key with self.bot.redis.delete(...) only when the Redis check passes.
🧹 Nitpick comments (6)
src/bot/cogs/sgc.py (6)
332-332: 型ヒント:Optionalを明示的に指定してください。デフォルト値が
NoneのパラメータにはOptionalを明示的に使用するか、dict | Noneの形式を使用してください。♻️ 修正案
- async def relay_message(self, message: discord.Message, config: dict, room: dict, isother_bot: bool = False, sgc_data: dict = None, ref_info: dict = None): + async def relay_message(self, message: discord.Message, config: dict, room: dict, isother_bot: bool = False, sgc_data: Optional[dict] = None, ref_info: Optional[dict] = None):🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/bot/cogs/sgc.py` at line 332, The relay_message signature uses default None for sgc_data and ref_info but lacks explicit Optional typing; update the signature of relay_message to annotate sgc_data and ref_info as Optional[dict] (or dict | None for Python 3.10+) and add the necessary Optional import from typing if using Optional; ensure any internal usages or type checks still accept None and adjust related docstrings or mypy stubs accordingly.
293-294: コードスタイル: 複数のステートメントを1行にまとめないでください。可読性のため、
if文の本体は別の行に記述してください。♻️ 修正案
- if description: embed.add_field(name="説明", value=description, inline=False) - if rule: embed.add_field(name="ルール", value=rule, inline=False) + if description: + embed.add_field(name="説明", value=description, inline=False) + if rule: + embed.add_field(name="ルール", value=rule, inline=False)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/bot/cogs/sgc.py` around lines 293 - 294, The if-statements that add fields to the embed are written with their bodies on the same line; update the checks for description and rule so each if has its body on the next line (i.e., separate the conditional from the call to embed.add_field) to follow coding style and improve readability—change the inline single-line forms around the variables description and rule and the method embed.add_field to multi-line if blocks.
417-418: 例外をログに記録してください。Webhook 送信の失敗理由をデバッグするために、例外をログに記録することを推奨します。
♻️ 修正案
except Exception as e: + logging.error(f"Webhook send failed for {url}: {e}") return None🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/bot/cogs/sgc.py` around lines 417 - 418, The except block currently swallows exceptions with "except Exception as e: return None"; change it to log the exception before returning so webhook send failures are debuggable—use the module/class logger (e.g. logger.exception or self.bot.logger.exception) or processLogger.exception to record the exception object and context (include a short message like "Failed to send webhook") and then return None; update the except block that catches Exception as e in src/bot/cogs/sgc.py accordingly.
329-330: 例外をログに記録してください。例外をキャッチしていますが、ログに記録していません。Webhook の作成/更新に失敗した理由をデバッグするために、エラーをログに記録することを推奨します。
♻️ 修正案
- except (discord.Forbidden, discord.HTTPException) as e: + except (discord.Forbidden, discord.HTTPException) as e: + logging.warning(f"Failed to fix webhook for channel {channel_id}: {e}") return None🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/bot/cogs/sgc.py` around lines 329 - 330, The except block catching (discord.Forbidden, discord.HTTPException) as e should log the caught exception so failures to create/update the webhook can be diagnosed; update that except block to call your module logger (or self.logger) with the error and stack trace (e.g., logger.exception(...) or logger.error(..., exc_info=True)), mentioning the operation context (webhook create/update) and include the exception variable e.
3-3: 未使用のインポートosがあります。
osモジュールがインポートされていますが、ファイル内で使用されていません。不要なインポートは削除してください。♻️ 修正案
import json import logging -import os from discord.ext import commands🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/bot/cogs/sgc.py` at line 3, Remove the unused top-level import "os" from src/bot/cogs/sgc.py; locate the import statement (the line importing os) and delete it, or if environment access is actually required later, replace/remove usages accordingly and keep only the necessary imports to avoid unused symbols.
74-75: 例外を静かに無視しています。
try-except-passは問題を隠蔽します。参照メッセージの取得に失敗した場合は、少なくともデバッグログを記録することを推奨します。♻️ 修正案
except Exception: - pass + logging.debug(f"Failed to resolve reference for message {message.id}")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/bot/cogs/sgc.py` around lines 74 - 75, Replace the bare "except Exception: pass" that swallows errors during reference-message retrieval with a proper exception handler: catch the exception as "e" (except Exception as e) and log it (e.g., logger.debug or logger.exception) including useful context such as the reference message ID, channel ID and guild ID so failures are visible during debugging; do not remove the try block otherwise—just emit the log with the error and context and only suppress the exception if it's expected.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/bot/cogs/sgc.py`:
- Around line 401-405: When isother_bot is True the code currently appends
images twice (once from sgc_data["attachmentsUrl"] and again from
message.attachments); change the branch that iterates message.attachments so it
only runs when isother_bot is False (or when sgc_data["attachmentsUrl"] is
empty) — i.e., guard the block that checks message.attachments and appends
discord.Embed(image=...) with an explicit check for not isother_bot (or no
attachmentsUrl) to avoid duplicate embeds.
- Around line 111-114: self.bot.get_channel(...) can return None causing an
AttributeError on .send(); update the block that handles name == "sgc" / "dsgc"
to check the returned channel before calling send (use the MAIN and DEBUG
identifiers and the existing sgc_edit_json(after.id, after.content)), and if
get_channel returns None either call fetch_channel(...) as a fallback or
skip/send a logged warning instead so .send is only invoked on a valid channel
object.
---
Duplicate comments:
In `@src/bot/cogs/sgc.py`:
- Around line 219-228: The edit branch lacks a Redis client existence check
before calling self.bot.redis.get; modify the m_type == "edit" block in sgc.py
to first verify the Redis client exists (e.g., check hasattr(self.bot, "redis")
and that self.bot.redis is not None or falsey) and return/skip processing if
missing, mirroring the checks used in on_message_edit/on_raw_message_delete,
then proceed to call self.bot.redis.get, json.loads and gather the
_edit_webhook_message tasks as before.
- Around line 183-186: Replace the bare except in the JSON parsing block so only
JSON parsing errors are swallowed: change the try/except around
json.loads(message.content) to catch json.JSONDecodeError (not a bare except)
and return on that specific exception; keep the surrounding logic and the
variable name dic and ensure json is imported where sgc.py uses json.
- Around line 50-55: The code currently checks message.author.primary_guild.tag
which raises AttributeError when primary_guild is None; change the guard to
verify primary_guild exists (e.g., if message.author.primary_guild:) before
accessing its attributes and then safely populate dic["x-userPrimaryGuild"] with
primary_guild.badge.key, primary_guild.tag, and str(primary_guild.id),
optionally guarding badge (e.g., primary_guild.badge and
primary_guild.badge.key) to avoid further None dereferences; update the block
around message.author.primary_guild and dic to perform these null checks.
- Around line 232-239: The delete branch uses self.bot.redis without confirming
Redis is available; update the m_type == "delete" block to first check that
self.bot.redis is truthy (or connected) before calling self.bot.redis.get(...)
and self.bot.redis.delete(...), and skip or return early if Redis is not
present; keep the existing logic for msg_id, json.loads on data, creating tasks
from self._delete_webhook_message(dest), awaiting asyncio.gather(...,
return_exceptions=True), and deleting the key with self.bot.redis.delete(...)
only when the Redis check passes.
---
Nitpick comments:
In `@src/bot/cogs/sgc.py`:
- Line 332: The relay_message signature uses default None for sgc_data and
ref_info but lacks explicit Optional typing; update the signature of
relay_message to annotate sgc_data and ref_info as Optional[dict] (or dict |
None for Python 3.10+) and add the necessary Optional import from typing if
using Optional; ensure any internal usages or type checks still accept None and
adjust related docstrings or mypy stubs accordingly.
- Around line 293-294: The if-statements that add fields to the embed are
written with their bodies on the same line; update the checks for description
and rule so each if has its body on the next line (i.e., separate the
conditional from the call to embed.add_field) to follow coding style and improve
readability—change the inline single-line forms around the variables description
and rule and the method embed.add_field to multi-line if blocks.
- Around line 417-418: The except block currently swallows exceptions with
"except Exception as e: return None"; change it to log the exception before
returning so webhook send failures are debuggable—use the module/class logger
(e.g. logger.exception or self.bot.logger.exception) or processLogger.exception
to record the exception object and context (include a short message like "Failed
to send webhook") and then return None; update the except block that catches
Exception as e in src/bot/cogs/sgc.py accordingly.
- Around line 329-330: The except block catching (discord.Forbidden,
discord.HTTPException) as e should log the caught exception so failures to
create/update the webhook can be diagnosed; update that except block to call
your module logger (or self.logger) with the error and stack trace (e.g.,
logger.exception(...) or logger.error(..., exc_info=True)), mentioning the
operation context (webhook create/update) and include the exception variable e.
- Line 3: Remove the unused top-level import "os" from src/bot/cogs/sgc.py;
locate the import statement (the line importing os) and delete it, or if
environment access is actually required later, replace/remove usages accordingly
and keep only the necessary imports to avoid unused symbols.
- Around line 74-75: Replace the bare "except Exception: pass" that swallows
errors during reference-message retrieval with a proper exception handler: catch
the exception as "e" (except Exception as e) and log it (e.g., logger.debug or
logger.exception) including useful context such as the reference message ID,
channel ID and guild ID so failures are visible during debugging; do not remove
the try block otherwise—just emit the log with the error and context and only
suppress the exception if it's expected.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 40581d84-f2d4-4f2f-8e09-46b195dbc7de
📒 Files selected for processing (1)
src/bot/cogs/sgc.py
| if name == "sgc": | ||
| await self.bot.get_channel(self.MAIN).send(self.sgc_edit_json(after.id, after.content)) | ||
| elif name == "dsgc": | ||
| await self.bot.get_channel(self.DEBUG).send(self.sgc_edit_json(after.id, after.content)) |
There was a problem hiding this comment.
get_channel が None を返す可能性があります。
self.bot.get_channel() はチャンネルが見つからない場合 None を返します。その場合、.send() の呼び出しで AttributeError が発生します。
🔧 修正案
if name == "sgc":
- await self.bot.get_channel(self.MAIN).send(self.sgc_edit_json(after.id, after.content))
+ channel = self.bot.get_channel(self.MAIN)
+ if channel:
+ await channel.send(self.sgc_edit_json(after.id, after.content))
elif name == "dsgc":
- await self.bot.get_channel(self.DEBUG).send(self.sgc_edit_json(after.id, after.content))
+ channel = self.bot.get_channel(self.DEBUG)
+ if channel:
+ await channel.send(self.sgc_edit_json(after.id, after.content))📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if name == "sgc": | |
| await self.bot.get_channel(self.MAIN).send(self.sgc_edit_json(after.id, after.content)) | |
| elif name == "dsgc": | |
| await self.bot.get_channel(self.DEBUG).send(self.sgc_edit_json(after.id, after.content)) | |
| if name == "sgc": | |
| channel = self.bot.get_channel(self.MAIN) | |
| if channel: | |
| await channel.send(self.sgc_edit_json(after.id, after.content)) | |
| elif name == "dsgc": | |
| channel = self.bot.get_channel(self.DEBUG) | |
| if channel: | |
| await channel.send(self.sgc_edit_json(after.id, after.content)) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/bot/cogs/sgc.py` around lines 111 - 114, self.bot.get_channel(...) can
return None causing an AttributeError on .send(); update the block that handles
name == "sgc" / "dsgc" to check the returned channel before calling send (use
the MAIN and DEBUG identifiers and the existing sgc_edit_json(after.id,
after.content)), and if get_channel returns None either call fetch_channel(...)
as a fallback or skip/send a logged warning instead so .send is only invoked on
a valid channel object.
| # 添付画像 embed | ||
| if message.attachments: | ||
| for a in message.attachments: | ||
| if a.content_type and a.content_type.startswith("image/"): | ||
| embeds.append(discord.Embed(color=0x007bff).set_image(url=a.url)) |
There was a problem hiding this comment.
isother_bot=True の場合、画像が重複して追加される可能性があります。
isother_bot=True の場合、385-386行目で sgc_data["attachmentsUrl"] から画像を追加していますが、402-405行目でも message.attachments から画像を追加しています。他ボットからの転送時は message オブジェクトの添付ファイルは JSON メッセージ自体であり、元のメッセージの添付ファイルではないため、この分岐は不要または意図しない動作を引き起こす可能性があります。
🔧 修正案
# 添付画像 embed
- if message.attachments:
+ if not isother_bot and message.attachments:
for a in message.attachments:
if a.content_type and a.content_type.startswith("image/"):
embeds.append(discord.Embed(color=0x007bff).set_image(url=a.url))🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/bot/cogs/sgc.py` around lines 401 - 405, When isother_bot is True the
code currently appends images twice (once from sgc_data["attachmentsUrl"] and
again from message.attachments); change the branch that iterates
message.attachments so it only runs when isother_bot is False (or when
sgc_data["attachmentsUrl"] is empty) — i.e., guard the block that checks
message.attachments and appends discord.Embed(image=...) with an explicit check
for not isother_bot (or no attachmentsUrl) to avoid duplicate embeds.
feat 公式グローバルチャットを追加
feat: Redisを追加
feat: sgcを追加
Summary by CodeRabbit
新機能
その他