オーケストラと合唱の運営に、自前のメンバーサイトを作った話

オーケストラと合唱を、メンバーサイトを表示したPCとスマートフォンでつなぐイラスト Music

ずいぶん久しぶりの更新になってしまいました。

ベートーヴェン・プロジェクトは、第9回演奏会「FINAL」を終え、予定していたすべての公演を走り切りました。音楽や主宰としての振り返りはnoteの「主宰の総括」に書きましたが、こちらでは少し違う切り口で、運営を支えたメンバーサイトの話をしておこうと思います。

今回の演奏会は、オーケストラも合唱もそれぞれ80名以上。練習日程を知らせる、出欠を確認する、楽譜や当日の案内を共有する、個別の問い合わせに答える。演奏の準備と並行して、こうしたことを回していく必要がありました。

主な運営は私と妻の二人です。人数が増えれば、連絡も確認も増えます。そこで、参加者がログインして情報を確認できる、自前のメンバーサイトを作って運用しました。

日程を載せるだけでは終わらない

メンバーサイトの基本は、練習日程と連絡事項の共有です。

ただ、日程を掲載するだけでは、運営に必要な情報はそろいません。誰が来るのか、どのパートが何人になるのか、変更のお知らせを読んでもらえたのか。参加者側にも、自分の出欠を変更したい、以前の案内を確認したい、主宰に個別に相談したい、といった用事があります。

そのため、サイトには「情報を見る」機能と「自分の情報を登録する」機能の両方を持たせています。

メールで届いた案内を探すだけでなく、サイトへ行けば現在の情報を確認できる。運営側も、個別のやり取りだけに頼らず、一覧で状況を確認できる。そうした場所です。

構成は、PythonとSQLiteによるWebアプリ

技術的には、PythonのFastAPIを中心にしたWebアプリケーションです。画面はJinja2でHTMLを生成し、Bootstrapを使って、スマートフォンからも閲覧できる構成にしています。

データベースはSQLite。Python側からはSQLAlchemyを通して読み書きします。ブラウザ上で操作するとサーバーで処理し、その結果を画面として返す、という構成です。

サーバー側は、nginxが入口となり、Uvicornで動かすFastAPIのアプリケーションへリクエストを渡します。アプリケーションの起動や再起動はsystemdで管理します。

全体の構成を簡略化すると、こうなります。

参加者のブラウザ(スマートフォン・PC)
                  ↓
                nginx
                  ↓
      FastAPI/Uvicorn(Python)
          ├─ Jinja2で画面を生成
          ├─ SQLAlchemy → SQLite
          └─ SMTP経由のメール通知

参加者は専用のアプリをインストールする必要がなく、ブラウザから利用できます。ただし、ブラウザで使えることと、誰でも迷わず使えることは、また別の話でした。この点は後ほど。

オケと合唱は「同じプログラム、別のサイト」

今回の構成で一つ特徴があるのは、オーケストラと合唱でプログラムを共通化していることです。

日程、お知らせ、出欠、メンバー管理といった基本機能は、どちらにも必要です。一方で、パートの構成や案内する内容、管理するメンバーは違います。

そこで、同じコードを使い、設定によってオーケストラ用と合唱用を切り替えます。内部ではSITE_PROFILEという設定を使っています。

ただし、共通なのはプログラムです。サイトは別々のアプリケーションとして動かし、会員データを保存するデータベースも分けています。ログイン状態を保持するCookieの名前も分けることで、同じブラウザから両方を使う場合にも混ざらないようにしています。

共通機能を直せば両方に反映できる一方、変更が両方に影響する可能性もあります。合唱向けの変更をしたら、オケ側も確認する必要がある。共通化すると、こうした確認もセットになります。

参加者が使う機能

練習日程と出欠

練習日程を一覧で確認し、自分の出欠を登録・変更できます。日程ごとの参加人数や、参加者を絞り込んだ一覧も確認できます。

今回、出欠が重要だったのは、練習の進め方だけでなく、会場の収容人数にも関係したからです。オケも合唱も人数が多く、会場によっては全員が来ると入れません。合唱にはピアノも必要ですし、オケには打楽器の手配や運搬もあります。

人数が見えることは、その判断材料になります。ただ、回答が入らなければ人数は確定しません。出欠機能を作ったからといって、会場選びの悩みが全部なくなるわけではなかったです……。

お知らせとパート連絡

お知らせは、全体向け、パート別、個別に対象を分けて掲載できます。本文はMarkdownで編集でき、未読・既読も管理します。

