こんにちは、タカフです。
アフィリエイトのリンクシェアにおいて、報酬成果を確認するにはリンクシェアの管理画面にログインしないとわかりません。
でも時には速報が知りたいですし、報酬成果が気になって度々管理画面にログインするのも面倒なものです。
他のアフィリエイトASPにはありがちな速報通知がリンクシェアには存在しないですが、リンクシェアにはAPIが公開されているのでそれを使って通知システムを作ってみました。
リンクシェア APIデベロッパーポータルサイトの登録
リンクシェア APIデベロッパーポータルサイトにログイン
リンクシェア APIデベロッパーポータルサイト は以下のURLです。
https://developers.rakutenmarketing.com/subscribe
既にリンクシェアに会員登録している人ならば誰でもログイン出来ます。
ログイン画面は以下のようになっています。
ログインに成功すると以下のようなトップページが表示されます。
アプリケーションの追加
ヘッダーメニューの「アプリケーション」をクリックしてアプリケーションのページに遷移します。
ここでアプリケーションの追加が出来るので、任意の名前を入力して追加ボタンを押下します。
リクエスト制限レベルは一旦「無制限」でいいでしょう。
今回は「成果速報アプリ」としました。コールバックURLは今回は必要ありません。
APIの登録
上記で登録したアプリケーションを成果データが取得出来る「イベント通知レポート」APIに登録します。
リンクシェアのイベント通知レポートAPIとは、
説明:
確定に数日かかる広告主の成果データでも、速報値としてよりリアルタイムに近い間隔でレポートに出力します(速報値の表示は対応している広告主のみ)。
とのことです。リアルタイムに近い感覚で取得出来るらしいです。いいですね。
管理画面メニューの「イベント通知レポート(1.0)」をクリックします。
イベント通知レポートAPIの画面の右側にて先ほど作成したアプリケーションを選択して「登録」ボタンを押下します。
初回アクセストークンの発行
ヘッダーメニューの「登録」のページ遷移します。
先ほど登録したアプリとAPIが表示されるので、「キーを確認する」ボタンを押下して以下のような画面を出します。
登録済みのAPIを利用するにはアクセストークンの取得が必要です。
という文言があるのでここをクリックすると以下の画面が表示されるので、
リンクシェアのユーザー名・パスワードと発行されたサイトIDであるSIDを入力し、「Submit」を押下します。
そうするとアクセストークンを含む以下のようなjsonデータが取得出来ます。
{
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"access_token":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
expires_isからわかるようにこのアクセストークンの有効期限は1時間であり、ずっと使い回すには、refresh_tokenを使ってアクセストークンを更新していく処理が必要になります。
リンクシェアの成果速報データの取得
上記までの操作で初回のアクセストークンは発行出来たのでこれを使ったリンクシェアのAPIを呼び出していきます。
事前準備:HTTPリクエストライブラリにGuzzleを使う
HTTPリクエストには便利なGuzzleライブラリを使っています。
composer経由でインストールします。
$ composer require guzzlehttp/guzzle
成果速報データの取得サンプルコード
結論として以下がサンプルコードとなります。
主な処理内容としては、
①アクセストークンの期限が切れそうになったらリフレッシュトークンを使ってアクセストークンの更新をする
②アクセストークンを使ってリンクシェアAPIで成果速報データを取得する
となっています。
<?php
require_once __DIR__ . "/vendor/autoload.php";
use GuzzleHttp\Client;
define("ACCESS_TOKEN_AUTH_HEADER", "管理画面で取得したアクセストークン取得用認証ヘッダーをここに記述");
try {
// APIで使用するトークンデータの取得
$token_data = get_token_data();
// 成果データの取得
$achievement_data = fetch_latest_achievement_data($token_data);
// TODO: ここで成果データに新規データがあったらメール通知する
var_dump($achievement_data);
}catch(Exception $e){
// 例外処理
var_dump($e);
}
/**
* API呼び出しに使用するトークンデータを取得します。
* 期限によってはトークンの更新処理が走ります。
* @return array|false|mixed|object|string
* @throws Exception
*/
function get_token_data() {
// 一定時間を過ぎていたらリフレッシュトークンで更新
$token_file = __DIR__ . "/storage/linkshare/linkshare_token.json";
if (!file_exists($token_file)) {
throw new Exception("リンクシェアトークンファイルは始めに手動で設置してください");
}
$file_time = filemtime($token_file);
$token_data = json_decode(file_get_contents($token_file), true);
// 期限が秒数でもっているのでファイル時間を合わせて計算する
if (isset($token_data["expires_in"]) && is_numeric($token_data["expires_in"])) {
// トークンの期限の計算
$expire_time = $file_time + $token_data["expires_in"];
// 期限UNIXTIMEの10分前より現在時間が越えていたらトークンをリフレッシュする
if (($expire_time - 600) < time()) {
$token_json = refresh_token_json($token_data);
// 新しいトークンjson文字列を取得出来たのでファイル保存しておく
file_put_contents($token_file, $token_json);
$token_data = json_decode($token_json, true);
}
}
// トークンデータを返却する
return $token_data;
}
/**
* 現在のトークンデータを渡してトークンをリフレッシュします。
* @param $token_data
* @return array|mixed|object
* @throws Exception
*/
function refresh_token_json($token_data) {
$client = new \GuzzleHttp\Client([\GuzzleHttp\RequestOptions::VERIFY => false]);
$response = $client->request('POST', 'https://api.rakutenmarketing.com/token', [
'headers' => [
'Authorization' => "Basic " . ACCESS_TOKEN_AUTH_HEADER,
],
'form_params' => [
'grant_type' => 'refresh_token',
'refresh_token' => $token_data["refresh_token"],
'scope' => 'PRODUCTION'
],
]);
if ($response->getStatusCode() != 200) {
throw new Exception("トークンの更新に失敗しました");
}
return $response->getBody()->getContents();
}
function fetch_latest_achievement_data($token_data) {
$client = new \GuzzleHttp\Client([\GuzzleHttp\RequestOptions::VERIFY => false]);
// 直近の 30 レコード分を取得して精査する
$response = $client->request('GET', 'https://api.rakutenmarketing.com/events/1.0/transactions', [
'headers' => [
'Authorization' => "Bearer " . $token_data["access_token"],
],
'query' => [
'limit' => '30'
],
]);
if ($response->getStatusCode() != 200) {
throw new Exception("トランザクション取得に失敗しました");
}
$contents = $response->getBody()->getContents();
return json_decode($contents, true);
}
APIに日付情報を付与して特定日時のデータを取得することも出来るのですが、タイムラグがあるかもわからないので、とりあえず毎回30件だけ最新データを取得するようにしてます。
そして僕の場合はさらにデータベースに保存しておいて、もし新しいレコードがある場合はそれをメールで流す、というような処理にしています。
まとめ
おかげでかなりリアルタイムに近い感覚でリンクシェアの成果速報データを取得出来るようになりました。
管理画面を確認する頻度も減ったので他の作業に集中出来るようになりとても良かったです。
もしリンクシェアを使っている方でこのような成果通知機能を取り入れたい方がいらっしゃいましたら、無料で限定5名の方に僕がこの機能を導入致します。
こんな機能欲しい人はレアだと思うので試験的にゆるく募集してみたいと思います(笑)
ご希望の方はTwitterのDMでも下さいませ。
現場からは以上です。