GameWith Engineering Blog

GameWith のエンジニア、デザイナーが技術について日々発信していきます。

LINE Messaging APIでモンストのマルチ募集が捗るチャットボットを作ってみた #GameWith #TechWith

f:id:gwchai:20181206165111p:plain

GameWith Advent Calendar 2018 9日目担当のiOSアプリエンジニアの chuymaster です。

先日、LINE DEVELOPER DAY 2018に参加してきて、クロージングセッションでの「今日のカンファレンスで聞いた内容で何かを作って欲しい」というメッセージを真に受けて、勢いでチャットボットを作った話を共有したいと思います。

サービスの背景

GameWithが取り扱っているゲーム攻略情報の中で、「モンスト」ことモンスターストライクが非常に人気で、多くのユーザーに見ていただいています。

f:id:gwchai:20181205165616p:plain
モンスト攻略

モンストには、「マルチプレイ」というモードがあって、最大4人で集まってゲームをするとクエストがクリアしやすくなったり、報酬がたくさんもらえたりします。

GameWithアプリでは、プレイヤーが集まりやすいように、「自動マルチ募集掲示板」機能を提供しています。クリアしたいクエストに、欲しい条件のプレイヤーに一緒にマルチしてもらえる掲示板です。

f:id:gwchai:20181205170741p:plain:w300
GameWithアプリ「自動マルチ募集掲示板」

GameWithユーザーが抱える課題

さて、そんな便利なマルチ自動掲示板ですが、実は一つ手間があります。

それは、募集のとき、募集メッセージをLINEからコピペする必要があることです。

f:id:gwchai:20181205172636p:plain:w300
マルチ募集画面

募集する手順は

  1. モンストでクリアしたいクエストのLINEでのマルチ募集を選ぶ
  2. LINEで友達を探す
  3. 友達に募集メッセージを送る(LINEチャットボットに送ることが多いらしいです)
  4. 送ったメッセージをコピーする
  5. GameWithアプリの募集画面を開く
  6. メッセージをペーストする
  7. 条件を決めて募集を始める

・・・長い!

募集メッセージを保存しておいたり、LINEを経由しない裏技的なことをしてマルチ募集の手間を減らすこともできますが、 公式の手順で、自然な流れで、「本当の友達とマルチする」みたいに募集したいというユーザーが多いはずです。

f:id:gwchai:20181205180859p:plain:w300
私はLINEデリマをいつもマルチに誘っていますw

そこで、LINEを通すことは仕方ないのなら、その後の手間をなくそう!という発想が、今回のチャットボットを作成する経緯になります。

どんなチャットボット?

「マルチ募集をワンタップでできる」チャットボットです。

このチャットボットにマルチ募集メッセージを送ると、GameWithアプリで募集するURLを返信してくれます。

そのURLをタップするだけでGameWithアプリで募集の必要な項目を埋めてくれて、コピペ要らずに募集開始ができるようになります。

f:id:gwchai:20181205184026p:plain:w300
マルチ募集お手伝いチャットボット(画面は開発中のものです)

デモ動画

さっそくデモ動画を見ましょう!

f:id:gwchai:20181206130223g:plain
チャットボットでマルチ募集

ポチポチタップするだけで募集ができて、サクサク感が伝わるんじゃないかと思います!

それでは、実装の説明をしていきます。

チャットボットの準備

まずは、公式のチャットボットサンプルでのセットアップです。 私はPythonが少し書けるので、Pythonのサンプルを選び、こちらの記事を参考に開発を始めました。

qiita.com

LINE@のアカウント作成、Herokuの環境作成は上記の記事で詳しく説明しているので割愛します。

