bbizinets.life
n8nでGoogle DriveのCSV更新が壊れる原因と解決法【HTTP Request + Drive API】
実践ログ

n8nでGoogle DriveのCSV更新が壊れる原因と解決法【HTTP Request + Drive API】

Google DriveのCSV更新で起きたこと

n8nでGoogle DriveのCSVファイルを更新しようとしたとき、うまくいきましたか?

私はn8nのワークフロー最終工程で、キーワード管理用CSVに1行追記する処理を実装していました。Google Driveノードでファイルをダウンロードし、Codeノードで既存の内容に新しい行を追加し、再びGoogle Driveノードでアップロードする。構造としてはシンプルなはずでした。

実行しました。ノードは「成功」と表示されました。エラーは出ませんでした。

ファイルを開いてみると、1行目が文字化けしていました。既存の9行分のデータが消え、今回追記しようとした1行だけが残っていました。

これが2回続きました。コードを修正して再実行しても、同じ壊れ方をしました。「エラーは出ないのにデータが壊れる」という状態で、何が起きているのかまったく分からず、正直かなり困りました。

なぜデータが壊れるのか:binaryDataModeの仕組み

原因を特定するために、n8nの設定を確認してみました。

n8nにはbinaryDataModeという設定があります。デフォルトのmemoryモードではバイナリデータをメモリ上で管理しますが、filesystemモードに設定されている場合、バイナリデータはメモリではなくディスク上のファイルとして管理されます。

私の環境はセルフホスト版n8nで、binaryDataMode: filesystemが設定されていました。

このモードで何が起きるかというと:

  • Google Driveノードがファイルをダウンロードするとき、バイナリデータはディスク上の一時ファイルに保存される
  • Codeノードからそのバイナリを取得しようとしても、正しくアクセスできないケースがある
  • 取得が失敗してもエラーにはならず、空データとして処理が進む
  • 結果として「空のデータ + 追記1行」だけが書き込まれ、既存データが消える

これが「エラーは出ないのにデータが壊れる」の正体でした。

構造分析:

  • 数値:2回の実行でデータが破損。既存9行が消滅
  • 構造分析:binaryDataMode=filesystemのため、Codeノードがバイナリを正しく読み取れず空として処理された
  • 判断基準binaryDataMode: filesystemの環境でバイナリ処理を伴うGoogle Driveノードを使う場合 → HTTP Requestへの切り替えを検討する

Google DriveノードをHTTP Requestに切り替える判断

Google DriveノードをやめてHTTP Requestに切り替えると決断したのは、2回目の破損が起きた直後です。

判断の決め手になったのは「検証手段がない」という事実でした。Google Driveノードはバイナリの扱いが内部に隠れており、「正しく読み取れているか」を確認する方法がありません。一方、HTTP Requestなら何を送って何を受け取っているかが明確で、問題の切り分けができます。

比較した選択肢は3つでした。

  1. コードをさらに修正する:同じGoogle Driveノードを使い続ける。検証手段がないため根本解決にならない
  2. 別のn8nノードに変える:同じ抽象化の上にある選択。問題の本質は変わらない
  3. HTTP Request + Drive APIに切り替える:内部仕様が見えるようになる。検証可能になる

3を選びました。

切り替えを決断する判断基準:

  • エラーなく壊れるケースが2回以上続いた → ノードではなくアプローチを変える
  • 「なぜ壊れるか」が分からないまま修正を繰り返している → 根本原因の特定を先にする
  • 検証手段がない → 生APIへ切り替える

HTTP Request + Drive APIでCSVを更新する手順

実際にどのように切り替えたかを整理します。

1. CSVを取得する(GETリクエスト)

HTTP Requestノードの設定:

  • Method:GET
  • URL:https://www.googleapis.com/drive/v3/files/{fileId}?alt=media
  • Authentication:Predefined Credential Type → Google Drive OAuth2 API

alt=mediaを付けることが重要です。これを省略するとファイルのメタ情報だけが返ってきて、中身が取得できません。

取得結果は$json.dataにテキストとして入ります。

2. CSVに追記する(Codeノード)

const prev = $('05_finalize').first().json;
const doneLine = prev.done_line + ' | ' + prev.moved_at;

