アニメ版イングレスを見た

Netflixで全話配信されていたので一気に最終話まで見た.

ネタバレにならない程度の感想などを書いていく.

Ingress: The Animation | Netflix

結論

思っていた以上に良かったし,安心して人に勧められるような内容だった.

Ingressプレイヤーから見て

Ingressの世界観を保ったまま,新しくストーリーが始まったという感じの内容.

既存のプレイヤーは5話からが特に面白いと感じるかもしれない.

Ingressのストーリーの流れを知っていると楽しめる部分も散りばめられており,

本来のストーリーが気になる人は公式の小説やSNS上に上がっているストーリーの日本語訳サイトである「LYCAEUM NET INGRESS」を見るといいかもしれない.

イングレス ザ・ナイアンティック・プロジェクト

イングレス ザ・ナイアンティック・プロジェクト

ingress.lycaeum.net

とはいえこれらを知らなくても全く問題はないストーリーにはなっている.

プレイしたことのない人は用語解説がある3話まで見ると雰囲気がわかりやすいと思う.

気になった点

Ingressプレイヤーなら知っているとあるキャラが登場する場面があるが,その部分に関して説明不足だったように思う.

もう少し本来のストーリーを知っているとわかる内容なのかもしれないが少なくとも自分はわからなかった.

アニメとして

アクション要素だけでもかなり見ごたえあると思った.

センシティブと呼ばれるいわゆる能力者が多く登場し戦いを繰り広げるので,意外とアニメにピッタリなんだなと思った.

映像も当然綺麗な青や緑が映えていてとても良かった.

おわりに

少しずつ見ていくつもりが先が気になり一気に見てしまった.

そういえば,次期バージョンでIngress Primeは来月にローンチされる予定ということで,アニメも面白くなってきたタイミングに合わさるのかもしれない.

楽しみになってきた.

www.netflix.com

Lambdaで動くupdate_nameをGoで書いてみた

Go言語の練習ついでに作ってみた.リポジトリは以下.

GitHub - cohalz/update_name: update_name by Go Lambda

