frappe-helpdeskを日本語で使えるようにした話——ヘルプデスクOSSの問合せ管理が「日本語で検索して0件」だった原因と、レビューで見つかった2つ目のバグ
名古屋でAIシステム開発の会社をやっています。今日のテーマはヘルプデスク・問合せ管理です。オープンソースのfrappe-helpdeskを実際に日本語で使えるところまで持っていき、本家にプルリクエストを出しました。その記録です。
問合せ管理の固定費は、人数×単価で毎年増える
Zendeskの公式料金表(2026年8月時点)を実測しました。担当者1人あたりの月額です。
| プラン | 年間契約 | 月間契約 | 10人で年間 |
|---|---|---|---|
| Support Team | $19 | $25 | $2,280(約34万円) |
| Suite Team | $55 | $69 | $6,600(約99万円) |
| Suite Professional | $115 | $149 | $13,800(約207万円) |
1ドル150円換算。担当者を増やすたびに増え、使い続ける限り毎年かかります。問合せ管理は人数課金と相性が悪く、サポート要員を増やした瞬間に効いてきます。
ヘルプデスクOSSは実在する。ただし日本語情報がゼロ
作る前に候補を実測しました(2026年8月21日・GitHub APIとZenn/Qiita検索API)。
| OSS | ★ | ライセンス | 日本語の解説記事 |
|---|---|---|---|
| frappe-helpdesk | 3,330 | AGPL-3.0 | Zenn 0本 / Qiita 0本 |
| Chatwoot | 36,033 | 独自 | Zenn 0本 / Qiita 3本 |
| Zammad | 5,860 | AGPL-3.0 | Zenn 0本 / Qiita 4本 |
| FreeScout | 4,490 | AGPL-3.0 | Zenn 0本 / Qiita 0本 |
ヘルプデスクOSSは揃っているのに、日本語の情報が全滅しています。この空白が「無料なのに誰も使っていない」の正体でした。
選んだのはfrappe-helpdeskです。チケット・SLA・ナレッジベース・メール連携という問合せ管理の芯が最初から揃っていて、ERPNextと同じFrappeの上に乗っているためカスタマイズの筋が良い。
壁は料金でも機能でもなく「日本語で検索すると0件」だった
構築して日本語でチケットを登録し、検索したら何も出ません。英語のチケットは出るのに、日本語だけ出ない。
原因はこれでした。
unsafe_chars = re.compile(r"[^a-zA-Z0-9\s]")
検索処理が英数字と空白以外を全部捨てていたのです。「パスワード」と入れると、ここを通った時点で空文字になります。空のクエリで検索するので当然0件。日本語だけでなく中国語・韓国語でも同じことが起きます。
さらに、日本語の翻訳ファイル自体がありませんでした。34言語のうち日本語だけが欠けている——韓国語も中国語もあるのにです。
直した内容
- 文字を捨てるのをやめた — NFKC正規化に置き換え、どの言語の文字も残す。全角カナや記号のゆらぎもここで吸収
- N-gramで索引を作った — 全文検索エンジンは日本語を単語に区切れません。そこで日本語を2〜3文字の断片にして索引に持たせ、検索時も同じ形に展開。区切れない問題を、区切らずに済ませる方法で回避しました
- 英語専用の後処理を日本語では切った — 結果が少ないときTextBlobで名詞句を取り直す処理があり、この辞書は英語専用。日本語では、せっかく出た結果を捨てていました
- 翻訳を全部当てた — 1,499メッセージすべて。未訳ゼロ(
Bcc・CSV・SLAなど18件は英語のまま残すのが適切と判断)
検証は目視ではなく機械で。実際にSQLiteのFTS5テーブルを作り、「パスワード」が「パスワード変更の手順」にヒットし、無関係な文書にはヒットしないことを自動テストにしています。
本家へは2本に分けて提出しました。翻訳とコードを混ぜると却下されやすいためです。
- 検索の修正: frappe/helpdesk#3712
- 日本語翻訳: frappe/helpdesk#3713
- 日本語対応版: katsushi2441/frappe-helpdesk-jp
検索の修正は「日本語対応」ではなく「CJK対応」として書きました。本家には韓国語も中国語もあるので、そのほうが本家にとっての価値が伝わります。
レビューで2つ目のバグが出た(ここが一番の学び)
PRを出した直後、コードレビューでこう指摘されました。
新しいクエリは
cjk_termsに依存しているが、同名のまま残っている既存のRedis索引は、文書数だけを見る有効性判定を通過してしまう。
追いかけたら、本当にバグでした。
index_exists() は「索引内の文書数」が実レコード数と近いかしか見ていません。この数字はスキーマが変わっても正しいままです。つまり、
cjk_termsが無かった頃のRedis索引が「有効」と判定される- 再構築がスキップされる
- 新クエリは
cjk_termsにしかマッチしない - → 既存サイトをアップグレードすると、日本語検索が効かないまま
SQLite側は索引ファイル名を上げたので再構築されますが、Redis側は同名のままで、そこだけ手当てが抜けていました。新規構築では絶対に踏まない、アップグレード時だけ出るバグです。
修正は、宣言スキーマとFT.INFOが返す実フィールドを突き合わせ、欠けていたら「索引なし」として扱う形にしました。cjk_terms専用のその場しのぎにせず汎用にしたので、今後フィールドが増えたときも同じ経路で拾えます。テストは5件から10件に増えました。
学びは2つです。新規構築だけ試して「動いた」と言ってはいけないこと。そしてレビューは、自分が絶対に踏まない経路を教えてくれること。今回は指摘がなければ、利用者の環境で静かに壊れていました。
自社で持つための3つの方法
frappe-helpdeskはAGPL-3.0なので、当社が「完成品」として買い切り販売することはできません。売れるのは手順と手間だけです。そのぶんソフトのライセンス費はずっとゼロです。
方法1: 自分で構築する(無料) ソースは公開しています。つまずくのはFrappe Frameworkのセットアップ、日本語ロケールの反映、検索インデックスの再構築の3か所です。
方法2: 構築手順書を買う(480円)
上の3か所でつまずかないための手順書です。メモリ不足でビルドが無言で落ちる話、翻訳が反映されないときの確認順序、索引をforce付きで作り直すコマンド、メール受信をチケットに落とす設定、カスタマイズ用AIプロンプト4本、AGPLの線引きまで。
frappe-helpdesk日本語化の実録と構築手順書(Brain)
方法3: 構築を任せる(110,000円税込〜) 自社の運用に合わせて構築し、ソースコードごとお渡しします。紙の見積もりではなく最短1営業日で動くデモ。「既存の顧客マスタとつなぎたい」といった要件もここで吸収します。 バイブプロトタイピング
料金比較とOSS比較、移行判断のチェックリストは解説ページにまとめました。 Zendeskの月額をやめたい会社へ
問合せの一次対応をAIに任せて、残りをチケット管理に落とす組み合わせも効きます。買い切りのAIチャットボット(55,000円税込)を用意しています。 AIチャットボット(Kurage App Store)
考察: 日本語の空白は「翻訳」ではなく「実装」にある
日本語化というと翻訳ファイルの話だと思われがちですが、今回いちばん効いたのは検索が日本語を捨てていた実装の修正でした。UIが日本語になっても、自分のチケットを検索できないヘルプデスクは使えません。
海外製OSSを日本語で使うときは、まず検索・ソート・全文一致を日本語データで試すのが早い。ここが壊れている製品は、翻訳が100%でも実用になりません。逆にここさえ直せば、月額課金をやめる選択肢が現実になります。
数字はいつもの実験ダッシュボードで公開しながら育てます。