- 動作確認日:2026-10-01
- n8nのバージョン:2.41.3(Docker、セルフホスト)
目次
前提
n8nを localhost で動かしているので、Telegram Triggerは使えません。そこで、TelegramのAPI(getUpdates)で、n8nのほうからボットあてのメッセージを取りに行き、Googleスプレッドシートに記録するワークフローを作りました。
getUpdates は、offset(最後に読んだ update_id + 1)を付けて呼ぶと、それより前のメッセージを「読んだ」とみなして、もう返さなくなるしくみです。
起きたこと1:メッセージが消えた
1回目の作りでは、4通のメモを受け取れていたのに、シートには何も記録されませんでした。しかも、もう一度動かしても、その4通は二度と返ってきませんでした。
原因
- 「メモがあるか」を判定するIfノードの条件の書き方が合っておらず、4通ともfalse側(メモなし)に流れていた。
- メッセージを受け取った時点で、
offsetを先に進めて保存していた。そのため、記録に失敗しても、Telegramには「読んだ」と伝わってしまった。
対処
- Ifノードの条件を「
textが空でない」に変えた。 offsetを保存するのは、シートへの記録が済んだあとにした。
起きたこと2:同じメッセージが2回記録された
作り直したあとに2回続けて動かすと、2回目にも同じ3通が記録され、シートが6行になりました。
原因 offset を保存するノードが、次に読む位置を受け取れておらず、offset が保存されていませんでした。そのため、2回目もTelegramから同じメッセージが返ってきました。
対処
- 次に読む位置を、
getUpdatesの結果から直接計算するようにした。 - 念のため、シートへの書き込みを「Append or Update Row」(メッセージIDで照合)にして、同じメッセージを受け取っても行が増えないようにした。
// シートに記録できたあとで、次に読む位置を覚える
const state = $getWorkflowStaticData('global');
const updates = $('Get Updates').first().json.result || [];
if (updates.length) state.offset = Math.max(...updates.map(u => u.update_id)) + 1;
return $input.all();
確かめたこと
直したあとは、1回目に3通を記録し、2回目は「新しいメモはありませんでした」となって、シートは3行のままでした。
ポイント
- 「読んだ」と伝える(
offsetを進める)のは、処理が全部済んでからにする。 - 万一同じものを受け取っても大丈夫なように、IDで上書きする作りにしておく。
