回答編集履歴

7

 

2022/09/13 13:49

投稿

退会済みユーザー
test CHANGED
@@ -106,7 +106,7 @@
106
106
 
107
107
  inputValue は 前2つ(jws_header, jws_payload)をピリオドで連結した文字列に一致しています。
108
108
 
109
- したがって calculatedSignature の後ろ部分に連結している `signature` は、pythonサンプルコードの `encoded_signature` に該当することになるので、
109
+ したがって calculatedSignature の後ろ部分に連結している `signature` は、pythonサンプルコードの `encoded_signature` [=上記 (2) の行] に該当することになるので、
110
110
  上記のように、
111
111
  ```js
112
112
  function hmacSha256(text, key) {

6

 

2022/09/13 12:48

投稿

退会済みユーザー
test CHANGED
@@ -115,4 +115,6 @@
115
115
  };
116
116
  ```
117
117
  というコードにすればよいのではないでしょうか。
118
+  
119
+ つまり元の GAS コードでは、HMAC_SHA_256 で得られたバイト列を Hex 文字列に変えていますが、そうではなくて、得られたバイト列を BASE64 エンコードするのが正解かと思います。
118
120
 

5

 

2022/09/13 12:46

投稿

退会済みユーザー
test CHANGED
@@ -104,7 +104,9 @@
104
104
  ```
105
105
  に該当しています。
106
106
 
107
+ inputValue は 前2つ(jws_header, jws_payload)をピリオドで連結した文字列に一致しています。
108
+
107
- したがって calculatedSignature の後ろ部分に連結している `signature` は、pythonサンプルコードの `encoded_signature` に該当するので、
109
+ したがって calculatedSignature の後ろ部分に連結している `signature` は、pythonサンプルコードの `encoded_signature` に該当することになるので、
108
110
  上記のように、
109
111
  ```js
110
112
  function hmacSha256(text, key) {
@@ -112,5 +114,5 @@
112
114
  return Utilities.base64Encode(rowHash);
113
115
  };
114
116
  ```
115
- というコードにすればよいのではないかと思いました
117
+ というコードにすればよいのではないでしょうか。
116
118
 

4

 

2022/09/13 12:43

投稿

退会済みユーザー
test CHANGED
@@ -86,7 +86,7 @@
86
86
 
87
87
  + hmacSha256 関数 → バイト列をBASE64エンコードしたものを返すように修正。
88
88
 
89
- こちらは、とのpython コードでの結果を比較してみると
89
+ こちらは、途中途中で GAS のデバッグ出力、サンプル python コードでのデバッグ出力とを比較して検証してました。
90
90
  ```python
