🐿️

週間スケジュール画像を作成するサービスを開発した 📅

2024/12/01に公開

週間スケジュール画像?

こういうやつです。

配信者の方々が多く作成してる印象です。このスケジュール画像を簡単に作成するWebアプリを開発しました。プレイグラウンドがあるので、よかったらお試しください。
(上の画像はプレイグラウンドで作れます)

https://scheduirrel.com/ja

特徴

週間予定を簡単作成

美しいスケジュール画像を簡単に作成できます。
1週間のスケジュールの開始日を決めたら、あとは予定を入力するだけで完了です。
多彩なレイアウトやテーマでお好みのデザインにできますよ!

Webで公開

スケジュールをWebで誰にでも公開できます。スマホでの縦長表示にも対応してます。またOGPもスケジュール画像なので、SNSで簡単にスケジュールを共有できます。
↓こんな感じです

https://x.com/taki0010/status/1861707226504896566

画像として保存

スケジュールを画像として保存できます。そのまま配信のサムネイルやメールの添付にいかがでしょうか📅。

日時の国際化

スケジュール画像にJST(日本時間)だけじゃなく、EDT(米国東海岸時間)などを載せている人もいますが、そういった国際化も自動で処理します。
また、上で挙げたWebページ版は訪問者のタイムゾーンに合わせた表示も可能です。

AIによるテーマ作成

「カラフルで可愛らしい感じで」みたいな指示を出すだけでAIがテーマを作成してくれます。使用制限はありますがぜひ一度お試しください。

動機

多くの配信者が直近の予定を共有するためにこういう画像を作っているので、需要も一定数あるだろうと考えました。技術的にもHTMLとCSSで行けるだろう、と。

技術構成

Cloudflare

  • Pages
  • R2
  • D1

Google Cloud

  • Cloud Run 関数
    • Puppetterでスケジュールのスクリーンショットを撮って画像化しています。最初はCloudflareのBrowser Rendering APIを使ってたんですが、制限がきつくてやめました。
  • Sign-in
    • ユーザー認証はこれだけです。

React Router 7

  • Shadcn UI
  • Tailwind CSS
  • Drizzle
  • Vite
  • Remix Auth
  • Valibot

Remixで作ってましたがReact Router 7 に移行しました。
ファイルアップロードの移行の記事を書きました。

https://zenn.dev/taki/articles/7c317d6612743a

Claude

後述するAIによるデコレーションで使ってます。
ほかの同種のサービスも試してみましたが、Claudeが最も高精度でした。
使っているのは Claude 3.5 haiku 20241022 です。

AIによるデコレーション

ユーザーは、AIを活用して好きなテーマを作成できます。
ユーザー登録後の編集画面でお試しいただけます。

プロンプトは「ユーザーの指示や要望を適切に解釈し、MaterialDesign3のカラーセットを構成してください」といった内容です。
例えばユーザーが「ホラー調のデザインにしてください」みたいに言うと、だいたいSurfaceは黒系で、Primaryは赤系といった構成が返ってきます。

なぜ Material Design なのか

公開されていて有名なデザインシステムなのでAIの習熟度も高いだろうと考えました。
例えばPrimaryとかSurfaceといったロールにはそれぞれデザイン上の役割が定められています。自分が試した範囲では、細かく指示しなくても基本的にはロールの役割に沿った配色をしてくれます。
例えば背景に使用されるSurfaceが真っ赤になるような配色は基本ありません。(あえてそう指示すれば別ですが)

テーマのインポート

ユーザーは他のユーザーが作成したテーマをインポートして、自分のスケジュールに使用できます。
ほかのユーザーが作ったテーマの一部はプレイグラウンドでも使用できます。こういうテーマが作れるんだというイメージが湧けば利用者増にもつながると考えています。

時刻の処理

週間予定の作り方

まず、1週間の開始日を設定します。UTCで保存しますが同時に作成者が選択したタイムゾーンも保存します。
開始日でDateオブジェクトを作るときに必ずこのタイムゾーンに基づいた時間を渡します。
次にイベントを入力しますが、保存するのは開始日の0時からのオフセット値(分)です。例えば1週間の開始日が月曜日だったとして、火曜日の午前9時のイベントは1980分後なので、offsetに1980を保存する感じです。
毎週スケジュールを作る場合、各曜日のイベント時刻は毎回そこまで大きくは変わらないだろうと思います。このやり方なら開始日を変えるだけで各曜日のイベント時刻は維持されます。

時刻の国際化

Webで公開するスケジュールは、訪問者のタイムゾーンに合わせた時刻表示が可能です。
これも開始日のタイムゾーンを変えるだけである程度完了します。

クライアントのタイムゾーンを取得する方法はこちらです。

const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone

"Asia/Tokyo"とか"Europe/London"とか取得できます。
あとは開始日でDateオブジェクトを作る際にこのタイムゾーンに基づいた時間を渡せば、訪問者のタイムゾーンに合わせた表示になります。

なぜ時刻の国際化を実装したか

国外の聴衆とのつながりを強化したかったからです。
週間スケジュール画像の使用者の多くは、国内外のストリーマー(というかVtuber)ですが、海外の配信者は複数のタイムゾーンを記載したスケジュール画像を作成することが一般的です。一方で、国内の配信者はタイムゾーンなしの時刻を記載しているケースが多いと感じます。

しかし、日本のVtuberのファンは国内に限らず、海外にも多く存在します。有名どころはもちろん、無名のストリーマーでも配信中に日本語以外(主に英語)のコメントが寄せられることは珍しくありません。

こうした海外のファンとの結びつきを強化するために、国際化されたスケジュールを共有することは有効だと考えました。

もちろん、ストリーマー以外にも国際化されたスケジュールの需要はあると思います。たとえば、近年増加している外国人観光客を考慮すると、観光地のイベント日程を国際化して共有することも、訪問者の利便性向上につながるはずです。

プレイグラウンドは開発にも役立つ

ログインしないと何もできないのは避けたかったので、トップページにプレイグラウンドを設置しました。実際の編集画面の機能に加えて、押すだけでレイアウトやテーマが切り替わるランダムボタンを設置したんですが、これがアリでした。
ボタンをぽちぽちするだけでデザインがチェックできるので、ユーザー向けに作った機能でしたが、開発において非常に有用でした。👍

おわりに

Googleカレンダーのようなサービスもスケジュールの共有は可能ですが、こちらの画像ひとつで完結する分かりやすさは強みだと思いますし、より拡散力も高くなるはずです。

サービスに関する要望や意見などはSNSやお問い合わせから遠慮なくお送りください。
よろしくお願いします。🤝

Discussion