Pythonで書かれたLINE Ads APIのサンプルコードをGAS(JavaScript)に翻訳したい
解決したいこと
LINE広告APIドキュメントにてPythonで書かれているサンプルコードを、GAS(JavaScript)で書き直して使いたい
開発の背景
- LINE広告のパフォーマンスレポートをスプレッドシートに自動で書き出したい
- 他プラットフォーム(GoogleやYahoo!)の広告データ抽出も行っていることもあり、GASで書きたい
発生しているエラー
{"errors":[{"reason":"Unauthorized","message":"JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted."}]}
「JWT署名がローカルで計算された署名と一致しません。 JWTが有効である確証がないため、信頼すべきではありません」とのこと。
今動かしているソースコード
ドキュメントのPythonのコードを見て、自力でGASに翻訳してみたものが以下です。
サンプルコードは GET /v3/groups/{groupId}/children
を使っていたので、 GET /v3/adaccounts/{adaccountId}/campaigns
に変えています。
function importAdsReport() {
const today = new Date();
const access_key = "xxxxxxxxxxxx";
const secretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const accountId = "xxxxxxxxxxx";
const header = `{"alg": "HS256", "kid": "${access_key}", "typ": "text/plain"}`;
const hex_digest = sha256("");
const content_type = "";
const payload_date = Utilities.formatDate(today, 'GMT', 'yyyyMMdd');
const canonical_url = `/api/v3/adaccounts/${accountId}/campaigns`;
const payload = `${hex_digest}\n${content_type}\n${payload_date}\n${canonical_url}`;
const inputValue = `${base64(header)}.${base64(payload)}`;
const signature = hmacSha256(inputValue, secretKey);
const calculatedSignature = `${inputValue}.${signature}`;
const request_headers = {
"Date": Utilities.formatDate(today, 'GMT', 'E, dd MMM yyyy HH:mm:ss z'),
"Authorization": `Bearer ${calculatedSignature}`
}
const options = {
"method": "GET",
"headers": request_headers,
"muteHttpExceptions": true
};
const response = UrlFetchApp.fetch('https://ads.line.me' + canonical_url, options);
}
/**
* base64エンコード
* @param {string} input - エンコードしたい文字列
* @return {string} - base64エンコードされた文字列
*/
function base64(input) {
return Utilities.base64Encode(input, Utilities.Charset.UTF_8)
}
/**
* HMAC SHA 256でハッシュ化
* @param {string} text - ハッシュ化する文字列
* @param {string} key - ハッシュ化するシークレットキー
* @return {string} - ハッシュ値
*/
function hmacSha256(text, key) {
const rowHash = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, text, key);
let txtHash = '';
for (i = 0; i < rowHash.length; i++) {
let hashVal = rowHash[i];
if (hashVal < 0) {
hashVal += 256;
}
if (hashVal.toString(16).length == 1) {
txtHash += '0';
}
txtHash += hashVal.toString(16);
}
return txtHash;
};
/**
* SHA 256でハッシュ化
* @param {string} input - ハッシュ化する文字列
* @return {string} - ハッシュ値
*/
function sha256(input) {
const rawHash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, input, Utilities.Charset.UTF_8);
let txtHash = '';
for (i = 0; i < rawHash.length; i++) {
let hashVal = rawHash[i];
if (hashVal < 0) {
hashVal += 256;
}
if (hashVal.toString(16).length == 1) {
txtHash += '0';
}
txtHash += hashVal.toString(16);
}
return txtHash
}
エラーの原因っぽいところ
signature
が間違っているんだろうと思っています。
HTTPリクエストに渡す calculatedSignature
は inputValue
と signature
から成っているのですが、 inputValue
はPythonで生成したものと一致していました。
Pythonのサンプルコードで
signature = hmac.new(
secret_key.encode(),
signing_input.encode(),
hashlib.sha256
).digest()
のように書かれているところを、GASで
const signature = hmacSha256(inputValue, secretKey);
としているのですが、このhmacSha256()
がよくないのかなと...。
今試していること
「要するにHS256形式での電子署名生成をGAS(JavaScript)でできればいいのでは」と思い、それらしき記事を見てみたりしているのですが、結局同じエラーが返ってきてしまっています…。
誤っている箇所がお分かりになる方いらっしゃいましたら、ご指摘いただけるととてもありがたいです…。
0