🚀

【Elixir】関連イベントの開催日を確認できるサイトを作ってみた

2022/02/05に公開

タイトルの通りですが、connpassに掲載されているelixir関連イベントを一覧で見れるサイトを作りました🗓

https://elixir-jp-calendar.fly.dev/

Image from Gyazo

モチベーション

fukuoka.exで月1程度でイベントを主催しているのですが、他コミュニティのイベントと予定がコンフリクトすることが増えてきました。

https://fukuokaex.connpass.com/

イベントが多いこと自体は幸せなことですが、せっかく開催するなら参加いただける方が気兼ねなくイベントに参加できるように、ある程度調整しつつイベントを開催したいという想いから、えいやっと作成しました。

開催されているイベントをざっと見て、興味があるイベントがあればぜひ参加してもらえたら良いなと思っています。

掲載内容

connpassのAPIを利用して、1hに1回の頻度で新規イベント順で取得しています。DBで永続化していない(後述)ため、100件より前のは見れません。まぁそこは要件から外していいかなと。

画面からは

  • あらかじめピックアップしたElixirコミュニティのイベント
  • elixir のキーワード検索でHitしたイベント

の2種類を選べるようにしています。

検索クエリとしては次のようになります。

種類 クエリ
コミュニティから検索 count=100&order=3&series_id=5294&series_id=...
キーワードから検索 count=100&order=3&keyword=elixir

connpassグループにはそれぞれ series_id というのが割り振られており、それを複数指定することで検索が行えるようでしたので、そのように実現しています。

series_idについて

series_id はconnpass画面から確認できない(?)値のため一度apiを叩いて確認する作業が必要でした。イベントページのHTMLの中にも埋まっているようなのでそこで確認してもいいかもしれません。

ひと通り収集したのち、コード内に固定値で持たせています。仮にコミュニティの増減があればここを修正することになります。

https://github.com/koga1020/elixir_jp_calendar//blob/749b0dba79dd4b566634850336926dd366f95a14/lib/elixir_jp_calendar/event_server.ex#L3-L4

  @communities [
    %{
      name: "fukuoka.ex/kokura.ex/EDI",
      series_id: 5294,
      url: "https://fukuokaex.connpass.com/"
    },
    %{
      name: "piyopiyo.ex",
      series_id: 11907,
      url: "https://piyopiyoex.connpass.com/"
    },
    %{
      name: "NervesJP",
      series_id: 8800,
      url: "https://nerves-jp.connpass.com/"
    },
    %{
      name: "LiveView JP",
      series_id: 12092,
      url: "https://liveviewjp.connpass.com/"
    },
    %{
      name: "autoracex",
      series_id: 11144,
      url: "https://autoracex.connpass.com/"
    },
    %{
      name: "beam-lang.tokyo",
      series_id: 1632,
      url: "https://beam-lang.connpass.com/"
    },
    %{
      name: "OkazaKirin.beam",
      series_id: 9575,
      url: "https://okazakirin-beam.connpass.com/"
    },
    %{
      name: "kochi.ex",
      series_id: 8111,
      url: "https://kochi-ex.connpass.com/"
    },
    %{
      name: "清流Elixir",
      series_id: 7578,
      url: "https://elixir-sr.connpass.com/"
    },
    %{
      name: "エリジョ ~Elixir女子部~",
      series_id: 9138,
      url: "https://elijo.connpass.com/"
    },
    %{
      name: "Sapporo.beam",
      series_id: 8525,
      url: "https://sapporo-beam.connpass.com/"
    },
    %{
      name: "space.ex",
      series_id: 10320,
      url: "https://spaceex.connpass.com/"
    }
  ]

Elixirコミュニティは k.nako さんが作成されたコミュニティの歩き方資料に乗っているコミュニティをピックアップしています。

https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian

実装について

リポジトリを公開しておきます。何かの参考になればと思います。

(HTML・css周りはほぼdefaultでちょっといじった程度なので無視してください😇)

https://github.com/koga1020/elixir_jp_calendar

作業の流れ

