Facebook「Business Mapping API」の使い方と「app-scoped ID」について

9.10
2014

mapping12
こんにちは。
Appleの発表がありましたね。まあ、あまり興味が無いので見てないんですけど。

さて、以前「Facebookビジネスマネージャー」というものの使い方を簡単にまとめました。
その際にも少し触れましたが「Business Mapping API」というものがあります。
今回はその辺のお話です。

API v2.0から、ユーザーIDの仕様が変わっている(app-scoped ID)

まずはじめに、API v2.0からアプリ経由で取得できるユーザーIDの仕様が変わっています。

Facebookプラットフォームアップグレードガイド(→日本語訳が出来てました。)
https://developers.facebook.com/docs/apps/upgrading#upgrading_v2_0_user_ids

docsが日本語訳されてました。「1. アプリ専用のユーザーID」というのが、「app-scoped ID」のことです。

mapping4

「app-scoped ID」とはなんなのか?

「app-scoped ID」の概念を簡単に説明すると、下記の図のようになります。

mapping2
なお、実際には「User ID」も「app-scoped ID」もどちらも単なる数字の羅列です。
↑の図のようにわかりやすい規則性はありません。

つまり、今まではどのアプリからもユーザー一意のIDが取得できていましたが、API v2.0以降はアプリごとに一意なIDとして、新たに「app-scoped ID」というものが導入されました。
ユーザー個人を特定できる情報は極力アプリには落とさない、ってことですかね。

「app-scoped ID」に切り替わったのはいつから?

mapping3
「app-scoped ID」は、API v2.0のタイミングで仕様が変わりました。v2.0以降を利用するアプリが対象になります。
すなわち、2014/4/30以降に作成したアプリもしくは、それ以前に作成したアプリでもAPI v2.0以降に移行を行ったものは対象になります。

2014/4/30以降に新たに作成したアプリについては、ユーザーのIDは全て「app-scoped ID」になっています。
API v2.0以降に移行を行ったアプリについては、移行以前にログインしたことがあるユーザーのIDは「User ID」ままとなり、移行後に初めてログインするユーザーのIDは「app-scoped ID」になります。
そのため、移行後にユーザーがログインすると既存のIDが書き換わる、というような事態は発生しません。

「app-scoped ID」に切り替わったことにより複数のアプリをまたいでユーザーの識別ができなくなった

このIDの仕様の変更ですが、通常の利用用途(アプリ単体としての動作完結)であれば何ら問題はありません。

ただし、ユーザーのIDを複数のアプリ間で連携しているようなケースでは、問題が発生します。
複数のアプリが全てAPI v1.0を利用している場合は良いのですが、一部もしくはすべてがv2.0以降を利用している場合、前述のようにユーザーのIDはアプリごとに変動してしまうので、連携が不可能になります。

mapping5

複数のアプリ間で同じユーザーを特定したり、1つのプログラムの中で機能や用途によってアプリを複数使っているようなケースでは今までこのUser IDをキーにユーザーのデータを相互参照していたと思いますが、それが出来なくなってしまうのです。

別のフィールドでユーザーの識別ができないか

では他に何かユーザー一意の情報はないでしょうか?
可能性としてあり得るのは、名前もしくはユーザーネーム(※)です。

※ユーザーネーム・・・http://www.facebook.com/[username] の形式でURLとして設定できる任意の名前です。他のユーザーと重複できません。

ただ、「名前」は他のユーザーと重複OKなので、一意の情報にはなりません。
ユーザーネームは一意ですが、なんとAPI v2.0からはこの情報を取得するAPIも廃止されています。

2014年4月30日 – APIバージョン2.0
https://developers.facebook.com/docs/apps/changelog#v2_0_graph_api

mapping6

つまり、どちらも使えないのです。あとはemailぐらいですかね、使えそうなの。

ここまでの流れを見れば、Facebookが「ユーザーを特定する」ようなアクションに対して規制を強めているのがわかると思います。
いずれそもそもポリシーで規制される可能性もあるかもしれませんね。

app-scoped ID を使って、ユーザーを一意に特定する方法(Business Mapping API)

さて、前段でapp-scoped IDというのが何なのかは説明しました。
ではこれを使ってアプリを横断してユーザーを特定する方法は完全に無いのでしょうか。

実は、これまたv2.0から新しく実装された「Business Mapping API」というものを利用することで、それが可能になります。
ただし、このAPIを使った場合でも、ユーザーのUser IDを取得することは不可能です。

はじめに、Facebookビジネスマネージャーを設定する

まずはじめに、ビジネスマネージャーの設定を行い、ビジネスアカウント(→このネーミングが正しいか微妙ですけど)の作成をする必要があります。

ビジネスマネージャーの設定については、以前まとめていますので今回は省きます。

mapping7

Facebookビジネスマネージャーの設定方法まとめ
http://snowadays.jp/2014/07/2889

なお、作成には「親」となるFacebookページが必要ですが、ここで設定したページはその後更新の際に若干不便になります。
(↑の記事を書いた当時と比べ、今ではほとんど通常と変わらなくはなりましたが。)
安易に企業の公式ページとかを設定するのは避けた方が良いと思います。(正しい使い方としては「公式ページ」を設定するんでしょうけど。)

「Business Mapping API」を使うために

まず、↑で設定したビジネスマネージャーの中で、連携させたいアプリを全て登録します。
仮にあなたが全てのFacebookアプリの管理人であれば、この作業は即時完了しますが、管理人が別にいる場合は承認待ちの状態になります。

