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

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

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

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

Q&A

解決済

1回答

620閲覧

【初心者】GAS Notionデータベース→スプレッドシートへの転記エラーが解決できない

euqina_sk

総合スコア11

Google Apps Script

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

0グッド

1クリップ

投稿2024/02/13 01:46

実現したいこと

Notionのデータベースの内容をスプレッドシートに定期的に転記をしたいと考えております。

データベース 各プロパティ
1列目:名前
2列目:応募日(日付)
3列目:ステータス(ステータス)
4列目:職種(セレクト)
5列目:次選考日(日付)

転記先のスプレッドシートは特定の1つのシートを想定しています。

発生している問題・分からないこと

エラーメッセージが発生し、先に進めておりません。

エラーメッセージ

error

1TypeError: Cannot read properties of undefined (reading 'length') 2syncNotionToGoogleSheet @ 20240213質問前.gs:17

該当のソースコード

function syncNotionToGoogleSheet() { // Notionからデータを取得するための関数を呼び出す var notionData = fetchNotionData(); // GoogleスプレッドシートのファイルIDとシート名 var ss = SpreadsheetApp.openById('【スプレッドシートID】'); var sheet = ss.getSheetByName('【特定のシート名】'); // シートをクリアする sheet.clear(); // ヘッダー行を設定 var headers = ['名前', '応募日','ステータス','職種','次選考日']; sheet.appendRow(headers); // Notionデータが存在しない場合の処理 if (notionData.length == 0) { Logger.log('Notionからデータが見つかりませんでした。'); return; } // Notionデータをスプレッドシートに転記 for (var i = 0; i < notionData.length; i++) { var row = []; row.push(notionData[i].properties.Name.title[0].text.content); row.push(notionData[i].properties['応募日'].date.start); row.push(notionData[i].properties['ステータス'].status); row.push(notionData[i].properties['職種'].select); row.push(notionData[i].properties['次選考日'].date.start); sheet.appendRow(row); } } // Notionからデータを取得する関数 function fetchNotionData() { var databaseId = "【NotionデータベースID】"; var url = 'https://api.notion.com/v1/databases/' + databaseId + '/query'; var token = '【secret_から始まるNotionAPI TOKEN】'; var options = { 'method': 'get', 'headers': { 'Authorization': 'Bearer ' + token, 'Notion-Version': '2022-06-28', "Content-Type": "application/json", }, 'muteHttpExceptions': true // このオプションを設定してサーバーからのレスポンスを取得 }; var response = UrlFetchApp.fetch(url, options); var data = JSON.parse(response.getContentText()); Logger.log(options); if (response.getResponseCode() != 200) { Logger.log('APIリクエストが失敗しました。レスポンスコード: ' + response.getResponseCode()); Logger.log('レスポンス内容: ' + response.getContentText()); } }

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

当方初心者のため、googleで検索したものを基本的にコピペ改変、それでも解決しなかったので、chatGPTで出力されたものを一部改変して用いております。
いずれも同様のエラーで先に進めない状況です。

エラー出現時にもchatGPTに問い合わせてみたのですが、提示されたような「APIエンドポイントの確認」「APIトークンの有効化に関する確認」「token情報の更新・再取得」なども行ったのですが、エラーが解消しません。
本件類似案件についてterateil でNotionで検索したのですが、同様の質問が見られませんでした。

なお、54行目の

Logger.log('APIリクエストが失敗しました。レスポンスコード:

1

では「APIリクエストが失敗しました。レスポンスコード: 400」と出力されています。

補足

特になし

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YellowGreen

2024/02/13 03:43

実際に試せないので、コメントで質問だけ。 function fetchNotionData()が取得したデータを戻していないようで、 // Notionデータが存在しない場合の処理 if (notionData.length == 0) { のところで、notionData自体がundefinedのままなので、 データの存否確認すらできずにエラーになっていると思われます。 * if (response.getResponseCode() != 200) { Logger.log('APIリクエストが失敗しました。レスポンスコード: ' + response.getResponseCode()); Logger.log('レスポンス内容: ' + response.getContentText()); } } ↓ if (response.getResponseCode() != 200) { Logger.log('APIリクエストが失敗しました。レスポンスコード: ' + response.getResponseCode()); Logger.log('レスポンス内容: ' + response.getContentText()); } return data; // この行を追加 } のように修正してみて、 エラーの内容がどう変わるかをお教えください。
euqina_sk

2024/02/13 06:53 編集

YellowGreen 様 ご質問ありがとうございます。 頂いた通り修正したところ、エラーは出ず、下記の内容が出力されました。 情報 [ 'A子', 'B郎', 'C江', 'D夫', 'E子' ] 情報 {headers={Notion-Version=2022-06-28, Authorization=Bearer 【secret_から始まるNotionAPI TOKEN】, Content-Type=application/json}, muteHttpExceptions=true, method=get} 情報 APIリクエストが失敗しました。レスポンスコード: 400 情報 レスポンス内容: {"object":"error","status":400,"code":"invalid_request_url","message":"Invalid request URL."} ※最初の情報に列記されている「 'A子', 'B郎', 'C江', 'D夫', 'E子' 」はNotionデータベース1列目に記載されている名前です。
YellowGreen

2024/02/13 05:19

var databaseId = "【NotionデータベースID】"; のIDがあっているか再確認をされていますか。 IDがxxxxxxxxxxxのとき、 var databaseId = "xxxxxxxxxxx"; とすべきところを var databaseId = "【xxxxxxxxxxx】"; としていたりはしませんか。 なお、 上のコメントの二つ目の情報のデータは、 上のコメントを編集して削除しておいていただいた方がよいかと思います。
euqina_sk

2024/02/13 05:28

ご返答ありがとうございます。 また、情報データにつきまして、分かりづらいように一部改変いたしました。ご指摘ありがとうございます。 スクリプト内に記載しているdatabaseIDですが、 データベースをフルページで表示した時のURL https://www.notion.so/●●●●●/▲▲▲▲▲▲?v=■■■■■ のうち、▲▲▲▲▲▲部分のみを抜き出しております。 (●●●●●は弊社全体のワークスペース名が入ります) 表記上分かりやすく【】を入れておりますが、実際のスクリプトには記載せず、半角英数のみで記載しております。
YellowGreen

2024/02/13 06:06 編集

あとは、 "Content-Type": "application/json", の行をコメントにしても変わりませんンか。 秘匿した方がいいと申し上げたのは、 1つ目ではなく、2つ目の内容(headers={}の内容)です。
YellowGreen

2024/02/13 07:41 編集

次のような修正ではいかがでしょうか。 var options = { 'method': 'post', // この行を修正 get → post 'headers': { 'Authorization': 'Bearer ' + token, 'Notion-Version': '2022-06-28', "Content-Type": "application/json", // ここはそのまま }, 'muteHttpExceptions': true // このオプションを設定してサーバーからのレスポンスを取得 };
euqina_sk

2024/02/13 07:00

>秘匿した方がいいと申し上げたのは、 >1つ目ではなく、2つ目の内容(headers={}の内容)です。 大変失礼いたしました、編集・修正いたしました。 >あとは、 >"Content-Type": "application/json", >の行をコメントにしても変わりませんンか。 教えて下さった通りコメントアウトにしても、1つ前と同様にエラーは出ず、同様の出力内容になります。 最後にいただいた修正を反映したところ、エラーは出ずに下記の情報が出力されました。 情報 [ 'A子', 'B郎', 'C江', 'D夫', 'E子' ] 情報 {method=post, muteHttpExceptions=true, headers={Authorization=Bearer 【secret_から始まるNotionAPI TOKEN】, Notion-Version=2022-06-28, Content-Type=application/json}} スプレッドシートの方には、プロパティ名のみ出力されているものの、2行目以降のデータベースの内容自体は出力されておりません。
YellowGreen

2024/02/13 08:01

notionDataは取得できていて、 その内容を解析してシートに記入する部分がおかしいと思います。 notionData.resultsが各行のデータになります。
YellowGreen

2024/02/13 08:33

var notionData = fetchNotionData(); ↓ var notionData = fetchNotionData().results; * row.push(notionData[i].properties.Name.title[0].text.content); row.push(notionData[i].properties['応募日'].date.start); row.push(notionData[i].properties['ステータス'].status); row.push(notionData[i].properties['職種'].select); row.push(notionData[i].properties['次選考日'].date.start); ↓ row.push(notionData[i].properties['名前'].title[0].plain_text); row.push(notionData[i].properties['応募日'].date.start); row.push(notionData[i].properties['ステータス'].rich_text[0].plain_text); row.push(notionData[i].properties['職種'].rich_text[0].plain_text); row.push(notionData[i].properties['次選考日'].date.start); としてみるとどうなりますか? 名前の名称は漢字でよろしかったですか。
YellowGreen

2024/02/13 10:55

もしかするとステータスの取得に失敗するかもしれませんので、 汎用的なプロパティの値取得の関数を作成してみました。 回答としてお示しします。
euqina_sk

2024/02/14 00:43

ありがとうございます。 いただいた通り var notionData = fetchNotionData(); ↓ var notionData = fetchNotionData().results; への修正と、その後のプロパティまわりを row.push(notionData[i].properties['名前'].title[0].plain_text); row.push(notionData[i].properties['応募日'].date.start); row.push(notionData[i].properties['ステータス'].rich_text[0].plain_text); row.push(notionData[i].properties['職種'].rich_text[0].plain_text); row.push(notionData[i].properties['次選考日'].date.start); ↓ row.push(notionData[i].properties['名前'].title[0].plain_text); row.push(notionData[i].properties['応募日'].date.start); row.push(notionData[i].properties['ステータス'].status.name); row.push(notionData[i].properties['職種'].select.name); row.push(notionData[i].properties['次選考日'].date.start); に変更した上で実行したところ、想定した通りのデータを取得することができました! ありがとうございました!
guest

回答1

0

ベストアンサー

Notionを利用したことがなかったので的外れな質問をしてしまいましたが、
例えば、次のようにすることができるのではないでしょうか。

まず、
ある程度汎用的なプロパティ取得の関数を用意します。

JavaScript

1// プロパティから値を取得する関数 2function getDataValue(item) { 3 switch (item.type) { 4 case 'title': return item.title[0] ? item.title[0].plain_text : null; 5 case 'rich_text': return item.rich_text[0] ? item.rich_text[0].plain_text : null; 6 case 'number': return item.number; 7 case 'email': return item.email; 8 case 'date': return item.date ? item.date.start : null; 9 case 'status': return item.status ? item.status.name : null; 10 case 'select': return item.select ? item.select.name : null; 11 case 'checkbox': return item.checkbox; 12 case 'url' : return item.url; 13 } 14}

その上で、
メインの関数を次のようにして値を取得してシートに記入してはいかがでしょうか。

JavaScript

1function syncNotionToGoogleSheet() { 2 // Notionからデータを取得するための関数を呼び出す 3 const notionData = fetchNotionData().results; 4 5 // GoogleスプレッドシートのファイルIDとシート名 6 const ss = SpreadsheetApp.openById('【スプレッドシートID】'); 7 const sheet = ss.getSheetByName('【特定のシート名】'); 8 9 // シートをクリアする 10 sheet.clear(); 11 12 // ヘッダー行を設定 13 const headers = ['名前', '応募日', 'ステータス', '職種', '次選考日']; 14 sheet.appendRow(headers); 15 16 // Notionデータが存在しない場合の処理 17 if (notionData.length == 0) { 18 Logger.log('Notionからデータが見つかりませんでした。'); 19 return; 20 } 21 22 // Notionデータをスプレッドシートに転記 23 for (let i = 0; i < notionData.length; i++) { 24 const row = []; 25 const data = notionData[i].properties; 26 for (const item of headers) { 27 row.push(getDataValue(data[item])); 28 } 29 sheet.appendRow(row); 30 } 31}

なお、
fetchNotionData関数については、
コメントで質問したとおりgetpostに修正し、
最後の } の前の行にreturn dataを挿入し

Javascript

1 'method': 'post',

Javascript

1 Logger.log('レスポンス内容: ' + response.getContentText()); 2 } 3 return data; 4}

のようにします。

投稿2024/02/13 10:52

編集2024/02/13 23:15
YellowGreen

総合スコア772

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YellowGreen

2024/02/13 10:54

Notionのデータベースの見出しとスクリプトの見出しの文字列が一致していることが前提になります。
euqina_sk

2024/02/14 00:43

またこちらも投稿ありがとうございました。 頂いた通り修正したところ、こちらもエラーなく成功しました。 今後さまざまなデータベースに応用するにあたり、こちらの方が編集が間違いなくできそうだったため、こちらをベストアンサーとさせていただきます。 Notion環境をお持ちでないにもかかわらず、丁寧にご対応下さり、本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.41%

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

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

質問する

関連した質問