ただし、記事で紹介された flask-echo というオウム返しするだけのサンプルを使うと、 LINEのチャットボットは何ができるかイマイチわからないので、flask-kitchensink (https://github.com/line/line-bot-sdk-python/tree/master/examples/flask-kitchensink)を使いました。

f:id:gwchai:20181205170713p:plain:w300
flask-kitchensinkボット

実装

ボット返信の大まかな流れは

  1. 送信者から受け取った、マルチ募集メッセージをサーバーに一時的に保存する
  2. メッセージファイルのURLを、GameWithアプリで処理するURLスキーマ gamewith:// のパラメータにくっつける
  3. 送信者に返信する

パラメータを受け取った後の処理はアプリ側の責任になります。

  1. URLスキーマを解析する
  2. メッセージファイルのデータを取得する
  3. 取得したデータを文字列に変換する
  4. マルチ募集画面を開いて、文字列を入力ボックスにセットする

アプリ側の実装は詳細を割愛します。以下、サーバー側の実装を説明します。

1. 送信者から受け取ったメッセージをサーバーに一時的に保存する

嬉しいことに、flask-kitchensink のサンプルでは既に画像を一時的に保存する処理が実装されているので、それを活用します。

もらったテキストをファイルに保存して、URLを返すメソッドを作りました。

def write_message_to_file(text):
    ext = 'txt'
    with tempfile.NamedTemporaryFile(dir=static_tmp_path, prefix=ext + '-', delete=False) as tf:
        tf.write(text.encode())
        tempfile_path = tf.name

    dist_path = tempfile_path + '.' + ext
    dist_name = os.path.basename(dist_path)
    os.rename(tempfile_path, dist_path)

    message_url = (request.host_url + os.path.join('static', 'tmp', dist_name)).replace("\\","/")
    return message_url

2. 保存したファイルのURLを、GameWithアプリで処理するURLスキーマ gamewith:// のパラメータにくっつけて返信する

ここは単純に文字列を結合するだけです。URLスキーマと処理するパラメータは予めアプリ側と合意を得る必要があります。

def get_monst_reply_message(message_url):
    message = "このURLをタップして、GameWithアプリですぐマルチ募集を始めよう!(*'▽')\n"
    gamewith_app_prefix = "gamewith://line?message_url="
    return message + gamewith_app_prefix + message_url

3. 送信者に返信する

linebotのSDKを使って返信します。サンプルからコピペするだけで良いです。

def handle_text_message(event):
    #-------
    # サンプル中略
    #-------
    elif "https://static.monster-strike.com/line" in text:
        message_url = write_message_to_file(text)
        reply = get_monst_reply_message(message_url)
        line_bot_api.reply_message(
            event.reply_token,
            TextSendMessage(text=reply)
        )

今後の課題

価値の検証

ユーザーが使って本当に喜ぶかどうかを検証する必要があります。まず社内の攻略チームの方々にお願いして、使ってフィードバックをもらおうと考えています。

全体的なユーザーフローの設計

チャットボット自体は便利ですが、歓迎メッセージや使い方の説明をちゃんと案内してあげないとユーザーが離脱してしまいます。 価値検証できたら、ユーザーフローやサポートを含めた設計をします。

本番稼働に向けた開発

まだプロトタイプ段階なので、Herokuの無料プランでチャットボットを稼働させていますが、 本番稼働に向けて、安全性・安定性・メンテナンス性を考慮した開発が必要になります。 この辺りのサーバーサイド開発はほぼ経験がないので、他のサーバーエンジニアからいろいろ学ぼうと考えています。

最後に

私はiOSアプリエンジニアですが、今回はサーバーのコーディング、社内でまだ使ったことのないLINE Messaging APIという未知の領域に挑戦しました。 GameWithは、会社のミッションである「ゲームをより楽しめる世界を創る」ことに繋がる挑戦を積極的に応援しているからこそ、実施できたと思います。

そんなGameWithは、ゲームが大好きで、新しい技術をどんどん使っていきたいという方を大募集中! Wantedly でもよいので是非お気軽にお声がけください!

www.wantedly.com

AndroidのプロジェクトにCIを導入した話 #GameWith #TechWith

はじめまして、GameWithのエンジニアのソンです。 今回はGameWith本体アプリのAndroidプロジェクトにCIを導入した話をします。

まずはどうしてCIを導入しようと思うのを説明させていただきます。 PullRequestを作る時に、人為的なミスでそもそもBuildやUnitTestが通らないことたまにあります。この問題はCIの導入でReviewする前に必要ない人力が省けます。

また、複数人のプロジェクトにはある程度のCode Styleを制限しないとCodeの可読性がすぐ悪くなります。

 

ゴール

f:id:w_sun:20181204153724p:plain

  1. CircleCI 2を導入
  2. UnitTestを行う
  3. APKをビルド
  4. Danger経由で、GithubにKtlintからのエラーメッセージをコメント
  5. 3.で生成したAPKをDeployGateにアップロード

Circle CI 2を導入

社内のGithubアカウントは既にCircleCiと連携してますので、新しいプロジェクトに導入するのは難しくないです。

導入したいプロジェクトの「Set Up Project」を押すと、そこには簡単なconfig.ymlの例文があります。チュートリアルに沿ってプロジェクトに配置すると、最初の構築が終わります。次はconfig.ymlにどんどんJob(実行させたいタスク)を追加する感じです。

一応CircleCIは複数のJobを同時に実行することができるので、ここはUnitTestBuildKtlintと三つのJobに分けまして、平行で走らせます。

また、各JobでGradleの初期化を行うと時間がかかりますので、CircleCiのworkspaceを使って、初期化したものを各Jobに提供してます。

UnitTestを行う

  unitTest:
    <<: *defaults
    steps:
      - attach_workspace:
          at: ~/
      - run:
          name: Run UnitTest
          command: ./gradlew testProductDebugUnitTest
      - store_artifacts:
          path: app/build/reports
          destination: reports
      - store_test_results:
          path: app/build/test-results

store_artifactsstore_test_resultsはテスト項目の結果を保存するMethodです。Jobが実行した後にArtifactsで見れます。

f:id:w_sun:20181204153805p:plain

APKをビルド

 normalBuild:
    <<: *defaults
    steps:
      - attach_workspace:
          at: ~/
      - run:
          name: Build
          command: ./gradlew assembleQualityAssuranceDebug
      - persist_to_workspace:
          root: ~/
          paths: code/app/build/outputs/apk/qualityAssurance/debug/

最後のpersist_to_workspaceは生成したAPKをDeployGateにアップロードできるように、workspaceに保留する。

ktlintの実行

  ktlint:
    <<: *defaults
    steps:
      - attach_workspace:
          at: ~/
      - run: ./gradlew ktlintProductReleaseCheck
      - persist_to_workspace:
                root: ~/
                paths: code/app/build/reports/ktlint/

ktlintはGradle pluginsのKtlint Gradleを使ってます (https://github.com/JLLeitschuh/ktlint-gradle

OutputはCHECKSTYLEに設定する、この後はDangerから読み込んでGithubにコメントする。

dangerの実行

  danger:
    working_directory: ~/code
    environment:
      - LANG: C.UTF-8
    docker:
      - image: ruby:2.1
    steps:
      - attach_workspace:
          at: ~/
      - run: gem update --system 2.4.8
      - run: gem install bundler
      - restore_cache:
          key: gem-cache-{{ .Branch }}-{{ checksum "Gemfile" }}
      - run: bundle install --path vendor/bundle
      - save_cache:
          key: gem-cache-{{ .Branch }}-{{ checksum "Gemfile" }}
          paths:
            - vendor/bundle
      - run: bundle exec danger --verbose

DangerはRuby版を使ってます。(https://danger.systems/ruby/)

Dangerfiledanger-checkstyle_formatdanger-lgtmくらい簡単なものしか入れてないです。

  • エラーになる時

f:id:w_sun:20181204160901p:plain

  • 成功する時

f:id:w_sun:20181204160913p:plain

DeployGateにアップロード

 deploy:
    <<: *defaults
    steps:
      - attach_workspace:
          at: ~/
      - run:
          name: Deploy APK
          command: curl -F "token=${DEPLOY_GATE_API_KEY}" -F "file=app-qualityAssurance-debug.apk" -F "message=$(git log --oneline -1)" https://deploygate.com/api/users/

リリースする前にQA版のAPKを使って自動テストを実行してるので、そこの手動生成の手間が省略できます。

以上で簡単なCI導入の手順でした。導入してよかったと思ったところがいくつあります。

  1. Ktlintの導入によって、書き方のミスが防げるようになりました。基本的に人工でチェックするのは不可能ので、非常に助かります。
  2. QAテスト向けのAPKを手動でビルドして、DeployGateにアップロードする手間も省略できました。
  3. 開発する時にDebugBuildすることは多いですが、実際ReleaseBuildの時にBuildが通らないこともたまにあります、これもCIによって事前にわかります。

また、この記事を書いてる途中で気づきましたけど、DangerさんがKtlintを対応してくれました。また試してみます。 :thinking_face:

終わりに

GameWith は、ゲームの楽しさをもっと世界に伝えていきたいエンジニアを大募集中です。 Wantedly でもよいので是非お気軽にお声がけください!

www.wantedly.com

AWS Session Manager を Mac の Terminal から利用する

GameWith Advent Calendar 2018 6 日目担当の @serima です。

最近のマイブームはソードアート・オンライン アリシゼーションです。 SAO シリーズで一番好きなエピソードは「ファントム・バレット」で、気付いたら何度も視聴しています。

Session Manager とは

GameWith ではリモートワーク環境の実現のために AWS Session Manager を利用しています。

AWS Session Manager を利用すると、踏み台サーバが不要になります。 踏み台サーバが不要になるということは、鍵の管理から解放されるということです。

前提として以下を満たしていると、EC2 インスタンスにシェルアクセスが可能になります。

  • シェルアクセスを受け付ける EC2 インスタンスに AWS Systems Manager エージェントがインストールされている
  • EC2 インスタンスの IAM ロールに AWS 管理ポリシー AmazonEC2RoleforSSM が割り当てられている

また、弊社のセキュリティポリシー上 IAM User に MFA 設定(二段階認証)がされていない場合は AWS Session Manager を利用してシェルアクセスができないようになっています。

Session Manager 自体について、詳しくは本家の記事をご覧ください。

このポストでは 「Session Manager の導入が済んでいる状態で、どのように Terminal からシェルアクセスを行うか」についてフォーカスしたいと思います。

aws.amazon.com

Terminal からのシェルアクセス

AWS Console 上から Session Manager を利用する際は当然すでに MFA での認証は済んでいる(Console へのログイン時に確認コードが求められ、それもパスしている)状態なので問題なく利用できます。

しかし、Terminal から aws ssm コマンドを利用して Session Manager に接続しようとすると認証エラーが出てしまいます。(二段階認証ができてないので当然ですね。)

前提

手順

基本的にはこちらの記事(AWS CLI 経由で MFA を使用してアクセスを認証する)を参照していただければ問題ないと思います。

--serial-number には MFA デバイスの ARN を指定、--token-code には二段階認証のコード(6桁の数字)を指定して以下のようにコマンドを叩くと、アクセスキーとトークンが手に入ります。

% aws sts get-session-token --serial-number arn:aws:iam::000000000:mfa/username --token-code 000000 --output json
{
    "Credentials": {
        "SecretAccessKey": "XXXXXXXXXXXXXXXXX",
        "SessionToken": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        "Expiration": "2018-10-15T21:39:58Z",
        "AccessKeyId": "XXXXXXXXXXXXX"
    }
}

取得できた SecretAccessKeySessionTokenAccessKeyId をここでは ~/.aws/credentials に以下のように追記しています。 これらのキーやトークンは一時的なもののため、期限が切れたら(デフォルトでは12時間)再設定する必要があります。

[mfa]
output = json
region = ap-northeast-1
aws_access_key_id = XXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXX
aws_session_token = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

その後

% aws ssm start-session --target i-someinstanceid --profile mfa

と、することで Terminal から指定したインスタンスに接続ができます。 ログイン時のユーザは ssm-user ですが sudo で昇格が可能です。(パスワードなし)

ubuntu ユーザになってからは [tab] キーでの補完が効くようになりました。

f:id:serimaryo:20181130231632p:plain

Session Manager で接続中にネットワーク切断した際の挙動

Terminal からの接続テストを行っている際に、ちょっとした実験を行いました。そちらは別記事として投稿してありますので、興味があれば、ぜひご覧ください。

qiita.com

終わりに

Session Manager は割と最近リリースされたものなのですが、インフラエンジニアの方がすかさず検証をして本運用まで導いてくれました。

GameWith では現在のところ AWS を利用していますが、最近は GCP の活用も本格的に始めています。

そのような環境下で、適材適所でクラウドベンダーを選択できるようなインフラエンジニアを募集しています!

www.wantedly.com

参考記事

Mac のプレビューで Slack カスタム絵文字を効率的に作る

GameWith Advent Calendar 2018 5 日目担当の id:syque です。三度の飯より Slack のカスタム絵文字を作るのが好きです。

弊社エンジニアチームでのコミュニケーションは Slack で行われているのですが、カスタム絵文字も人が増えるにつれ順調に増加し、本日 2018/12/5 時点では 583 emoji が登録されていました。

f:id:syque:20181204124715p:plain
大丈夫? だめだ...ダメです。ダメらしい🤢


何やら危なげな絵文字が登録されていますが、実際のSlack上の利用例を見てもなかなかにカオスです。


f:id:syque:20181204155220p:plain:w300
リンクをシェアするときにさりげなく parrot gif


f:id:syque:20181204155354p:plain:w250
明日から本気出す。


f:id:syque:20181204161258p:plain:w450
ポケモンにはポケモンの絵文字でリアクション。


f:id:syque:20181204155735p:plain:w350
港区。GameWithは港区にあります。なんだこれは。てぇてぇ。


うまくコミュニケーションできてるのかできてないのかよく分からない感もありますが...概ねメッセージに添えたりリアクションに用いたりとで表現の幅を広げるのに活用できているかと思います。

本題

本題です。カスタム絵文字を作成するためには当然素材が必要なわけですが、巷のトレンドもそうですが自社組織・携わる業界ならではのニュースやトレンド、ミームなどがありそこで出回っている事象をカスタム絵文字にしたい! という欲求も出てくるかと思います。

そういった時に加工が必要であればAdobeなど各種画像編集ツールを使って...とやるところですが、エンジニアだと会社のMacにインストールされていないということもままあり得ます。ですがちょっとした切り抜きやサイズ・色味調整であればOS標準機能やMacのプレビューでも問題なく行えたりします。今回はいくつか紹介します。

領域のスクリーンショットを取る

OS標準機能として、⌘ + Shift + 4 で領域を選択してのスクリーンショットが保存できます。デスクトップに保存されます。

f:id:syque:20181204174528p:plain

例としていらすとやさんの塩水ウニの画像を選択して取得してみます。

f:id:syque:20181204174812p:plain:w100

このように取得できます。(もちろんダウンロードできるものはした方が早い)

サイズ変更 & 切り抜き、クロップ

プレビューの機能です。⌘ + Shift + A または 表示 -> マークアップツールバーを表示 でツールバーを表示し、中央付近にあるサイズ変更のボタンをクリックします。

f:id:syque:20181205100322p:plain

サイズ変更のダイアログが表示されるので、任意のサイズに変更します。

f:id:syque:20181205100916p:plain:w250

Slack のカスタム絵文字のサイズは 128x128px と決まっているので、これに合わせてリサイズしたりなどが主な用途になるかと思います。

またサイズ変更するにあたって不要な部分などを切り取りたい場合があるかと思います。 こうした場合に領域を選択して、⌘ + Delete で切り取り、⌘ + K でクロップ(切り抜き)が行えます。(後述のテクニックでも紹介しますが、⌘ + C コピーや ⌘ + X カットもできます) 領域を選択する際に Shift を押しながらドラッグすることで枠の比率を維持することができますので、例えば絵文字向けに正方形に切り抜きたい場合に有効です。(この操作はスクリーンショットの領域切り抜きの際にも利用可能です。) また選択中の枠はドラッグやカーソルキーで動かすこともできますので、境界のピクセルに合わせる際などに有用です。

f:id:syque:20181205104025p:plain:w300

f:id:syque:20181205104322p:plain:w300

綺麗に正方形に切り取ることができました。これを 128x128px にリサイズすれば絵文字に登録できます。

人物などを切り抜き

背景色を自動選択しての切り抜きができます。マークアップツールバーの左から二番目にある色選択ツールのアイコンをクリックします。

f:id:syque:20181205102453p:plain

画像の背景部分をクリックし、任意の方向にドラッグします。これにより色の選択範囲を調整できます。 参考画像だとシンプルな背景色なので分かりにくいですが、木の葉など似た色味を選択してくれるのでうまく範囲選択できれば綺麗に人物などを切り取ることができます。

f:id:syque:20181205102930p:plain:w350

f:id:syque:20181205103357p:plain:w350

このような形に切り取れます。写真とかだと背景が複雑なことも多いので、ある程度切り取って残りは選択ツール(矩形や丸など)で不要な部分やゴミを切り取っていくと良いです。 この例だと輪郭に白い線が残っていたり、スカーフの白い部分まで消えてしまっていたりするので調整が必要です。⌘ + Z でUndoが可能なので切り抜く前の状態に戻し、下の余白を切り取ってから領域選択をもう少し深めに実行してみます。

f:id:syque:20181205105411p:plain:w350

先ほどよりはかなりマシになりました。(あまり変わらない? スカーフは直った...)まだ白い線が残っていたりはしますが、絵文字に使う用途であれば 128px まで縮小されるので、多少のゴミや輪郭は無視してもそれほど見栄えには関わりません。あくまでプレビューを使って気軽に...という範囲なのでこのくらいの気持ちで作ってしまいましょう。

(応用) 複数の画像を重ねる

応用として、複数の画像を重ねるというものをやってみます。 例として、先程切り取った人物の画像にウニの画像を重ねてみます。

二つの画像をそれぞれプレビューで開きます。

f:id:syque:20181205111137p:plain:w350

ウニのプレビュー画面で ⌘ + A で全選択し、⌘ + C でコピーします。その後、人物のプレビューで ⌘ + P でペーストします。

f:id:syque:20181205111359p:plain:w350

ウニの画像がペーストされます。この画像はドラッグで移動、角の丸をドラッグでサイズ変更ができるので配置したい場所まで移動&リサイズします。

f:id:syque:20181205111500p:plain:w350

画像を重ねることができました。透過部分は重ねた時にもきちんと透過するので、前述の切り抜き処理と組み合わせるとかなりクリエイティブの幅が広がります。


登録してみる

せっかく作ったので絵文字に登録してみます。アメデオアヴォガドロがウニを持っているのでそのままの名称で登録します。

f:id:syque:20181205112319p:plain:w350

無事に登録し、Slack で使うことができるようになりました。

f:id:syque:20181205112709p:plain:w350

この発言の後にチャンネルの会話の流れが止まってしまった気がしますが、そんな日もあります。ハイコンテクストな会話を重ねることでチームメンバーのコミュニケーションを高めていくことができるのです。 *1


終わりに

非デザイナーでもMacのプレビューでこのような感じに絵文字が作れます。自分で作った絵文字をメッセージやリアクションに使うと愛着も湧くしコミュニケーションもより活発になること受け合いです。*2

今回紹介した以外にも Mac のプレビューの使い方や絵文字の作成ツール(アニメーションGIFにしたり)などもありますので、皆さまこれを機に良いSlack絵文字ライフを送って頂ければ幸いです。

*1: 言い訳

*2: ハメを外しすぎて業務に支障が出ないようには注意しましょう 👀

HTML5 Conference 2018に参加してきました! #html5j #GameWith #TechWith

GameWith Advent Calendar 2018 4日目担当の GameWithのエンジニアの tiwu です。

先日開催されたHTML5 Conference 2018に参加してきました!

f:id:tiwu_gamewith:20181201155309j:plain
お疲れ様でした!

HTML5 Conferenceに参加するのは3度目で、毎回刺激をもらっています。

今回も見たいセッションがたくさんあったのですが、厳選に厳選を重ね以下のセッションを見ました。

  • 光を超えるためのパフォーマンスチューニング/アーキテクチャ
  • カンファレンススポンサーによるライトニングトーク大会
  • 「それ、AMPで作りませんか?」--- RichでResponsiveかつPWAなAMPの作り方
  • Web Components のリアル
  • Web プラットフォーム再考 ~PWA のもたらす未来の光と影 ~
  • HTTP の今と未来 ー BBR, HTTP/2, QUIC の基礎から 5G 試験ネットワークでのブラウザベース評価試験まで
  • スペシャルセッション

各セッション簡単にですが概要と感想を書いていきたいと思います。

光を超えるためのパフォーマンスチューニング/アーキテクチャ

  • 賽の河原でdivを積む
  • この世界の光の速度はとても遅く、世界中の人とリアルタイムにゲームするにはまだ耐えられない(格ゲーなど致命的
  • 60fpsをwebで目指す= 16msの壁を超える必要がある
  • フロントから見たらサーバーというものはデータをシンクするシステム
  • ローカルキャッシュ > CDN Edgeキャッシュ > サーバーキャッシュ > クエリ叩く
  • しかしキャッシュの設計は難しい
  • 高速化は目的ではなく結果に過ぎない=高速化ができるキレイなアーキの証明
  • コードの綺麗さと速度は両立する
  • つまりみんな綺麗なコードを書こう

SWでHTMLキャッシュをしてサイトを作ったことがあるのですが、あれは本当に光を超える・・・

ただキャッシュ破棄戦略とかが難しい・・・

ここの戦略の難しさは綺麗なコードによる綺麗なアーキが繋がってくるんですね・・・!

資料

カンファレンススポンサーによるライトニングトーク大会

印象に残っているのは新人研修でSlackを作ったLTで、サイバーエージェントさんの新人研修のレベルの高さとそれを超える新卒の技術力を感じました。

ほかチームが機能を沢山開発している中で、開発フローや開発体制などに力をいれ、賞を取ったそうです。

※ビデオチャット?の時に美肌加工する機能などあったらしいです(うろ覚えです

最後に苦労した点を聞かれた際に「他チームが機能を作っている中、開発フローなどに力を入れたため、他チームと比べて遅れている、進捗が悪いなど不安になった」と言っていました。

しかし、メンターに相談して不安を取り除いてもらい自信もって開発を進めることができたそうです。

新人研修の内容、新人、メンター全て合わさって素晴らしい新人研修ができていると実感しました。

「それ、AMPで作りませんか?」--- RichでResponsiveかつPWAなAMPの作り方

  • AMPは3年経って、LP以外にサイト全体をAMPで構築する事例も増えてきた
  • 便利なAMPコンポーネントもたくさんできた
  • AMPは簡単にレスポンシブにでき、一休さんのサイトはとてもいい事例
  • AMPとPWAは相性がいい(文字をひっくり返すとAMP <=> PWAになることからもわかる...w)
  • ただ、URLがGoogleドメインになるのは課題として感じており現在対応中(Signed Exchangeを利用)
  • さらに、AMPでJSが使えるようになる!(WorkerDOMを利用)

ついにAMPでJSが動くそうです(震え声)

サイト全体をAMPで構築し、ほぼ光の速度のサイトを作れるのは夢がありますね!

登壇者によるタイムライン

Web Components のリアル

  • IEを無視すれば今すぐにでもいける(2020年にWin7のサポートが切れるからそこまで待つ説)
  • Custom Elements,Shadow DOM,HTML Template,ES Modulesの組み合わせの技術
  • Custom Elements独自タグを作り、コールバックを定義できる
  • Shadow DOMはDOMをスタイルごと隠す
    • slotで小要素を表示する
  • プロジェクトをまたぐコンポーネントを作る時に便利(ロゴなど)
  • ライブラリに依存しないコンポーネントを作る時に便利(Vue,Reactなど)
  • マイクロフロントエンドの実現
    • コンポーネント内にVueやReactを隠蔽できる
    • ボタンはVueが得意なチームが、カルーセルはReactが得意なチームが作るといった分離ができる
  • Web Componentsは標準の仕様なので使えるなら使ったほうがいい
  • 現実的に作るなら、バニラ,lit-html,lit-element,Vueなどを利用したほうがいい
  • lit-elementが作る時は便利

以前Polymer使ってWebComponentsを作ったことがあるのですが今はlit-elementが主流?ぽいんですね

AMPのコンポーネントもWebComponentsベースらしいです。

今後はJSフレームワークではなく、コンポーネントによるサイト構築が主流になるのかも。

資料

Web プラットフォーム再考 ~PWA のもたらす未来の光と影 ~

  • PWA + ○○ が来ている(Web VRなど)
  • WebなのにPWAのせいで使いづらくなることがある
    • スタンドアローンモードは検索バーが消えるので、検索したい時にブラウザにアプリ切り替えをする必要がある
    • 別のページを開くとき、前のページを上書きして開くので前のページに戻れない
  • PWAで夢を見るな、現実を見ろ

僕も作ったサイトにAdd to homescreen入れたのですが、完全にUXの向上など無視してました・・・。

HTTP の今と未来 ー BBR, HTTP/2, QUIC の基礎から 5G 試験ネットワークでのブラウザベース評価試験まで

  • 5Gが来たが、5Gで何ができるのかが課題になっている
  • この前HTTP/3が出た(HTTP over QUIC)
  • ネットワーク技術の変化を知らないWeb開発者はやばい
  • Softbank X WebDinoJapanが世界初の調査結果を公表
  • Web開発者と共に、5Gネットワークの使い方を創っていきたい
  • 5G IoT Studioという場所を提供している
  • 5GだとHTTP/2のほうが遅い
  • ただまだまだ5Gは調査不足

ネットワーク技術の変化を知らないWeb開発者はやばい

この一文にすべてが込められていました。

資料

スペシャルセッション

LT大会とクイズ大会でした!

1000万以上をAMPにした話

  • WeblioをAMP対応
  • 段階的にAMPにしていった
  • 通常のサイトにAMPコンポーネントを使っている

PureJS

  • Haskellライクな関数型

CSSアンチパターン

  • ビルドプロセスから考えることが必要
  • コンポーネント化されているのにCSSだけグローバルになっていた・・・
  • ビルド後のJSはDRYだがCSSはDRYになってない

Preload,Preconnect

  • とりあえず入れるだけでも負担にならない先読みの仕様
  • APIもフェッチできる

Vivliostyle

  • css組版
  • ブラウザの印刷機能を利用しPDF出力する
  • 利用者が増えてきた

Passive Event

  • Chromeの絵を書く人
  • スクロールにEventを貼ると、スクロールがカクつく
  • heightが変わったりする可能性があるので処理が終わるのを待っているため
  • addEventListenerに{passive: true}を渡すと、処理が終わるまでにスクロールするのでなめらかになる

最後に

以前参加したHTML5 ConferenceはAMPやPWAやWeb Componentsは紹介するセッションが多くありましたが

今回は使ってみてどうだったか、などといった事例のセッションが多かった気がします!

GameWithは、ゲームが大好きで、フロントエンドが大好きな方、新しいWeb技術に興味がある方を大募集中! Wantedly でもよいので是非お気軽にお声がけください!

www.wantedly.com

PHPの現場に「GameWithの現場」というテーマで出演しました #GameWith #TechWith #phpgenba

お久しぶりです。

GameWith Advent Calendar 2018 1 日目担当の @serima です。

去年の今ごろは、GameWith でも Advent Calendar やりたいな…ただエンジニア少なすぎて回すの物理的に無理だ…できない... となっていたのですが、今年はこのような勢いです。

f:id:serimaryo:20181130175941p:plain

エンジニアが増えたこともそうですし、積極的に Advent Calendar を書こうと思ってくれることが、たいへん嬉しいです。

tl;dr

  • PHPの現場という PHP 界隈で有名な Podcast があります
  • 「GameWithの現場」というタイトルで出演させて頂きました
  • みんな聞いてくれよな

php-genba.shin1x1.com

出演までの経緯

PHPの現場のホストである shin1x1 さんのことはかなり前から Twitter でフォローしていました。PHPの現場というPodcastが始まったときに「いつか出たい」なんて言っていたこともありました。

PHP カンファレンス関西 2018

7 月に行われた PHP カンファレンス関西 2018 で GameWith はブースを出展をしていたのですが、なんと shin1x1 さんがふらっと遊びに来てくださいました。 そこで、GameWith のサービス概要やアーキテクチャについて簡単にご紹介させていただきました。実はそのときが初対面でした。

広島での勉強会と台風

そして、9月末に行われた「中国地方DB勉強会 in 広島」というイベントで、shin1x1 さんと僕が登壇者としてそれぞれ Docker と CircleCI について話しました。

Podcast 内でも話してますが、ちょうどそのタイミングで台風 24 号が九州地方に接近しており、イベント後に宿泊すると帰宅できなくなりそうでした。

やむなくイベント終了後はすぐに新幹線に乗って帰ることになったのですが、道中いろいろとお話をしていて、その延長戦として Podcast 収録ということになりました。

ずっと出演したかった Podcast だったので、とても光栄でした。

GameWith を支えるインフラ基盤

Podcast 内で「GameWith Engineer Meetup を行った」と話していますが、その時の資料がこちらです。 Podcast を聴きながら資料を見て頂けるとより理解が深まると思いますので是非ご覧ください。

また、Meetup を行った際にはログミーさんにお越しいただき、記事にしていただきましたのでこちらも合わせてご覧ください。

logmi.jp

収録に利用したマイク

せっかくなので、リーズナブルでそれなりの音質で録音できるというマイクを購入しました。 手元で録音をすると、ささやかにホワイトノイズが乗っていましたが、おそらく編集で簡単に消せるレベルではないかなと感じました。

f:id:serimaryo:20181128135312j:plain
SONY PCV80U ECM-PCV80U

終わりに

GameWith は、ゲームの楽しさをもっと世界に伝えていきたいエンジニアを大募集中です。 Wantedly でもよいので是非お気軽にお声がけください!

www.wantedly.com

GuardDuty(とSecurity Hub)で始めるセキュリティの第一歩 #GameWith #TechWith

初めまして、GameWith のインフラ担当 加我(id:damenaragyouza)です。
GameWith Advent Calendar 2018 の2日目を担当させて頂きます。

ここ最近、外部からの不正なトラフィックによる攻撃が流行しています。
ユーザにサービスを安心して使って頂くために弊社もちゃんとセキュリティを考えていく必要があると感じ、現状の課題と対策を検討しました。

対象となる読者

  • セキュリティ対策を何から始めようか迷ってる方
  • チームにセキュリティの専任がいない状況で開発を行っている方

gamewith.jp におけるセキュリティ上の課題

弊社のゲーム攻略メディアである gamewith.jp は2013年9月にオープンしました。
特定の時間帯でトラフィックが跳ね上がるというサービス上の特性に対し、AWSを活用する事で高トラフィックな環境に対応してきました。

その反面、セキュリティに対しては十分な対策を行えていなかったという事情があり、現時点でどのような課題があるかを調べてみることにしました。

技術的な課題

  • 外部からの不正なトラフィックを検知する仕組みがない
    • ポートスキャンやSSHブルートフォースアタック
    • DDoS攻撃
    • 設定不備によるEC2のインターネット公開状態
  • 内部から外部に対する不正なトラフィックを検知する仕組みがない
    • 外部に向けてのDDoS攻撃やSSHブルートフォースアタック
    • ビットコインのマイニング
  • AWSアカウントに対する不正操作を検知する仕組みがない
    • Credentialの漏洩
    • 各種AWSサービスのAPI不正利用
    • AWS Management Consoleへの不正ログイン

技術的な観点では上記の課題が見えてきました。
これはしっかりと対策をする必要があります。

少し観点を変えてみます。
人的リソースという点でどのような課題があるのかを考えてみました。

組織的な課題

  • インフラの専任は自分のみ
    • そもそもこれまでずっとインフラの専任は不在だった
  • セキュリティの専任はずっと不在である

つまり、インフラとセキュリティに対してガッツリ対策ができる専任のリソースが無かったという状況が続いていました。こういった状況を改善すべく、どのような対策が可能で、より効果的なのかを考えていきます。

理想は「運用に私のリソースをそこまで費やす事なく、いい感じに検知してくれるような都合の良いサービス」です。まぁこんなの無いだろうなぁと思ってたんですがありました。

選ばれたのはAmazon GuardDutyでした

www.slideshare.net

Amazon GuardDutyは AWS環境におけるセキュリティの驚異リスクを検知するAWSマネージドサービス です。
分析する情報として下記の3点が挙げられています。

Amazon GuardDutyの分析ソース

  • VPC Flow Logs
  • AWS CloudTrail Event Logs
  • DNS Logs

上記のソースを機械学習で分析し、脅威(異常)を検知する仕組みとのことです。
Amazon GuardDutyを使用する事で弊社が抱える技術的な課題にアプローチが可能ではと考えました。

VPC Flow Logsからは 外部からの不正なトラフィックを検知内部から外部に対する不正なトラフィックを検知 を、
AWS CloudTrail Event Logsからは AWSアカウントに対する不正操作の検知 を期待します。

導入してみて「やっぱりダメでした」という事もありえるため、30日間のフリートライアルがあるのは個人的に好印象です。

導入

AWS Management ConsoleからAmazon GuardDutyのコンソールに飛び「Get started」をポチるだけです。とても簡単。

f:id:damenaragyouza:20181113155855p:plain
Get started

導入した結果

意図せず外部との通信が可能になっていたSecurity Groupが適用されているEC2インスタンスに対し、外部からポートスキャン(PortProbeUnprotectedPort)が多々行われている事が判明しました。
この結果を踏まえ、Security Groupの全体的な見直しを実施することでGuardDutyが検知した脅威に対する対応ができました。Trusted Advisorを併用するとより効率的です。

f:id:damenaragyouza:20181113170008p:plain
現在はAmazon GuardDutyが検知した脅威をSlackに通知することで運用コストの軽減に成功しています。

[11/29 追記] AWS Security Hubについて

re:Inventで新サービス AWS Security Hub が発表されました!既に東京リージョンでもPreview版が利用可能です。
aws.amazon.com
AWS Security Hubは各セキュリティサービスを一括で管理する事ができるサービスで、文字通りHubとして機能してくれます。
先に導入したAmazon GuardDutyもSecurity Hubから管理する事が可能ですので、今後は全てこちらで管理・操作することになりそうです。

Security Hubの設定ですが、こちらも非常に簡単です。
SecurityHub ConsoleからEnable Security Hubを選択するだけです。
f:id:damenaragyouza:20181129140850p:plain
設定を有効にする際、いくつかのPermissionが必要になるので、内容を確認した上で有効にします。 f:id:damenaragyouza:20181129141149p:plain
StandardsではCIS AWS Foundationsの結果を確認することができます。
設定は簡単で、Enableを選択するだけです。(注意書きを見る限りだと、All resourcesに対してAWS Configを有効にする必要があります)
f:id:damenaragyouza:20181129151926p:plain
Insightsを見ると、様々な観点から問題を報告してくれます。
この観点の中には弊社がこれまで出来ていなかったセキュリティに対する技術的な課題へのアプローチ(Credentialの漏洩やEC2の設定不備/脆弱性)も含まれていました。
GuardDutyと併せて強力にサポートしてくれる事間違いなしです。

f:id:damenaragyouza:20181129142147p:plain
Insightsの一部

コスト

現在トライアルの最中なので最終的なコストはまだ出ていませんがコレくらいです。
この金額は月額のように錯覚しますが日額です。比較的高めではありますが、とても強力かつお手軽なため、トライアル終了後も継続して利用する事にしました。
f:id:damenaragyouza:20181127115730p:plain

終わりに

タイトルに第一歩と書いた通り、Amazon GuardDutyの導入はあくまで「脅威の検知」が目的です。
今後は脅威を未然に防ぐための仕組みづくりや、よりセキュアな運用方法を考えていく必要があります。

このような課題を一緒に考え、一緒に解決していってくれる仲間をGameWithはお待ちしております。

www.wantedly.com

参考資料

Amazon GuardDuty(インテリジェントな脅威検出) | AWS
20180509 AWS Black Belt Online Seminar Amazon GuardDuty
AWS Security Hub | Amazon Web Services (AWS)