見出し画像

スプラトゥーン3のwipeout動画を集めて表示するサービスを作った

はじめに

こんにちは。noteのエンジニアのsacckeyです。
この記事はnote株式会社 Advent Calendar 2022の19日目の記事です。

スプラトゥーン3、やってますか?
私は2022年9月9日の発売日から今日まで寝る間も惜しんでやっています。

先日スプラトゥーン3の動画付きTweetを集めて表示するサービスを公開したので、そのサービス内容と実装について紹介します。

つくったもの

wipeout.ink

GitHub

スプラトゥーン3をやっている人向けのサービスの紹介ですが、サービス自体は単純に動画を表示するだけなので、やったこと無い人でも内容は伝わると思います。是非読んでください。
技術的な話は一番最後に記載しています!

事前知識

スプラトゥーン3をやったことない人向けの説明です。
スプラトゥーン3は4人チーム対4人チームのアクションシューティングゲームで、各プレイヤーはルール毎に決まった勝利条件を満たすために相手プレイヤーを倒したり、フィールドをインクで塗ったりします。
倒されたプレイヤーは操作不能になってフィールドを離れ、一定時間経過後にフィールドに復活します。
短時間に相手チームの4人全員を倒すと、以下の画像のようにWIPEOUT!!!と大きく表示されます。

WIPEOUT!!!

この瞬間、相手全員がフィールドにいない状況になるので自チームが大きく有利になり、嬉しい気持ちになるのと同時に、大きな爽快感が得られます。
また、かっこよくwipeoutできたときはその動画を録画して他の人に見せたくなるし、他の人のとっておきwipeout動画も見たくなります。

つくったもの(再掲)

そこで、wipeout動画を埋め込んだツイートを集め、それを表示するサービスをつくりました。

リンク

スクショ

とてもかっこいいUI

しくみ

Switchから投稿された、ハッシュタグ #Splatoon3 #wipeout が付与されたツイートを検索して保存し、それを表示しているだけです。
例えばポケモンの動画にハッシュタグ #Splatoon3 #wipeout を付与して投稿しても表示されます。やらないでね。

使い方

1. 動画を保存する

wipeoutしたらNintendo Switchのキャプチャーボタンを長押しして動画を保存します。長押しすると30秒前から現時点までの動画がアルバムに保存されます。

2. 動画をTwitterに投稿する

Nintendo Switchのアルバムから動画を選択し、ハッシュタグ #Splatoon3 #wipeout を付与してTwitterに投稿すると、トップページに投稿が表示されます。 ( ハッシュタグ #Splatoon3 は、ツイートを作成した時点で勝手に入るはずです。)
動画投稿手順はこちら

3. Twitter連携する

※ 動画の閲覧や投稿はTwitter連携しなくても行うことができます。wipeout.inkのloginボタンからTwitter連携をすると、動画右上の☆マークをクリックで投稿をお気に入りに追加できるようになります。また、自分が投稿した動画やお気に入りに追加した動画を、一覧ページから見れるようになります。

画面右上のアイコンをクリックすると会員用メニューが表示されます(noteと同じ!)

おすすめ動画

私の動画です。
最後の1人をウルトラショットで倒しているところが芸術点高い。

ウルトラハンコで3人倒してから、最後の1人をぶった斬っててcool

これはびっくり!

wipeoutではないけど好き。

最後に

是非皆さんの秘蔵のwipeout動画を投稿してください!
明日は我らがEM、@fukuiretuさんの記事です。楽しみですね。

おまけ

技術的な話をします。

構成図

wipeout.inkの構成

front以外は全てFirebaseで完結するようにしました。
Cloud FunctionsでTwitter APIを一定間隔で叩き、wipeout動画があったらFirestoreに保存していく感じです。

Firestoreの構成

# tweets/{tweetId}
{
  active: boolean,
  name: string,
  username: string,
  twitterUid: string,
  profileImageUrl: string,
  url: string,
  text: string,
  video: string,
  replyCount: number,
  twitterLikeCount: number,
  retweetCount: number,
  likeCount: number,
  createdAt: timestamp,
  updatedAt: timestamp,
  publishedAt: timestamp
}

# users/{uid}
{
  name: string,
  photoURL: string,
  twitterUid: string,
  createdAt: timestamp,
  updatedAt: timestamp
}

# users/{uid}/likes/{twitterId}
{
  tweet: {
    ref: reference
  },
  createdAt: timestamp,
  updatedAt: timestamp
}

データはこのように持っています。
tweetsはusersのサブコレクションなのでは?と思うかもしれませんが、tweetsにTwitterのuidを一緒に保存しておくことで、uidからそのユーザーのtweet一覧を取得できるようにしています。
usersテーブルにはwipeout.inkでtwitter連携したユーザーのデータを保存していて、likeしたtweetデータをサブコレクションとして持っています。

このように保存しておくとセキュリティルールも簡潔に書くことができる嬉しさもあります。tweetsは読み取り限定にして、usersはFirebase Authで認証した本人のみが読み書きできるようにしておけばOKです。

 Cloud Functions

以下のことをやっています。

■ tweetデータの保存
Search Tweets APIを叩いて#Splatoon3 #wipeout が付与されたtweetを検索し、保存しています。このAPIは検索時にsource(=どのクライアントから送信されたか)でフィルタリングができないため、tweetを取得したあとにsourceがNintendo Switch Share以外のtweetを除外するようにしています。

■ tweet.likeCountの増減
userがtweetをlikeすると、users/{uid}/likes/{twitterId}にデータが作られます。これをトリガーにして、tweetがlikeされた回数であるtweet.likeCountをインクリメントしています。逆にlikeを解除したときにはデータが削除され、これをトリガーにしてデクリメントしています。

■ tweetデータの最新化
Firestoreに保存しているtweetがtwitter上で削除された場合、添付されていた動画は再生できなくなります。また、twitter上でユーザーアイコンを変更した場合は、wipeout.ink上のtweetのアイコン部分がリンク切れになり表示できなくなります。
これに対応するために、一定期間毎に保存されたtweet全てについてTweets lookup APIを叩いて最新化しています。このときtweetが削除されていた場合は、tweet.active=falseに更新し、表示されなくなるようにしています。

front-end

Next.js + tailwind on Vercelです。
ISRで最新30件を表示し、それ以降は無限スクロールで表示します。
無限スクロールの実装はreact-infinite-scrollerを使うと簡単です。

この記事が参加している募集

つくってみた