概要
Facebook Marketing APIのバージョン2.4から今利用しているレポート集計のreportstatsが使えなくなるため、比較的最近出来たエンドポイントのinsightsを試しに使っています。
調査
reportstatsとinsightsを利用してみると、微妙に取れる件数が異なっている状態なのでどうしたもんかなと悩んでいました。
ところが今週くらいから、FacebookのWebツールである広告マネージャ側でinsightsのエンドポイントを叩き始めているので、使い方を眺めてみると以下のように呼んでいるようでした。
(パラメータのaccess_tokenは省いています。)
https://graph.facebook.com/v2.3/act_0000000000/insights?action_attribution_windows=["28d_click"]&callback=__globalCallbacks.f667930cc4&date_preset=yesterday&default_summary=false&fields=["adgroup_name","campaign_group_name","campaign_group_id","adgroup_id","impressions","social_reach","social_impressions","clicks","social_clicks","ctr","cpc","cost_per_unique_click","spend","total_actions","cost_per_action_type","actions"]&filtering=[{"field":"adgroup.delivery_info","operator":"IN","value":["active","archived","inactive","not_delivering","not_published","pending_review","recently_rejected","rejected","scheduled"]},{"field":"adgroup.impressions","operator":"GREATER_THAN","value":0},{"field":"adgroup.name","operator":"CONTAIN","value":"cont"}]&level=adgroup&limit=5000&locale=ja_JP&method=post&pretty=0&time_increment=1
method=post
を引数にしているので、非同期で処理しているようでした。
結果はcallbackしたところに返ってきているようです。
実際にやってみる。
調査で出ていたパラメータをそのまま使うとGraph API Explorerは死んでしまいました。
limit=5000
はさすがにどぎついので、limit=1
でやってみても返ってきません。
パラメータを真似てバッチスクリプトの方で試そうと思ったのですが、sdkに非同期処理は無いかなと思って見てたらgetInsightsAsyncというのがあったのでこれを試すようにしました。
require_once __DIR__ . '/vendor/autoload.php';
use FacebookAds\Api;
use FacebookAds\Object\AdAccount;
use FacebookAds\Object\Values\InsightsLevels;
use FacebookAds\Object\Values\InsightsPresets;
$app_id = '<YOUR_APP_ID>';
$app_secret = '<YOUR_APP_SECRET>';
$accessToken = '<YOUR_ACCESS_TOKEN>';
$account_id = 'act_<YOUR_ACOUNT_ID>';
try {
Api::init(
$app_id,
$app_secret,
$accessToken
);
$api = Api::instance();
$ad_account = new AdAccount($account_id);
$async_job = $ad_account->getInsightsAsync(
[],
[
'fields' => 'impressions',
'level' => InsightsLevels::ADGROUP,
'date_preset' => InsightsPresets::YESTERDAY,
'limit' => 100,
]);
while (1) {
if ($async_job->read()->isComplete()) {
var_dump($async_job->read()->getData());
insertReportData($async_job->getResult());
$async_job->read()->delete();
break;
}
sleep(10);
}
} catch (Exception $e) {
var_dump($e);
}
function insertReportData($insights)
{
$insights->setUseImplicitFetch(true);
while ($insights->valid()) {
var_dump($insights->current());
$insights->next();
}
}
var_dump($async_job->read()->getData());
で出力される値はこんな感じです。
array(6) {
["id"]=>
string(13) "0000000000000"
["account_id"]=>
string(15) "0000000000"
["time_ref"]=>
int(1438232892)
["async_status"]=>
string(11) "Job Running"
["async_percent_completion"]=>
int(100)
["is_running"]=>
bool(true)
}
$job->read()->isComplete()
でtrueが返ってきているのにもかかわらず、async_statusがJob Running
ってなってるので、その後に値を取ろうとするとError accessing adreport job.
という例外が投げられてしまうという(^_^;)
async_statusがJob Completed
となっていると実際に完了になっている状態なので、sdk側はそこを何とかして欲しいなぁ。
修正してPR投げるといいんだろうか。