91
91
  signature = hmac.new(
92
92
  secret_key.encode(),

3

 

2022/09/13 12:40

投稿

退会済みユーザー
test CHANGED
@@ -104,7 +104,7 @@
104
104
  ```
105
105
  に該当しています。
106
106
 
107
- したがって calculatedSignature の後ろ部分に連結している `signature` は、pythonサンプルコードの encoded_signature に該当するので、
107
+ したがって calculatedSignature の後ろ部分に連結している `signature` は、pythonサンプルコードの `encoded_signature` に該当するので、
108
108
  上記のように、
109
109
  ```js
110
110
  function hmacSha256(text, key) {

2

 

2022/09/13 12:39

投稿

退会済みユーザー
test CHANGED
@@ -6,7 +6,7 @@
6
6
  const secretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
7
7
  const accountId = "xxxxxxxxxxx";
8
8
 
9
- const header = `{"alg":"HS256", "kid":"${access_key}","typ":"text/plain"}`;
9
+ const header = `{"alg":"HS256","kid":"${access_key}","typ":"text/plain"}`;
10
10
 
11
11
  const hex_digest = sha256("");
12
12
  const content_type = "";
@@ -77,7 +77,11 @@
77
77
  ---
78
78
 
79
79
  # 変えたところ
80
- + const header の半角スペースを削除(こちらは関係ないかもしれません。ただドキュメントのサンプルは、JSON文字列の半角スペースが削除された文字列をBASE64エンコードしたものになっていました。)
80
+ + header の半角スペースを削除(こちらは関係ないかもしれません。ただドキュメントのサンプルは、JSON文字列の半角スペースが削除された文字列をBASE64エンコードしたものになっていました。)
81
+ ```diff
82
+ - const header = `{"alg": "HS256", "kid": "${access_key}", "typ": "text/plain"}`;
83
+ + const header = `{"alg":"HS256","kid":"${access_key}","typ":"text/plain"}`;
84
+ ```
81
85
   
82
86
 
83
87
  + hmacSha256 関数 → バイト列をBASE64エンコードしたものを返すように修正。

1

修正

2022/09/13 12:38

投稿

退会済みユーザー
test CHANGED
@@ -1,7 +1,112 @@
1
+ 下記ではいかがでしょうか。
1
2
  ```js
3
+ function importAdsReport() {
4
+ const today = new Date();
5
+ const access_key = "xxxxxxxxxxxx";
6
+ const secretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
7
+ const accountId = "xxxxxxxxxxx";
8
+
9
+ const header = `{"alg":"HS256", "kid":"${access_key}","typ":"text/plain"}`;
10
+
11
+ const hex_digest = sha256("");
12
+ const content_type = "";
13
+ const payload_date = Utilities.formatDate(today, 'GMT', 'yyyyMMdd');
14
+ const canonical_url = `/api/v3/adaccounts/${accountId}/campaigns`;
15
+ const payload = `${hex_digest}\n${content_type}\n${payload_date}\n${canonical_url}`;
16
+
17
+ const inputValue = `${base64(header)}.${base64(payload)}`;
2
- const signature = Utilities.computeHmacSignature(
18
+ const signature = hmacSha256(inputValue, secretKey);
19
+ const calculatedSignature = `${inputValue}.${signature}`;
20
+
21
+ const request_headers = {
22
+ "Date": Utilities.formatDate(today, 'GMT', 'E, dd MMM yyyy HH:mm:ss z'),
23
+ "Authorization": `Bearer ${calculatedSignature}`
24
+ }
25
+
26
+ const options = {
27
+ "method": "GET",
28
+ "headers": request_headers,
29
+ "muteHttpExceptions": true
30
+ };
31
+
32
+ const response = UrlFetchApp.fetch('https://ads.line.me' + canonical_url, options);
33
+ }
34
+
35
+ /**
36
+ * base64エンコード
37
+ * @param {string} input - エンコードしたい文字列
38
+ * @return {string} - base64エンコードされた文字列
39
+ */
40
+ function base64(input) {
41
+ return Utilities.base64Encode(input, Utilities.Charset.UTF_8)
42
+ }
43
+
44
+ /**
45
+ * HMAC SHA 256でハッシュ化
46
+ * @param {string} text - ハッシュ化する文字列
47
+ * @param {string} key - ハッシュ化するシークレットキー
48
+ * @return {string} - ハッシュ値
49
+ */
50
+ function hmacSha256(text, key) {
3
- Utilities.MacAlgorithm.HMAC_SHA_256,
51
+ const rowHash = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, text, key);
4
- inputValue,
5
- Utilities.newBlob(secretKey).getBytes());
52
+ return Utilities.base64Encode(rowHash);
53
+ };
54
+
55
+ /**
56
+ * SHA 256でハッシュ化
57
+ * @param {string} input - ハッシュ化する文字列
58
+ * @return {string} - ハッシュ値
59
+ */
60
+ function sha256(input) {
61
+ const rawHash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, input, Utilities.Charset.UTF_8);
62
+ let txtHash = '';
63
+ for (i = 0; i < rawHash.length; i++) {
64
+ let hashVal = rawHash[i];
65
+ if (hashVal < 0) {
66
+ hashVal += 256;
67
+ }
68
+ if (hashVal.toString(16).length == 1) {
69
+ txtHash += '0';
70
+ }
71
+ txtHash += hashVal.toString(16);
72
+ }
73
+ return txtHash
74
+ }
6
75
  ```
76
+
77
+ ---
78
+
79
+ # 変えたところ
80
+ + const header の半角スペースを削除(こちらは関係ないかもしれません。ただドキュメントのサンプルは、JSON文字列の半角スペースが削除された文字列をBASE64エンコードしたものになっていました。)
81
+  
82
+
83
+ + hmacSha256 関数 → バイト列をBASE64エンコードしたものを返すように修正。
84
+
85
+ こちらは、もとのpython コードでの結果を比較してみると
86
+ ```python
87
+ signature = hmac.new(
88
+ secret_key.encode(),
89
+ signing_input.encode(),
90
+ hashlib.sha256
91
+ ).digest() # ---(1)
92
+ encoded_signature = encode_with_base64(signature) # ---(2)
93
+ token = "%s.%s.%s" % (jws_header, jws_payload, encoded_signature) # ---(3)
94
+
95
+ ```
96
+ (1) は `Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, text, key);` の結果に一致しています。
97
+ また(3)は、質問者さんのGASコードを最初から読んでいくと、
98
+ ```js
99
+ const calculatedSignature = `${inputValue}.${signature}`;
100
+ ```
101
+ に該当しています。
102
+
103
+ したがって calculatedSignature の後ろ部分に連結している `signature` は、pythonサンプルコードの encoded_signature に該当するので、
104
+ 上記のように、
105
+ ```js
106
+ function hmacSha256(text, key) {
107
+ const rowHash = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, text, key);
108
+ return Utilities.base64Encode(rowHash);
109
+ };
110
+ ```
7
- した場合はいかがでょうか
111
+ いうコードにすればよいのでいかと思いま
112
+