クラウドワークス エンジニアブログ

日本最大級のクラウドソーシング「クラウドワークス」の開発の裏側をお届けするエンジニアブログ

「アプリだけのオリジナルコンテンツ」をSNSで拡散してもらうために。

こんにちは、クラウドワークスで公式Androidアプリの開発などをやっている @YusukeIwaki です。 クラウドワークスアプリでは、今年の5月に「仕事を探す」機能アップデートをした際に、お仕事特集 というアプリオリジナル機能をリリースしました。

f:id:YusukeIwaki:20160729152317p:plain

お仕事特集機能は、「電車の中で仕事をなんとなく見る」という人のために、クラウドワークス事務局側が温かみのある職人作業(誇張w)で仕事を選んで定期的に掲載しているものなのですが、 今回は、このお仕事特集機能を

といった要望 をどう実現したのか、をお話します。

 

SNSシェアするための要件は?

そもそもTwitterFacebookで拡散させたい、とはどういう機能があれば実現できるでしょう?

答えは簡単で、「URLがあればいい」のです。 逆に、URL以外のメタデータ(画像やdescriptionなど)は、用意しても共有先のアプリで使われないことが多く、「URLがあればいい」が必要十分条件なのです。 (参考→ Y.A.M の 雑記帳: Facebookとそれ以外でACTION_SENDで渡すテキストを変える

では、アプリ独自のコンテンツにURLを紐付けるにはどうすればいいのでしょうか?

ここが今回の記事の本題で、 ディープリンク という仕組みをうまく使います。

ディープリンク

ディープリンクには、大きく分けて2とおりの実装方針があります。

  • アプリが独自スキームを定義して、独自スキームを含むURLをシェアする
  • 特定のhttp(s)のURLへのアクセスをアプリで横取りする

もし仮にほぼ100%のユーザがアプリでリンクを開くことを期待できる場面であれば、前者の方針のように、独自スキーム (androidapp://xxxxx...、crowdworks://xxxx... ) などを定義し、そのリンクをシェアすることで、アプリに誘導をすることができます。 ところが、今回は「SNSでシェアする」という想定のため、PCを使っているユーザも一定数いるのでこの方法は使えません。PCユーザがリンクを踏んだら「androidapp://xxx」や「crowdworks://xxx」というリンクが解釈できずエラーになってしまいます。

f:id:YusukeIwaki:20160729173716p:plain

 

そこで、今回のお仕事特集のシェアでは、後者の方針のように、特定のhttp(s) URLをアプリで横取りする方式を採用しました。

f:id:YusukeIwaki:20160729175019p:plain

「お仕事特集の詳細を見ようとしたらクラウドワークスのアプリが立ち上がってきた!」というモデルにするため、

  • お仕事特集詳細のURLを定義する
  • お仕事特集詳細のURLをPCで見た際の代替動作を定義する
  • アプリ側でお仕事特集詳細のURLを横取りする処理を実装する

の3つの対応をおこないました。

このなかで、2つ目の「お仕事特集詳細のURLをPCで見た際の代替動作を定義する」と3つ目の「アプリ側でお仕事特集詳細のURLを横取りする」という部分について、少し説明を加えます。    

お仕事特集詳細のURLをPCで見た際の代替動作を定義

冒頭で述べた通り、Webサービス本体側にはお仕事特集というコンテンツは存在しません。 だからといって、たとえば「ポケモンGO特集」というリンク文字列をクリックした人がクラウドワークスのトップページに飛ばされたら「あれ??」ってなってしまいますよね。

そこで、今回の実装では、「PCでクリックした時に見せる既存コンテンツ」を管理画面で設定できるようにしました。  

f:id:YusukeIwaki:20160801114438p:plain

これにより、たとえば

  • ポケモンGO特集」→ ポケモンGOの検索結果(新着順)のページ
  • 狙い目ライティング特集 → ライティングカテゴリの仕事一覧ページ

のように、それぞれの特集に対して、違和感のない既存コンテンツを指定でき、PCでリンクを踏んだ際にそれらのコンテンツを見せるようにすることで「あれ??」ってならないような配慮ができます。

 

アプリ側でお仕事特集詳細のURLを横取りする

アプリ側は、単純に https://crowdworks.jp/public/feature_articles/:id を拾うよう、AndroidManifestでインテントフィルタを追加しています。

labelを独自に指定したくなる時が来るかもしれないので、既存のアクティビティに直接インテントフィルタを追加するのではなく、aliasを作成してそこにインテントフィルタを指定すると良いでしょう。

        <activity-alias
            android:name=".PublicFeatureArticleActivity"
            android:targetActivity=".EntrypointActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="https" android:host="@string/hostname" android:pathPrefix="/public/feature_articles" />
            </intent-filter>
        </activity-alias>

エイリアス先のEntrypointActivityでは、URLから特集idを抽出し、当該のお仕事特集にジャンプさせる処理を追加しています。

og:imageを正しく設定するために

おおむね上記の方法でうまくいったのですが、1つだけ問題がありました。

もともと、PCで見た際の代替コンテンツの表示を、単純なHTTP 302リダイレクトで実装していたため、リダイレクト先(仕事検索結果ページなど)のOGPが取得されてしまい、

f:id:YusukeIwaki:20160729182020p:plain

facebookで実際にお仕事特集をシェアしてみると、イマイチな感じになってしまいました。 これでは、「ポケモン特集だ」というのがパット見わからず、バズってもらえません。

そこで、ロボットによるアクセスの場合には、302リダイレクトではなく、HTTP 200でダミーページを返し、そのなかでJavaScriptでリダイレクトをかけるように変更をしました。

修正前
f:id:YusukeIwaki:20160729185208p:plain
修正後
f:id:YusukeIwaki:20160729185852p:plain

ダミーページに指定するog:imageとog:descriptionは、以下のように管理画面で設定できるようにしました。

f:id:YusukeIwaki:20160801180702p:plain

 

 

こうすることで、FacebookからのOGP取得は、お仕事特集の指定画像を参照するようになり、その結果・・・

f:id:YusukeIwaki:20160729202526p:plain

このように、特集をシェアしても違和感がなくなりました。めでたしめでたし。  

 

今後の展開

今回は、「コンテンツをシェアしてもらうために」という思いで、ディープリンクの対応を進めました。

実のところ、対応を進めているときは、マーケティング的にはメリットはあるけど、技術/設計的にメリットは有るのかなー・・・」と複雑化に対する懸念をもちつつやっていました。しかし、対応を進めていくうちに

f:id:YusukeIwaki:20160801135537p:plain

などなど、プッシュとの設計共通化など、新たに設計改善ができそうだなー、というポイントを発見できました。  

クラウドワークスでは、アプリは少人数で開発をしているため、複雑化しちゃったあとにはしっかりリファクタリングし、設計をシンプルに保つ、というのを常に心がけています。 直近は、プッシュ通知とディープリンクの共通設計などを行い、次なるマーケティング施策を打ちやすい土台がためを実施することになるでしょう…。  

 

We're Hiring!

クラウドソーシングのクラウドワークス では、アプリを使って「クラウドワークスをより身近に」するエンジニアを大募集中です!

アプリなら是非やってみたい!APIならガシガシ書けるよ!というかた、お気軽に「話を聞きに行きたい」をポチッとどうぞ!

www.wantedly.com

© 2016 CrowdWorks, Inc., All rights reserved.