仕様

  • CloudWatch Eventから毎分のスケジュールを設定する.
  • 変更ルールとAPIキー情報を入力として渡してLambdaを実行する.
    • トリガーのタイプ(前方一致か後方一致か),トリガーとなるワード,変更後の名前にトリガーを含むか,リプライの内容(%sの部分に変更後の名前が埋め込まれる)を設定できる.
    • 1つのLambdaに対しAPIキーの違うイベントを複数Lambda渡すだけでマルチユーザでの利用が可能.
  • 入力例
{
    "rules": [
        {
            "triggerType": "suffix",
            "triggerword": "はる"
        },
        {
            "triggerType": "prefix",
            "triggerWord": "@cohalz update_name ",
            "omitTriggerWord": true,
            "replyFormat": "%sになりました"
        }
    ],
    "credential": {
        "accessToken": "",
        "accessTokenSecret": "",
        "consumerKey": "",
        "consumerSecret": ""
    }

ここからは実装についての話をする.

UserStream無しでupdate_nameを実現するために

8月にUserStreamが終了し,リアルタイムで反応をすることが出来なくなった.

そのため,UserStreamでないAPIを使って出来る限り早い反応を返すようにしなければならない.

Twitter APIのRate Limitは15分に15回までの制限が掛けられている.

参考: Rate Limiting — Twitter Developers

つまりは1分に1回のペースで動かすということになる.

幸いにも,CloudWatch Eventはトリガーとして毎分が選べるため採用することにした.

取得するツイートが被らないようにするために

毎分取得するとして前回取得したツイートと被らないようにする必要がある.

被ってしまうとTLの流速が遅いときなどは毎回反応してしまうという事が起きてしまう.

それを防ぐ方法がパラメータで用意されている.

GET statuses/user_timeline — Twitter Developers

パラメータにsince_idとしてツイートのidを追加することで,そのツイートid以降のツイートのみを取得することができる.

そのため,取得するツイート数の最大値であるcountパラメータを200にしつつ,since_idを設定することにより最大限TLが重複なく拾えるようになる.

当然,1分に200以上のツイートが流れている場合は反応できない可能性があるので注意が必要.

Lambdaから前回の状態を取得する

では,状態を持たないLambdaでどうやってsince_idを保存・取得するかということについてはLambdaの環境変数に書き込むという方法を取った.

外部のシステムに依存しないKVSとして簡単に利用することができるが,いくつか制限があるため,利用する際は気をつけないといけない. 例としては,

  • キーの名前や保存容量に気を付ける
    • 特に容量は合計で4KBまでなので大量にデータを保存しておく事はできない.
    • 公式のドキュメントに制限が書いてある. docs.aws.amazon.com
  • IAMに権限の追加が必要
    • lambda:UpdateFunctionConfiguration の権限が追加で必要になる.
  • 環境変数をアップデートする際,自分で定義した環境変数のみをすべて渡す必要がある
    • Lambdaの環境変数はシステム側で用意された環境変数が含まれている.
    • 自分で定義した環境変数のみを渡すために,自分で定義する環境変数はprefixを決めておくと扱いやすくなる.
  • ライブラリの名前空間が衝突する
    • 今回は"github.com/aws/aws-lambda-go/lambda""github.com/aws/aws-sdk-go/service/lambda"が同じlambdaという名前になるためリネームが必要.

ここまで説明した環境変数に書き込む部分の実装例がこちら.

import (
    "log"
    "os"
    "strconv"
    "strings"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    lambda_sdk "github.com/aws/aws-sdk-go/service/lambda"
)

func setSinceIDToEnv(functionName string, screenName string, sinceID int64) {
    sinceIDStr := strconv.FormatInt(sinceID, 10)

    sess := session.Must(session.NewSession())

    svc := lambda_sdk.New(
        sess,
        aws.NewConfig().WithRegion("ap-northeast-1"),
    )

    m := make(map[string]*string)

    envs := os.Environ()

    // 自分で定義した環境変数のみをkey-value形式のmapに保存
    for _, env := range envs {
        if !strings.HasPrefix(env, "sinceID_") {
            continue
        }
        envKeyValue := strings.SplitN(env, "=", 2)
        m[envKeyValue[0]] = &envKeyValue[1]
    }

    m["sinceID_"+screenName] = &sinceIDStr

    env := &lambda_sdk.Environment{
        Variables: m,
    }

    input := &lambda_sdk.UpdateFunctionConfigurationInput{
        FunctionName: &functionName,
        Environment:  env,
    }

    _, err := svc.UpdateFunctionConfiguration(input)

    if err != nil {
        log.Fatal(err)
    }

}

名前変更部分について

update_nameの要である名前変更についてもすぐに実装ができたわけではなかった.

ChimeraCoder/anacondaというライブラリを使うことにしたのだけれど,名前を変更するエンドポイントに対する関数が実装されていなかった.

もう少し探してみると,Pull Requestはあるが余計な機能追加によりコンフリクトが起きていて放置されていたという状態だということがわかった.

そのため,その機能のみに絞って自分がPRを送ってみることにした.

github.com

送ったあとに気がついたのだが,このライブラリはしばらくメンテされていない状態だった.

他のPRも放置されていてマージされる気配もないので,今はforkした自分のリポジトリから使うようにしている.

[追記] マージされていた.

その他

ローカルで実行確認をするために,SAMでテンプレートを書いた.

ローカルではfunctionNameがtestという名前になる他に,環境変数の保存ができない気がしたためにローカルでは実行していない.

SAMのデプロイ・テストにはMakefileを用意するのがやはり便利だと感じた.

余談

前回update_nameを作ったのは三年半ほど前のことで,何故か今あまり書いていないRubyだったのもありメンテナンスできていなかった.

今回の機会にそれがGoとLambdaでメンテナンスしやすい形に変更できたので良かった.

Goでなにか書いてみるのは初めてだったけど,VS Codeの拡張もあり意外とスムーズに実装できた.

今後おもちゃを作ってみるときはGoで書いてみようと思う.

github.com

h抜きと晒し

昨日はブログを書いていないのにもかかわらず,アクセス数が普段の4倍くらいあった.

原因として最初に考えたのは,前に書いた記事で言及したインデックス登録により,検索流入の増加が起きたことである.

core.cohalz.co

とはいえいくら何でも急にこんなに検索されるものなのかと不思議に思い,Google Analyticsを見ることにした.

するとitest.5ch.net*1とnozomi.2ch.sc*2からのアクセスを確認することができた.

それぞれアンチスレとなんJのスレらしく,特に良いことも書いてないだろうと思ってどう言われているのかまでは確認してない.

そんな話を他の人にしていたら,「今の2ちゃんってh抜きしてないのか」と言われた.確かに別のスレとか見てもh抜きはあまり見ないように思う.

今回アンチスレやなんJからのアクセスがわかったのはリファラを見て気づいたのだが,これはもしh抜きをしていたら気がつくことはできなかった. 今までh抜きは自動リンクやクロールの問題に対する方法と認識していたので,リファラを消すためにh抜きをするという効果がよくわかった.

h抜きの文化は現在だいぶ衰えていそうだけれど,何かを晒す際相手にバレない用で使うとき便利なのは違いない.

Google Search Consoleを見ていたら,インデックス登録されていないことに気がついた

前にこんな記事を書いてみて,Google Search Consoleを見るようになった. core.cohalz.co

ここ最近は,ブログを書いてはGoogle Search Consoleの検索の変化を見るみたいなことが習慣になっていた.

そんな中,結構気合を入れて書いた記事があった.

core.cohalz.co

この記事で紹介している動画は既に30万再生以上されていて,かなり話題になっている.

ところがいつになってもブログの流入は増えないし,検索結果も変わらないのに気がついた.

原因は不明だけれど,10/4を最後にクロールが止まっているらしい.10/4の記事がTwitter貼り付けばかりだったのが良くないのか,その前の設定変更なのかははっきりしない.

記事を書いていけば直るだろうか.引き続き調査していく.

追記

古い方のGoogle Search Consoleからクロールリクエストをすると検索結果にでるようになった.

f:id:cohalz:20181011085027p:plain

とはいえ,新しいConsoleで対象のページになったようには見えないので根本的な解決ではなさそう.

ヨメミのドッキリ動画はVTuber界に対するアンチテーゼとなるのか

10月6日に投稿された動画で衝撃を受けた.

【ドッキリ】500万円ヨメミさんに投げ銭したらガチ泣き【神展開】 - YouTube www.youtube.com

動画の内容を簡単に紹介すると,「ドッキリの生放送が人気になり高額な投げ銭を貰ったらどういう反応をするのか?」と言ったものである.

ヨメミについて紹介

本題へ入る前に,ヨメミの紹介を軽くしておく.

  • ゲームのプレイ動画などを中心に投稿しているVTuberで,チャンネル登録者は現時点で26万人以上いるなどかなりの人気を誇っている.

  • 企業に所属しているわけではないが,エイレーンというYouTuberによってプロデュース*1されている.

www.youtube.com

というのが今回ドッキリを受けた動画のVTuberである.

生放送と投げ銭の文化が定着したVTuber業界

VTuberは現在かなりの人数いるが,生放送を一度もしたことが無いVTuberというのは現在非常に珍しい例*2になっている.

また,投げ銭の文化も根付いており,YouTube Liveを始めとして毎日多くの投げ銭がどこかで行われている.

そのため生放送や投げ銭の文化を題材としたドッキリというのは,他のVTuberが真似しようと思ってもまず真似できるものではない.

そんな状態から今回のドッキリ動画は始まった.

ヨメミは多くの動画を投稿しているが,生放送は「放送事故が怖い」という理由*3で一度も行われていなかった.

そんな中で,ヨメミが嘘の企画に騙され,高額の投げ銭を貰ったのも,そもそも初めての生放送自体がドッキリという非常に手の混んだものになっている.

VTuberとは別の企画者が動画に参加できるアドバンテージ

動画のに関しておさらいすると,内容はプロデューサーであるエイレーンが偽の生放送と投げ銭システムを用意して,何も知らないヨメミがずっと騙されるというものである.

そもそも,VTuberの動画に別の企画者が参加できるのは大きなアドバンテージとなっている.

もちろん,他のVTuberであっても運営している企業はあるのだが,VTuber業界はあまり運営のことを見せない風潮なのもあり,企画者が出てこない.そのためこういったドッキリ動画を作るのは非常に難しい.

近い例を探すと.LIVEのばあちゃるが似た例ではあり,アイドル部の動画・生放送の企画をし本人が参加することもある.ヘイトを一気に引き受ける役目をしているのも似ているところがある.

とはいえ,ここまで攻めた企画を立てることもなかった.

プロデューサーであるエイレーンは2014年からYouTuberを始めているが,過激で高クオリティな動画によって人気を集めていたという歴史がある.

そのため,このような攻めた内容を企画し実行できることに対しても,大きなアドバンテージとなっている.

文化に対するアンチテーゼ?

編集の手間から生放送が行われることが多いが,ヨメミはエイレーンはずっと動画のみを作り続けていた.

今回は生放送の文化を取り上げたものだったが,内容は動画としての魅力が短く詰まったものになっていた.

毎回の場面が濃い動画になっていて,ストーリー展開もしっかりしているため,一部をスキップすることがなく全部を見てしまう.

反対に生放送は時間も長く見るのが大変という話もあり,中身も比較的薄くなってしまう傾向がある.

そうすると視聴者は流し見のような状態になる可能性もある.

今回は無かったが,普段ヨメミの動画では動画内に隠されたマークを探し,報告をすることで先着でグッズが貰えるキャンペーンを行っていることもある.

このキャンペーンにより動画が投稿されたらすぐに見てくれる人も増え,動画の隅々まで見てくれるようになるという利点がある.

このように動画ならではの仕掛けも用意できるのも利点の一つである.

また投げ銭に関しても,YouTubeの投げ銭は3割が手数料としてYouTubeに持っていかれる上に見返りもないという問題もある.

投げ銭の代わりにエイレーンはPatreonというサイトでファンディングを募っている.

www.patreon.com

Patreonのようなファンディングサイトでは手数料も少ない上に見返りを用意することができるため,そちらを使って欲しいという話もあるかもしれない.

生放送や投げ銭文化に対するアンチテーゼとして今回の企画が立ったのかはわからないが,結果として非常に面白い動画になったのは間違いない.

これからヨメミも生放送を始めるのかはわからないが,面白くて短い動画を投稿していくスタイルは継続してほしいと思っている.

おわりに

今まで見てきたVTuberの動画の中でも,相当に攻めていて面白い動画だと思った.

ヨメミは活動の初期から応援をしていたのもあり,ドッキリは心を痛むものがあったけれど,面白くて嬉しい気持ちにもなった.

こういった動画はまた出してほしいと思うようにもなった.

ちなみにヨメミは8月に3D化をしたばかりで,色んなことにチャレンジしている最中である.

もし興味を持ったら動画を視聴してはいかがだろうか.

*1:エイレーンは他にもミライアカリや夏実萌恵などをプロデュースしている

*2:登録者10万人以上で見ても他には鳩羽つぐと夏実萌恵しかいない

*3:今まで生放送を行わなかった理由は今回の動画まで不明であった

自分の文章

はてなインターン2018の成果エントリが出た.この記事はインターン生が書いた.

この記事はなんとブクマ数が300を突破した.

コンテナデプロイ基盤の検証 - Hatena Developer Blog

ただ,エントリの最初と最後で自分の名前が出ていることからも予想できる通り,この文章を校閲・編集をしたのは自分だった.

自分が良いと思った文章が外で評価されるのは,自分が書いた文章が評価されるのと同じように嬉しいものがあった.

公開される前にも他のエンジニアや広報の人に見てもらっていたのだが,ほとんど指摘点が無かったというのも嬉しいことだった.

ただこのままではダメだとも同時に感じた.

自分は普段は校閲や編集をするわけでは無かったし,それこそ初めての経験のようなものだった.

そんな中どうやったかというと,単に「良いと思えるか」で判断することで行うしかなかった.

完全に「こういう風にすると良いだろう」というのは自身の経験か何かから引き出されていて,それは非常に感覚的なものになってしまっている. そして感覚的であるとともにその感覚の原典が分からないので統一感が保証されない.

保証されないので文が長くなると書くのが本当に難しくなる.

ある程度しっかりした文章では,質を保証しようとするためとにかく時間がかかる.

あまり長い記事を書けていなかったのはそのためで,その記事を書くために取れる時間が十分になかったことが理由になる.

そのため感覚ではない文章にしたルールが欲しくなっている.ルールが有ることで,

  • 項目ごとに文章をチェックすることで,チェックが終わった際には品質が保証されることになる
  • ルールが明文化されたことで,試行錯誤の時間が減り早くに文章を完成させることができる

文章のルールとしてはlintなどのツールを試してみようとしている.どこまでlintでできるのかという調査をして,もし機械的なチェックが難しいものがあればチェックリストを作って運用する形になるだろう.日本語文章に関する本も必要になってくるのかもしれない.

そういえば昨年末にこんな事を自分で言っていた.

このツイートの「めるさん」というのはこの記事などを書いているWindymeltさんのことである.

blog.3qe.us

この記事以外にも説得力のある文章が多く,自分の文章との違いを考えてみると肉付けが本当にうまいのだと思う.

さっきの話に戻ると,文章のルールを決めるということはゴールではなくて,その結果ストーリーや肉付けに集中できるようになるのが目的である.

文章を書く速度を上げて,文章量を増やし,ルールによって後から品質を保証していくスタイルでこれから少しずつ書くようにしていきたい.

そしてブログの頻度の向上や品質の高い技術記事を出していくことが今年の目標になるだろう.