質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

解決済

Pythonで書かれたLINE Ads APIのサンプルコードをGAS(JavaScript)に翻訳したい

退会済みユーザー

退会済みユーザー

総合スコア0

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1回答

0リアクション

0クリップ

516閲覧

投稿2022/09/12 13:27

解決したいこと

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 に変えています。

JavaScript

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リクエストに渡す calculatedSignatureinputValuesignatureから成っているのですが、 inputValue はPythonで生成したものと一致していました。

Pythonのサンプルコードで

Python

signature = hmac.new( secret_key.encode(), signing_input.encode(), hashlib.sha256 ).digest()

のように書かれているところを、GASで

JavaScript

const signature = hmacSha256(inputValue, secretKey);

としているのですが、このhmacSha256()がよくないのかなと...。

今試していること

「要するにHS256形式での電子署名生成をGAS(JavaScript)でできればいいのでは」と思い、それらしき記事を見てみたりしているのですが、結局同じエラーが返ってきてしまっています…。

誤っている箇所がお分かりになる方いらっしゃいましたら、ご指摘いただけるととてもありがたいです…。

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。