筑波大学学園祭の裏側 〜メールシステム構築への挑戦〜
はじめに
多くの学生団体では現実的な選択としてメールアドレスやGoogleアカウントなどの共有が行われると思います。この記事では筑波大学学園祭実行委員会でメールを安全な構成にし運用する試みについてご紹介します。
雙峰祭とは
雙峰祭(公式サイト)とは、筑波大学で例年11月頃に開催されている学園祭です。第49回目となる2023年度の雙峰祭は11月3日〜5日の3日間にわたって行われ、3万人を超える方々に来場いただきました。
前年度はコロナ禍を受けて入場者数制限を設けた形での開催でしたが、本年度は4年ぶりに完全対面で実施しました。
雙峰祭を支えるシステム
雙峰祭を運営する筑波大学学園祭実行委員会(以下、学実委)は約300名もの委員から構成されています。したがって、雙峰祭を無事に開催するためには各委員が効率的に、かつ協調して働くことのできる環境づくりが重要です。
そのために、学実委ではいくつかの内部向けのシステムを開発・運用しています。
- 企画応募システム
企画団体と学実委が使用する、企画に関する情報を収集・管理するためのシステムです。 - 物品管理システム
情報メディアシステム局が所有する物品を管理するためのシステムです。 - メールシステム
学実委が企画団体や協賛企業様などとメールでコミュニケーションする際に使用するシステムです。
今年度はこれらのシステムを、ご協賛いただいているさくらインターネット様が提供する、さくらのクラウド・さくらのメールボックス上で構築しました。
メールシステムの課題
先述した通り、学実委では企画団体や大学、協賛企業様などとのコミュニケーションにメールを利用しています。また、「sohosai.com」というドメインを保有しており、これを利用してメールを送るために、Google Workspace Business Standardを6アカウント分契約しています。
それぞれのアカウントは総合窓口用、企画団体とのコミュニケーション用、協賛企業様とのコミュニケーション用、などざっくりと役割が分けられており、学実委内でパスワードを共有して各アカウントにログインしていました。
学実委の代替わりは1月上旬に行われるのですが、引き継ぎの際にこの共同ログインをかなり問題に感じていました。もし十分にお金があれば全員分のGoogle Workspaceアカウントを契約することで解決できるのですが、残念ながらありませんでした。
そこで、Google Workspaceの利用をやめ、すべての委員にメールアドレスを発行できるメールサーバへの移管を検討しました。
メールサーバーの選定
利用するメールサーバには以下の選択肢が挙げられました。
- さくらのメールボックス
- ムームーメール
- カゴヤ・ジャパン メールサーバー
- セルフホスト
まずセルフホストは将来的に維持していける未来が見えなかったので最初に除外しました。予算が限られているので主に料金面、発行できるメールアドレスの数などを重視して、さくらのメールボックスを選択しました。
さくらのメールボックスは最小構成で年額1,048円という破格の安さで、メールアドレスも無制限に発行できます。学実委はさくらインターネット株式会社様にご協賛をいただいており、技術的な相談ができるかもしれないと思ったことも理由の1つです。
メールクライアントの選定
メールクライアントの選定にあたっては概ね以下の要件を元に検討しました。
- 基本的なメールクライアントとしての機能が備わっていること
- セルフホストが可能であること
- 無料で使用できること
- Web上で扱えること
- 赤入れ機能や上長承認機能が備わっているか、プラグインを用いた機能付加システムが備わっていること
- そのドキュメントが整備されていること、もしくはインターネット上に一定の資料が存在すること
- 2023年に入っても開発が継続されていること
- ある程度のユーザ数・コントリビュータ数がおり、これからも開発がある程度継続される見込みがあること
こうした要件をほとんど満たすクライアントは意外にも数が少なく、ざっと調べた限りでは僅かにCyphtやRoundcubeなどが挙げられるのみでした。
Cyphtは基本的なメールクライアントとしての機能を備え、セルフホストが可能で無料で使用可能、かつ2023年に入っても開発が継続されていました。しかしプラグイン機能は一応存在するものの、プラグインを開発するにあたってのドキュメントがRoundcubeと比べて整備されていない部分がありました。
これを鑑みてメールクライアントはRoundcubeを選択することとし、さくらのクラウド上にRoundcubeの環境を構築しました。
赤入れ機能
「赤入れ」とは、メールの文面を下書きの段階で担当の委員がチェックしてから送信する、いわゆる上長承認機能です。Google Workspaceを利用していたときには、委員が下書きにメールを書き、赤入れ担当が下書きをチェックし、執筆者が送信するという流れを取っていました。
メールアドレスを委員が1つずつ持つようになると、下書きボックスを共有できないため、赤入れができなくなってしまいます。そこで、Roundcubeでの赤入れは以下の流れで行うようにしました。
- 執筆者がRoundcubeのエディタから赤入れ依頼ボタンを押す
- 赤入れプラグインがメールデータをStrapi(CMS)に送信し、GitHubのIssueを立てる
- 赤入れ担当がIssueの文面を編集して、Issueをcloseする
- 執筆者がそれを反映させて送信する
Roundcubeプラグインの実装
RoundcubeはPHPでスクリプトを書くことで独自の機能を追加できます。かなりプラグインの存在を前提にした設計になっており、たとえばアップロードされたファイルの管理や連絡先リストなど、メールクライアントとしてのコア機能もプラグインで実装されています。
一方、プラグイン開発には以下のような障壁があります。
- ドキュメントが全然更新されていない
- 渡ってくる引数が持つプロパティのリストがない
- UI層をRoundcubeが定義した謎のタグを使って書く必要がある
1.はどうにもならず、2.は挙動を調べて独自のドキュメントを育てていくことでなんとかすることにしました。3.はRoundcubeプラグインの責務をメールデータや赤入れサーバとの通信のみに抑えて、クライアントの処理は独自に書くことにしました。
また、サーバ側は特にバージョンの揺らぎによって動作しなくなることがあり、開発時にはDocker Composeを、ビルドにはNixを利用してさくらのクラウドに環境を整備しました。
メールの受信・転送
さて、ここまでで個人メールアドレスで作業できる状態になりましたが、いきなりすべての問い合わせ先として個人メールアドレスを晒すわけにはいきません。調べてみたところ、大体の法人等においては大まかな代表メールを設定し、そこに届いたメールを担当者に回覧させる方式が一般的ではあるようでした。
そこで今まで用いていたinfo@、project49th@の2つのメールアドレスを代表メールとし、それらで受信したメールをすべて各委員に転送し、各委員はそれらに対して適時個人メールより返信を返すという方式を採用することとしました。
しかし単純にメールを転送してしまうと添付ファイル10MBのメールが一通来るだけで 10MB×300人=3GBを消費することとなり、実行委員会が契約しているサーバの全体容量であるところの300GBをあっという間に使い切ってしまいます。そこでいったん添付ファイルをいったん抜き、本文のみを転送するというスタイルを取ることにしました。
メール受信・転送スクリプトの実装
メール受信・転送スクリプトの実装としては概ね以下の流れを取ることとしました。
- 各代表メールアドレスの受信トレイを30秒ごとに確認
- もし新規メールがあった場合、メールをパースし、以下の情報を取り出す
- 送信元
- 宛先
- Cc 宛先
- 件名
- 本文
- 添付ファイル
- 添付ファイルが存在する場合はMinio(オブジェクトストレージ)に上げる
- パースして得た情報をStrapiに投げる
- 送信元を偽装した上で同じ宛先・件名・本文のメールを作成、これに添付ファイルへのパスとCc情報をテキストとして最後に付け加え、各委員に転送
メールの多様性
メールは多様な形式に対応するため当初のRFC5322で定められたものからどんどん拡張を続けており、さまざまなメール形式が存在しています。主な形式としては以下のものがあります。
- よくある
Content-Type
- text/plain
- text/html
- multipart/alternative
- multipart/mixed
- よくある
Content-Transfer-Encoding
- base64
- quopri
- よくある日本語
Charset
- ISO-2022JP
- UTF-8
これらについてはメールクライアントによってどれを採用するかがまちまちであるものの、通常Content-Type
やContent-Transfer-Encoding
、Charset
としてどれを採用しているかについてはメッセージ内にて宣言されることとなっており、実装は簡単に終わりました。
しかしながらこの実装を本番運用に投入したところ、学実委に届くメールのうち肌感覚で10~20%がこれらの変数をまったく宣言していないか、ひどい場合だと宣言しているものの実際とは異なるという手に負えないものすら存在しました。そこで対策を考えた結果、これらの形式を順番にすべてトライし、一番正常っぽい結果を出したものを転送するという対処療法的な実装を行うこととなってしまいました。
アカウントの紐付け
さくらのメールボックスはCSVでまとめてメールアドレスを発行するといった機能がありませんので、何もしなければ手動で300個ものメールアドレスを頑張って作る必要があります。これはあまりにも苦痛なので、アカウントを自動発行できるような仕組みを整える必要があります。
まず、大学が発行するメールアドレスである、@u.tsukuba.ac.jp
を利用する方法が考えられます。しかし、学生の中には学実委ではない方も含まれているため、この方法では実委人のみを絞り込むことは難しいです。
学実委では作業関連のコミュニケーションのためにSlackのワークスペースを利用しているのですが、これに参加している人は基本的に実委人であると見なされています。そこで今回は、ワークスペースのユーザIDを持っていることを実委人であるという証明にして、以下の機能を満たすソフトウェアを実装しました。
- Google Formを使って必要な情報を収集する
- さくらのメールボックスでメールアドレスを作る(rust-headless-chromeを使用)
- そのメールアドレスでAuth0のアカウントを作る
- 初期パスワードをSlackのDMに送信する
これもあまりまともな方法ではないのですが、時間と体力が全然ありませんでした。せめてSlackのDMで完結していると良いと思います。
運用して得られた課題と顛末
今回実装したメールシステムは最終的に以下のような構成になりました。
しかしながら、このメールシステムを運用していく中で次のような問題点があることが発覚しました。
- 送信したメールが他者によって確認しづらい
基本的に実委人からは個人アドレスよりメールを送付するため、他者が送信したメールの内容や、とくに送信ステータスを確認するには本人に直接聞くか、GitHubのIssuesを漁る他なくなってしまう - 予約送信が出来ない
実委人は夜間に活動をすることが多い一方で、一般には相手が活動している時間にメールを送信することがマナーとして知られているため、そのギャップを埋めるために予約投稿が求められる - スパムメールの検知・隔離
さくらのメールはスパムメールの検出方法としてSpamAssassinを用いているが、これは以前使っていたGmailの迷惑メールフィルタに比べるとどうしても検知精度がある程度落ちてしまい、結果迷惑メールが受信トレイに紛れ込むことが多くなってしまっている - Roundcubeの検索が貧弱
過去のメールはバックアップ用のアドレスから検索するが、Roundcubeの検索は1万件を超えると非常に重くなり検索結果を返せないことも多々ある - 個人宛に送信されたメールの行方を追うことができない
Googleアカウントが共有されていた頃は、良くも悪くもすべてのメールを追うことができたため責任者に放置されているメールを巻き取れたが、現状では個人宛にのみ送信されたメールの進捗状態が確認できない
このこともあってか、2024年度の学実委の引き継ぎの際にはメールシステムをGoogle Workspaceにフォールバックすることが決定されました。
今後の展望
次の雙峰祭は記念すべき第50回目の開催となります。この節目の年を迎えるにあたって、情報メディアシステム局では既存のシステムのリプレースや新しいシステムの開発を計画しています。
まずは、やはりメールシステムの再構築です。2023年度のメールシステムの移管には多くの反省点がありました。その原因の1つには1年で移管を強行しようとしたことが挙げられます。十分な準備期間と検証期間をとり、安定したシステムの構築を目指します。
その他、企画応募システムのリプレースも行う計画です。現在運用している企画応募システムはオンライン開催の代に設計・開発されたもので、対面開催となった現在においては実情に即していない仕様が存在します。こういった仕様の刷新を進めるほか、さくらのクラウドへのデプロイ方法の検討も含めて再設計を行っていく予定です。