Edited at

facebook/facebook-php-ads-sdkの非同期処理『getInsightsAsync』を試してみる

More than 3 years have passed since last update.


概要

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というのがあったのでこれを試すようにしました。


test_job.php

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投げるといいんだろうか。