この記事では、最近取り組んでいるもうひとつのプロジェクトについて記録しておこうと思います:CMCC Notify。
プロジェクトの所在地:
github.com/thekfjie/cmcc-notify
OpenClaw のオープンソース化に感謝します、各主要融通の利かないサービスプロバイダー面白いAPIもいくつか公開されています(🙏)。今回使用したのは、中国移動の「新メッセージ」のChannel APIです。本来はOpenClawやMClawといったツールが会話に連携するために用意されたものですが、私はこれを使ってサーバーからの通知を受信しようと考えています。
メールもGotifyも利用できますが、スマホで直接メッセージを確認できる手段がもう一つ増えるのも良いですね。サーバーのアラート、スクリプトの実行結果、NASからの通知などは、すべてここに送信できます。
現在、2つの利用方法をご用意しています。すでにGotifyをご利用中の方は、プラグインをインストールしてメッセージを転送できます。スクリプトから直接呼び出したい場合は、独立したサービスをデプロイし、HTTP API経由で利用できます。テキスト、画像、ファイルのいずれも対応しており、DockerおよびAMD64/ARM64向けのビルドも用意されています。
接続と設定
接続には、開通および認証後に取得したものを使用します。 Channel API Key。プログラムがこのキーを使用してゲートウェイに接続すると、メッセージは対応する紐付け済みユーザーに送信されます。送信時に電話番号を入力する必要はありません。
自分でプロトコルを処理する場合、WebSocketのハンドシェイク時には以下を含める必要があります。 X-API-Key、接続後に認証メッセージを1フレーム送信します:
{"type":"auth","apiKey":"ak_...","version":"2.0"}
了解しました auth_ok これで認証が完了となります。SDK内でも定期的な処理が実装されています。 ping、点検 pong 接続が切断された後の退避と再接続について、送受信通知が未処理の状態でも、わざわざ別途コードを書く必要がありません。
実際に文字を出力するフレームはごく単純です:
{
"type": "send",
"apiKey": "ak_...",
"content": "备份完成",
"messageId": "msg_..."
}
ここには記入しない to そうすれば、そのキーに紐付けられたユーザーに送信できます。スタンドアロン版またはGotifyプラグインのみを使用する場合は、これらの処理はSDKが行うため、キーの設定を行うだけで済みます。
プロジェクト内では、各キーを1つのチャネルとして保存し、名前を付けたり、メモを追加したりすることができます。設定時には、直接貼り付けることができます。 ak_...、認証SMSの全文を貼り付けることも可能です。プログラムがそこからキーを抽出するため、それ以外のSMSの内容は保存されません。手動で選択してコピーする手間が少なくなります。
1つの通知を複数の人に送信する必要がある場合は、それぞれのチャネルを同じ通知グループに追加してください。サーバー側は順次送信を行い、結果を個別に記録します。成功したものと失敗したものがある場合、APIは 207 Multi-Status、どのチャネルに問題が発生しているかが具体的に分かります。
これらの設定はスタンドアロン版のWebUIで行うことができ、画面上で接続状態の確認やメッセージ送信のテストも可能です。
スタンドアロンサービスと Gotify プラグイン
スタンドアロン版は、主に監視、スクリプト、NASなどからの呼び出しを想定しています。
すべてのスクリプトで、基盤となるChannel APIキーをいちいち入力するのは避けたいですし、また、当社のあまりセキュリティは重要であるため、別途「通知アプリ」を作成しました。例えば、監視システムにはあるアプリを、バックアップスクリプトには別のアプリを使用し、それぞれが独自のトークンを取得して、あらかじめ設定されたチャネルや通知グループに送信します。
アプリを作成する際に一度表示されます cn_app_... トークンについては、サーバー側ではその SHA-256 ハッシュのみを保存します。アプリケーションでは、トークンを個別に無効化したり、ローテーションさせたりできるほか、1分あたりのリクエスト上限を設定することも可能です。
この呼び出しは、ごく普通の HTTP リクエストです:
curl -X POST https://notify.example.com/v1/notify \
-H "Authorization: Bearer <APPLICATION_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"title": "服务告警",
"message": "磁盘使用率超过 90%"
}'
受信先は管理ページで設定され、スクリプトはコンテンツの送信のみを担当します。その後、受信チャネルを変更する場合は、アプリケーションの設定を変更するだけで済みます。
WebUI には、コピー可能な API のサンプルや、テキスト、画像、ファイルの送信テストも用意されています。設定が完了したら、まずはページ上で試してみてから、ご自身のサービスに組み込んでください。
Gotify プラグインについては、Gotify に標準で備わっている設定ページと詳細ページをそのまま使用します。このプラグインはユーザーのメッセージストリームを読み取り、Application ID と Priority に基づいてフィルタリングを行った後、設定済みの CMCC チャネルに転送します。
例えば、特定の監視アプリのメッセージのみを転送したり、指定された優先度(Priority)に達したアラートのみを転送したりする場合などです。ここでいう優先度(Priority)は、メッセージのフィルタリングにのみ使用され、スマートフォン側で優先度が高いことを示す特別な表示が追加されることはありません。
プラグインページでは、接続状況、マスキング処理済みのキー、送信統計を確認でき、日常的な確認には基本的に十分です。
画像、ファイル、および長文メッセージ
画像とファイルは実際に送信済みです。送信は2段階で行われます。まず、HTTP multipartを使用してファイルをアップロードし、 mediaUrl、その後、WebSocket を通じてメディア情報を送信する。
本地文件 → HTTP 上传 → mediaUrl → WebSocket 媒体消息 → 手机
アップロード用インターフェースは /upload、フォームにファイルが添付されている場合と apiKey、成功した場合は、返された data メディアのURLを取得し、ファイル名、MIMEタイプ、サイズをまとめて送信フレームに格納する。
外部ホスティングのメディアURLもゲートウェイで受け入れられる可能性がありますが、事前にアップロードしてから送信する方法ほど安定して動作しません。現在のプロジェクトではローカルファイルのアップロードという経路を採用していますので、ご自身で実装する際も、まずはこの方法で動作確認を行うことをお勧めします。
アップロードサイズの上限は、現在クライアント側で 200 MiB に制限されています。これはプロジェクト側の制限であり、この範囲内のすべての種類のファイルがすでにスマートフォン上でテスト済みであるとは限りません。連携する際は、まずは小さな画像や小さなファイルで試してみてください。
テストの際に少し厄介な点があります。メディアフレームには説明文を記載できますが、モバイル端末では必ずしも表示されるとは限りません。
そのため、現在、テキストと添付ファイルを同時に送信する場合、まずプレーンテキストのみを送信し、その後、本文を含まない画像やファイルを送信してください。通常、携帯電話には2通のメッセージが届きます。ただし、この2回の送信は別々に行われるため、テキストの送信に成功した後でも、添付ファイルのアップロードや送信に失敗する可能性があります。トラブルシューティングの際は、それぞれの結果を確認する必要があります。
長いメッセージの表示にも注意が必要です。現在のテストでは、改行は保持され、URLも認識されますが、MarkdownやHTMLは正しいレイアウトで表示されません。通知にたくさんの見出しや太字のマークアップを追加しても、スマホではそれらの記号として表示されるだけなので、通常のテキストで改行する方が良いでしょう。
本文が長くなると、省略記号付きのプレビューとして折りたたまれる場合があります。全文を確認するには、プラットフォームが生成したウェブページにアクセスしてください。この折りたたみはプラットフォーム側による処理であり、SDKがコンテンツを削除したり、要約を作成したり、レイアウトを変更したりすることはありません。
現時点で確認されている動作に基づくと、通知をできるだけ直接的に表示させたい場合は、まずUnicode文字数を220文字以内に抑えるようにしてください(スペースや改行も含まれます)。総行数は20行以内とし、内容のある行は15行以内にするのが望ましいです。
これらの数値は、余裕を持たせた推奨値であり、プラットフォームの固定の折りたたみ閾値とは見なせませんし、ましてやAPIの文字数上限でもありません。上限を超えても投稿は可能です。SDKは原文を保持しますが、モバイル端末では全文を表示するためにウェブページを開く必要がある場合があります。
アラートでは、サービス名、ステータス、主要な数値を先頭に記載すれば十分です。例えば、次のようにすれば十分です:
NAS 磁盘告警
数据盘使用率:92%
剩余空间:80 GB
检查时间:09:30
必要であれば、最後に詳細リンクを追加してください。日報や長いログは投稿しても構いませんが、スマホのメッセージで探すのは不便ですので、重要な結果はできるだけ最後に埋めないようにしてください。
音声や動画についてもプロトコルの構造は定義済みですが、端末の動作確認をさらに続ける必要があります。当面はテキスト、画像、ファイルを使用します。
コードの分割とプラグインの構築
2つの接続方式で1つのGo SDKを共有しており、WebSocketの認証、ハートビート、切断時の再接続、メディアのアップロードはすべてそこに含まれています。リポジトリは3つのモジュールに分かれています:
cmcc-notify/
├── cmcc/ CMCC Go SDK
├── gotify-plugin/ Gotify 插件
├── server/ 独立服务与 WebUI
├── docs/ 架构与协议说明
└── go.work 本地联合开发
3つのディレクトリにはそれぞれ go.mod、ローカル経由で go.work 共同開発を行うことで、 GOWORK=off 個別にビルドします。スタンドアロン版の HTTP サービス、設定、および WebUI の依存関係は server/、プラグインは必要な部分のみを読み込みます。
リンクの構成は、おおよそ以下の通りです:
flowchart TB GOTIFY["Gotify 消息"] --> PLUGIN["Gotify 插件"] APP["监控 / 脚本 / NAS"] --> API["独立服务 REST API"] WEBUI["WebUI 配置与测试"] --> API PLUGIN --> SDK["CMCC Go SDK"] API --> SDK SDK --> CMCC["中国移动新消息网关"] CMCC --> PHONE["手机"]
GotifyのGoプラグインのビルドは少々面倒で、.so Gotify のバージョン、Go ツールチェーン、システム、CPU アーキテクチャなどに関係するため、ダウンロードの際は適切なバージョンを選択する必要があります。
現在、Gotify 3.1.1 の ARM64 プラグインを実際にビルドして読み込みました。CI にもプラグインの依存関係チェックを追加し、今後スタンドアロン版を修正する際に、不要な依存関係がプラグインに混入するのを防ぐようにしました。
スタンドアロン版のWebUIはGoのバイナリに直接組み込まれているため、デプロイの際に別途フロントエンドファイルを配置する必要はありません。3つのモジュールそれぞれに対してテストを行い、go test -race、go vet Actions のチェックも接続されました。
ご使用の際はご注意ください
インターフェースの戻り値 202 Accepted、あるいは SDK が accepted: true、これは今回送信した書き込み手順が成功したことを示しています。現時点では、確実な配信確認や既読通知がないため、ページ上で接続状況や送信結果を確認することはできますが、スマートフォンに受信されたかどうかは実際に確認する必要があります。
メディアの報道によると、もう一つあるという media_processed このステータスは、ゲートウェイがメディアを処理したことを示すものであり、スマートフォンが受信済みであると判断する根拠にはなりません。プロトコルを独自に実装する際は、まず短いテキストを送信してスマートフォンが受信できることを確認し、その後、画像、ファイル、長い本文を試すことをお勧めします。そうすれば、どの段階で問題が発生したかを見極めやすくなります。
通知グループ内の各チャネルも独立して送信されるため、1つが失敗しても、すでに送信済みの他のメッセージは取り消されません。添付ファイルも同様にチャネルごとに処理する必要があります。各チャネルは独自のKeyを使用してアップロードし、それぞれが取得したURLを送信します。このプロジェクトでは、あるチャネルでアップロードされたリンクをグループ全体で直接再利用することはありません。連携時に一部で失敗が発生した場合は、APIから返された各チャネルの結果に基づいて原因を調査することができます。
今後も使い続けていく予定だが、主にメッセージ履歴、アプリケーション監査、およびその他の監視システムの連携例を追加したいと考えている。ゲートウェイとモバイル端末での表示動作についても引き続き観察し、問題があれば修正していく。
コードと使用方法はすべて倉庫内。Gotify ユーザーの閲覧数 gotify-plugin/、APIを直接呼び出して確認する server/;プロトコルを送信するだけであれば、単独で cmcc/ のSDK。