仕事終わりに夜な夜な進めた感じで、totalでは10時間程度だと思います。本番環境はfly.ioを使っています。

以下記事に書いた通りに進めてサクッとデプロイしています。生成コマンド最高...!!

https://zenn.dev/koga1020/articles/b60725143bbadf6a2b5a

  • 2/2
    • アイデアを思いつく
    • mix phx.new elixir_jp_calendar --no-ecto でゼロからスタート
    • fly.ioへ空プロジェクトをdeploy
    • ライブラリ調査。FullCalendarなるものが良さげ→導入
  • 2/3
    • FullCalendarのdocumentとにらめっこ
    • Connpass API部分実装
    • GenServer実装
    • LiveViewでとりあえず実装するも、FullCalendarのライブラリとうまく合わせられず断念
      • 自分のLiveView力が低いだけだが、特に用途ないから今回は見送り
  • 2/4
    • LiveView → 通常のControllerを使った実装に修正
    • cssを軽くいじる。なにもわからない
    • 全体リファクタ
  • 2/5

Point

FullCalenderのEvent Sourceを利用する

FullCalendarにはイベントデータの取得先を指定して、読み込み時にGETリクエストを投げてデータを読み込んでくれる機能があったのでこれを利用しました。

  • バックエンドにイベント情報を返却するAPIを生やす
  • リクエスト先に指定
  • extraParams で追加のパラメーターを指定
    • コミュニティベースの検索 or キーワードベースの検索かをバックエンドに渡す

という具合に実装しています。

  events: {
    url: "/events",
    extraParams: function () {
      let selectEl = document.getElementById("source");
      return {
        source: selectEl.value,
      };
    },
  },

https://fullcalendar.io/docs/events-json-feed

GenServerを使ってデータを永続化する

毎回connpassのAPIを叩くのはよろしくないため、サーバー起動時&そこから1時間おきにconnpassのAPIを叩いてGenServerに保持しているイベント情報を更新しています。

connpassへのリクエストも robots.txt を参照して、5sec間隔空けるようにしています。

DBなしのシンプルな作りです。最近好きなやり方です。

参考

https://hexdocs.pm/elixir/GenServer.html#module-receiving-regular-messages
https://qiita.com/MzRyuKa/items/268bc4824703feaf8b2c

paramsの導入

せっかくならあまり触ったことのないライブラリを入れてみようということで、検索パラメータのバリデーションをparamsを使って実装してみました。

無効なパラメータが渡されたら無視してデフォルトの値に置き換えるという動きにしました。use Params と書いてあったら「ここにバリデーションの処理が書いてあるんだな」というのがパッと分かるようになるので良いですね。

https://github.com/koga1020/elixir_jp_calendar//blob/a69020659fcf6837015031d766bfa8588f357d4a/lib/elixir_jp_calendar_web/params/event/index_params.ex#L0-L1

参考:

https://qiita.com/shkomine/items/98bb5c401e4267f43571
https://qiita.com/enerick/items/ee7f4321a507f418388b

commandexの導入

これもparams同様、勉強がてら導入しました。connpassにAPI callする処理に利用しています。

  • APIリクエスト先のURL作成
  • API実行
  • decode処理

というのがパッと読めるコードになったと思います。

https://github.com/koga1020/elixir_jp_calendar/blob/547e85092d3c317d01c1b8bbbcba4248161f6cf5/lib/connpass/search_event.ex#L1

commandexについて先日記事も書いたのでよければぜひ。

https://zenn.dev/koga1020/articles/db3f0eb4b76632af4d39

まとめ

Elixirでの開発はやはり楽しいですね!今回はFullCalendarというライブラリに甘えてLiveViewは登場しませんでしたが、また何らかネタが降りてきたらLiveViewを使った実装にもTryしたいところです。

最後に

宣伝続きで恐縮ですが、今月2/24(木)にイベントやります。早速カレンダーを使ってイベントがない日にしました。

オンライン開催でどこからでも参加できますので、興味がある方はぜひご参加ください!

https://fukuokaex.connpass.com/event/238834/

Discussion