const existing = $('keyword_done.csv 取得').first().json.data
  .replace(/\r\n/g, '\n')
  .trimEnd();

const newContent = existing + '\n' + doneLine;

return [{ json: { updated_csv: newContent } }];

replace(/\r\n/g, '\n')で改行コードを統一しておくことで、文字化けを防げます。

3. CSVを更新する(PATCHリクエスト)

HTTP Requestノードの設定:

  • Method:PATCH
  • URL:https://www.googleapis.com/upload/drive/v3/files/{fileId}?uploadType=media
  • Authentication:Predefined Credential Type → Google Drive OAuth2 API
  • Body Content Type:Raw
  • Content Type:text/plain
  • Body:{{ $json.updated_csv }}

PATCHが正しいメソッドです。PUTではファイルを置き換えるのではなく更新情報が届かないことがあります。

ハマりやすいポイントと対処法

実際に試してみると、いくつかつまずきやすい箇所があります。

exportエンドポイントは使えない

/drive/v3/files/{fileId}/exportはGoogle DocsやSheetsのエクスポート専用です。通常のCSVファイル(Driveにアップロードしたファイル)には使えず、403エラーが返ってきます。

/drive/v3/files/{fileId}?alt=mediaが正しいエンドポイントです。

PATCHのURLにuploadTypeが必要

更新時のURLは/upload/drive/v3/files/{fileId}?uploadType=mediaです。/upload/?uploadType=mediaの両方が必要で、どちらか一方でも欠けると400エラーになります。

Content-Typeにtext/plainを指定する

text/csvでも動きますが、text/plainの方が安定していました。ヘッダーにContent-Type: text/plainを明示的に指定してください。

判断基準:

  • 403エラーが出た → exportエンドポイントを使っていないか確認する
  • 400エラーが出た → URLに/upload/?uploadType=mediaが両方あるか確認する
  • 更新後にデータが化ける → Content-Typeを明示的に指定する

この後どうなったか

HTTP Requestへの切り替え後、CSV更新は1回で成功しました。

取得時に$json.dataでテキストが正しく取得できていること、更新後にファイルを開いて内容が正しく書き込まれていることを確認しました。Google Driveノードのときに起きていた「エラーなく壊れる」問題は完全に解消されました。

n8nのワークフロー全体(インタビュー生成→本文生成→監査→リライト→WP投稿→CSV追記→Slack通知)はこの修正を経て一通り完成しています。現時点では記事1本のテスト投稿を完了した段階で、本格稼働はこれからです。

まとめ

n8nでGoogle DriveのCSV更新が壊れる場合、原因はbinaryDataMode: filesystemの設定にあることが多いです。Google Driveノードのバイナリ処理がエラーなく失敗するため、発見が遅れやすい問題です。

解決策はHTTP RequestノードでDrive APIを直接叩くことです。

  • 取得:GET https://www.googleapis.com/drive/v3/files/{fileId}?alt=media
  • 更新:PATCH https://www.googleapis.com/upload/drive/v3/files/{fileId}?uploadType=media
  • 認証:Google Drive OAuth2 API(n8nのPredefined Credential Type)

今日できる一歩として、まず取得ノードだけをHTTP Requestに切り替えて、$json.dataにCSVの内容が正しく入るかを確認してみてください。それが確認できれば、更新ノードへの切り替えも同じ方法で進められます。

ここまでの内容で、CSV更新の原因と解決の方向性は整理できたと思います。
ただし、このままだと「どの条件が揃ったらノードを捨ててAPIに切り替えるか」は自分では判断できません
なぜなら、ツールの抽象化をどこまで信頼するかという判断軸が、まだ整理されていないからです。

今回の詰まりを「n8nの使い方の問題」で終わらせると、別のノードで同じ状況になったときに同じ詰まりを繰り返します。「どのタイミングでノードを捨てるか」という判断の記録をノーコード自動化でデータが壊れた記録【抽象化を捨てた判断基準】にまとめています。あわせて読んでみてください。

bizinets.biz

記事を読んで「もっと知りたい」と思ったあなたへ

bizinets.biz では、ビジネスの仕組みづくりを体系的に学べるコンテンツを用意しています。まずは一度、覗いてみてください。

bizinets.biz へ行く →

関連記事