mapping1
こうすることで、登録した複数のアプリはビジネスアカウントに紐づいてグルーピングされます。
この登録が完了したアプリのうち、API v2.0以降のものについては「Business Mapping API」が使えるようになります。

「Business Mapping API」の使い方

ビジネスアカウントに登録した複数のアプリですが、普通にユーザーのIDを「/me?fields=id」でたたいても、一意のIDではなくアプリごとに異なるIDが返ってきてしまいます。
ところが、「Business Mapping API」を使うことが出来るアプリについては「/me/ids_for_business」という形式で下記のようなデータが取得可能です。

{
  "data": [
    {
      "id": "10153949089790582",  /* App Scoped User IDです */
      "app": {
        "name": "Business's App 1",   /* アプリの表示名です */
        "namespace": "business_app_1",   /* アプリのネームスペースです */
        "id": "647733625268125"  /* アプリのIDです */
      }
    }, 
    {
      "id": "605665581", 
      "app": {
        "name": "Business's App 2", 
        "namespace": "business_app_2", 
        "id": "370612223054807"
      }
    }, 
    {
      "id": "10154053730190582", 
      "app": {
        "name": "Business's App 3", 
        "namespace": "business_app_3", 
        "id": "194890427204075"
      }
    }
  ]
}

上記の例では、「Business’s App 1~3」の3つのアプリは同じビジネスアカウントに登録してあることになります。

このデータを受け取ることで、デベロッパーでは「App1のID:10153949089790582さんと、App2のID:605665581さんと、App3のID:10154053730190582さんは同一人物」ということがわかります。

見ればわかる通り、User ID(v1.0までで取得できていた、真のUser ID)はどこにも入っていませんのでご注意を。

結構使いにくいですね・・・。
というのも、仮に個別にアプリを立てていくようなケースがあるとすれば、↑でいうところの「App 1~3」がどんどん増えていくことになります。
となると、例えばこれらのデータをDBにため込むとした場合に、カラムがどんどん増えていくようなイメージです。
特定の二つ、とか三つ、のアプリだけ記録すればいいなら問題ないんですけどね・・・。

実際にデモアプリで「Business Mapping API」を使ってみます

幸いなことに手元に複数のパターンのアプリがあります。
(アプリ名は気にしないでください)

  1. Tuesday ※API v1.0 →認証ページ
  2. Sunday ※API v2.0 →認証ページ
  3. Monday ※API v2.0 →認証ページ
  4. Wednesday ※API v2.1 →認証ページ

で、これらのアプリを、ビジネスマネージャーに設定してみました。
期待値としては、v1.0であるTuesday以外の3つのアプリについてはどれにログインしても他の2つのアプリにおけるそのユーザーのIDが取れるはずです。

★説明不要かと思いますが、当然デモを試すユーザーが3つのアプリ全てにログインしたことが無ければそうなりません。はじめてデモにアクセスする場合は、事前に3つのデモページでユーザーの認証通してからでないと、Business Mapping APIのテストはできません。

API v1.0のアプリを使って「/me?fields=id」を叩いてみる

デモページはこちら

mapping8

API v1.0で「/me?fields=id」を叩いていますので、このID(100*********125)が私の「User ID」です。(真のUser ID、real User ID)
なお、デモページではBusiness Mapping APIの情報も表示するようになってますが、v1.0では使えないのでError表記となります。

API v2.0のアプリを使って「/me?fields=id」と「/me/ids_for_business」(Business Mapping API)を叩いてみる

デモページはこちら

mapping9

さて、続いてはAPI v2.0で「/me?fields=id」と「/me/ids_for_business」を叩いてみました。
v2.0ということで、このUser ID(752*********630)は「App Scoped User ID」です。

また、その下にBusiness Mapping APIの結果も並べています。
各アプリそれぞれで、User IDが異なっているのがわかりますね。
さて、このうち一番下のSundayのアプリのUser IDは、先ほど確認した真のUser ID(100*********125)と同じです。
何故でしょうか?

過去にログインしたことがあるAPI v2.0のアプリを使って「/me?fields=id」と「/me/ids_for_business」(Business Mapping API)を叩いてみる

デモページはこちら

mapping10

このアプリはv2.0にもかかわらず、User IDが真のUser IDのままです。

実は、過去にログインしたことがある場合、そのユーザーのIDは「App Scoped User ID」にはならずに、以前の「User ID」のまま返されます。
これは、v2.0移行後にそのユーザーが再ログインしていようとしていまいと、関係ありません。
全てのアプリにおいて、2014/4/30よりも以前にログインしたユーザーのIDは、「User ID」のままです。
「App Scoped User ID = User ID」といった方が正しいですかね。

★なお、この結果は私がたまたまSundayのアプリに4/30以前にログインしていたから出ただけなので、初めてログインする人は単純に全アプリで「App Scoped User ID」(別々のID)が返ると思います。あしからず。

API v2.1のアプリを使って「/me?fields=id」と「/me/ids_for_business」(Business Mapping API)を叩いてみる

デモページはこちら

mapping11

おまけです。念のためv2.1でも試してみました。
まあ、v2.0と結果は変わりません。

ステージング用のアプリとかどうするの?

さて、余談ですが。
開発用のアプリはともかく、本番アプリとは別にステージングのアプリを運用しているようなケースでは、本番とステージングのアプリでユーザーのIDが変わってしまう(アプリが違うから)と困りますよね。

そんな時、「Test Apps」を使えば同じID(同じApp Scoped User ID)が使えるようです。
この辺の話は、また改めてまとめます。