パート連絡は別に用意し、複数のパートをまとめた連絡グループにも対応しています。合唱指揮者やパートリーダーなど、役割に応じて使える機能を分けています。

同じ「連絡」でも、全員が知るべき話と、特定のパートだけに必要な話があります。それを分けて扱えるようにしました。

楽譜、当日の案内、個別の問い合わせ

楽譜ダウンロードの案内や、前日・当日の案内などは、固定ページとして掲載できます。こちらも管理画面からMarkdownで編集できます。

また、参加者と管理者の間には、スレッド形式のメッセージ機能を用意しています。全体へ出す話ではない相談を、個別のやり取りとして扱うためです。

マイページでは、自分の参加費の支払状況も確認できます。ここは決済機能ではなく、運営側が管理する支払状況の表示です。

運営側の管理と、予算の管理

管理者側には、メンバー、パート、練習日程、お知らせ、参加費の支払状況などを管理する画面があります。一斉メール送信や送信履歴の確認、CSV形式でのバックアップ・復元機能もあります。

さらに、BPO側の管理者だけが使う、プロジェクト運営用の画面も作っています。こちらでは、参加人数のスナップショットや予算案、変更履歴を扱います。

この部分のデータは、会員サイトのデータベースとは別のSQLiteに保存します。会員情報を管理する場所と、予算案を管理する場所を分けた構成です。会員名簿を人数集計の元にしながら、予算の対象に含めるかどうかを管理し、予算案に反映できます。

予算は、単価や数量などを編集して収入・支出・差額を再計算したり、案を複製して比較したりできます。Markdownや印刷用の出力にも対応しています。

プロジェクト形式の演奏会では、参加人数の変化が収入の変化に直結します。参加者への案内だけでなく、その裏側の運営も扱うサイトになりました。

メールとLINEも併用する

サイトに情報を掲載しても、更新したことに気づいてもらえなければ読まれません。そのため、メール通知も組み合わせています。

メールはSMTP経由で送信します。サイトには送信履歴を確認する仕組みもありますが、送信処理が成功したことと、参加者が実際にメールを受け取って読んだことは別です。

今回も、更新メールが見つからない、届いていないように見える、といった問題がありました。受信側の振り分けなども関係し得ますが、個々の原因をすべて特定できたわけではありません。

LINEオープンチャットの案内機能もあります。お知らせを登録した後に、LINEへ貼り付ける文章を生成できますが、自動投稿ではなく、管理者がコピーして投稿する方式です。

一つの方法だけで全員に届けるのは難しい。サイトを中心にしつつ、別の連絡手段も組み合わせる必要があります。

作ってからわかった、「使える」の違い

今回の反省として大きいのは、合唱の皆さまの中に、サイトを使うこと自体が難しい方が一定数いらっしゃったことです。

ログインできない、更新メールが見つからない。入口でつまずくと、日程もお知らせも確認できません。こちらとしても、連絡が届いているかどうかがわからず、これは結構ストレスでした。もちろん、使いたいのに使えない参加者の方が、もっと困っていたと思います。

スマートフォンで表示できることだけでは十分ではなかった。ログインして、必要な情報へたどり着き、出欠を登録できるところまで含めて考える必要がありました。

既読が付いたとしても、内容を理解してもらえたかどうかまではわかりません。未回答も、忘れているのか、操作が難しいのか、予定がまだ決まらないのかは、数字だけでは判断できません。

運営側にとって情報がまとまっていることと、参加者全員にとって使いやすいこと。その両方をどう成立させるかは、今回残った課題です。メンバー間のITリテラシーの違いをどう埋めるかについては、別の記事でも考えてみたいと思います。

終わりのあるプロジェクトに、仕組みを作る

ベートーヴェン・プロジェクトは、9回で終わるプロジェクトです。それでも、最後の演奏会を実現するためには、参加者が情報を確認でき、運営側が状況を把握できる仕組みが必要でした。

作ったのは、日程を載せるだけのホームページではなく、参加者と運営がそれぞれ使うWebアプリケーションです。オケと合唱で共通の仕組みを使い、データを分け、連絡や出欠、予算を扱う。その一方で、仕組みだけでは解決できないことも、実際に運営して見えてきました。

機能を増やすことと、連絡が届くことは、必ずしも同じではありません。便利になった部分と、別の難しさが出てきた部分。その両方があったメンバーサイトでした。

開発や運営でのAI利用についても書きたいことがありますが、それはまた別の記事で。まずは、今回どんな仕組みを作ったのかを、ここに残しておきます。

コメント

タイトルとURLをコピーしました