Skip to content

feat: 対象者が多い場合のtraQメッセージ分割処理#1511

Merged
kaitoyama merged 5 commits intofix/openapifrom
claude/split-long-messages-dai2Y
Apr 11, 2026
Merged

feat: 対象者が多い場合のtraQメッセージ分割処理#1511
kaitoyama merged 5 commits intofix/openapifrom
claude/split-long-messages-dai2Y

Conversation

@Eraxyso
Copy link
Copy Markdown
Contributor

@Eraxyso Eraxyso commented Apr 4, 2026

概要

アンケート作成・リマインダー通知において、対象者が多い場合にtraQのメッセージ上限(10,000文字)を超えてしまう問題を修正します。

変更内容

分割方針

対象者リストを複数のメッセージに分割する際、各メッセージが完全な形(ヘッダー・対象者サブセット・回答リンク)になるようにします。

分割前(1件):

### アンケート『test』の回答期限が迫っています!
...
#### 対象者
@user1 @user2 ... @user1000
#### 回答リンク
https://anke-to.trap.jp/responses/new/1

分割後(複数件):

### アンケート『test』の回答期限が迫っています!
...
#### 対象者
@user1 @user2 ... @userN
#### 回答リンク
https://anke-to.trap.jp/responses/new/1
### アンケート『test』の回答期限が迫っています!
...
#### 対象者
@userN+1 ... @user1000
#### 回答リンク
https://anke-to.trap.jp/responses/new/1

主な変更ファイル

  • traq/webhook_impl.go

    • MessageLimit = 10000 定数を追加(traQ の vd.RuneLength(1, 10000) に基づく)
  • controller/questionnaire.go

    • createQuestionnaireMessage の戻り値を string[]string に変更
    • createReminderMessage の戻り値を string[]string に変更
    • createMessagesFromTargets(prefix, suffix, targets, limit) ヘルパー関数を追加
  • controller/reminder.go

    • 複数メッセージをループして送信するよう変更
  • controller/questionnaire_test.go

    • 既存テストを []string 対応に更新
    • TestCreateMessagesFromTargets を新規追加

claude added 3 commits April 4, 2026 13:31
When too many targets are specified, the mention line can exceed
traQ's message length limit. PostMessage now tokenizes the message
at newline and space boundaries, then greedily packs tokens into
chunks of at most 2000 runes, sending each chunk as a separate
webhook request.

https://claude.ai/code/session_01CgXuuWWwhkMr1fXAR9LGgw
…/footer

When the target list causes a message to exceed traQ's 2000-char limit,
createMessagesFromTargets splits targets into groups and creates a
separate complete message for each group — each one includes the full
questionnaire header, the subset of @mentions, and the response link.

The previous generic token-based split in PostMessage is removed;
createQuestionnaireMessage and createReminderMessage now return []string
and their callers iterate to send each message.

https://claude.ai/code/session_01CgXuuWWwhkMr1fXAR9LGgw
The actual traQ message length limit is 10,000 runes (validated in
router/v3/messages.go with vd.RuneLength(1, 10000)), not 2,000.

https://claude.ai/code/session_01CgXuuWWwhkMr1fXAR9LGgw
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 4, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c52dfab2-8328-4ec5-b32d-e8aca861bef5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/split-long-messages-dai2Y

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 4, 2026

Codecov Report

❌ Patch coverage is 85.10638% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.37%. Comparing base (0a67109) to head (89e6dfe).
⚠️ Report is 19 commits behind head on fix/openapi.

Files with missing lines Patch % Lines
controller/reminder.go 0.00% 5 Missing ⚠️
controller/questionnaire.go 95.23% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@               Coverage Diff               @@
##           fix/openapi    #1511      +/-   ##
===============================================
- Coverage        66.79%   64.37%   -2.43%     
===============================================
  Files               25       25              
  Lines             3762     3888     +126     
===============================================
- Hits              2513     2503      -10     
- Misses             875     1012     +137     
+ Partials           374      373       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@kaitoyama
Copy link
Copy Markdown
Contributor

  • [P2] 分割された通知メッセージの投稿を DB トランザクション内で行わないでください。
    対象: controller/questionnaire.go:447
    createQuestionnaireMessage が複数チャンクを返すようになったことで、このループにより質問票作成が非 atomic になっています。2 件目以降の
    PostMessage で失敗すると、DB トランザクション自体はロールバックされますが、それ以前のチャンクは既に投稿済みです。その結果、実際にはコミッ
    トされていない質問票へのリンクがユーザーに配信される可能性があります。対象者が多い場合に限られますが、部分的な公開が発生し得ます。

Copy link
Copy Markdown
Contributor

@kaitoyama kaitoyama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一点だけ確認お願いします

When PostMessage was called inside the DB transaction, a failure on the
second or later chunk would roll back the transaction, but any previously
sent chunks already contained a link to a questionnaire that no longer
exists.

By calling PostMessage after the transaction commits, the linked
questionnaire is guaranteed to exist. Send failures are only logged;
the questionnaire creation itself is still treated as successful.

https://claude.ai/code/session_01CgXuuWWwhkMr1fXAR9LGgw
@Eraxyso Eraxyso force-pushed the claude/split-long-messages-dai2Y branch from d406f12 to 4807e0f Compare April 11, 2026 10:48
@Eraxyso Eraxyso requested a review from kaitoyama April 11, 2026 10:50
Copy link
Copy Markdown
Contributor

@kaitoyama kaitoyama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTMです

@kaitoyama kaitoyama merged commit 21a58c7 into fix/openapi Apr 11, 2026
10 of 11 checks passed
@kaitoyama kaitoyama deleted the claude/split-long-messages-dai2Y branch April 11, 2026 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants