How to pick the latest item (row) added to an airtable table?

Hi, wondering if anyone could help. Since there’s no trigger for airtable, I’m trying to create some logic to simulate one: I take the latest added row to an airtable table compare its ID to previously processed item, if it’s the same, it stops the flow else it progresses in the flow.

How could we do this?

I am working on setting up the same kind of system, but for rows in a Google Sheet. If I come up with something, I’ll try to post it back here too.

Polling is never not the best thing. For Google Sheets, I think it would be possible to build a proper Trigger-Node. For Airtable does it not seem like it though. When I looked I was not able to find anything to do that. So I guess polling it is.

If it does not execute to often (like if it would never overlap) and the data is not too large (like you said just an id) it would be possible to use static workflow data. With that, it is possible to save data with the workflow. Does, for example, get used for the Github-Trigger Node to save the webhook id. Looks like this:

	const webhookData = this.getWorkflowStaticData('node');
	webhookData.webhookId = responseData.id;

There are however two problems right now.
That method is not exposed in the Function-Node. That is, however, an easy fix and takes two minutes.
There seems to be a bug that the data does not get saved correctly when executing multiple times (like when triggered via Interval node or similar). No idea how much work that would be.
Normally I would try to fix it now asap but sadly things are still a little bit crazy from the launch and I am just answering emails, issues and community questions all day long. So do not know when I find time to look into that. Sorry!

An alternative would be to use the Postgres node to persist the value there. Or simply saving a file would also be possible.

I hope that helps!

Ok in the latest n8n version (0.25.1) the bug got now fixed. Also, do the function nodes now have access to the static data.

Here a basic counter-example:

{
  "nodes": [
    {
      "parameters": {
        "functionCode": "const staticData = this.getWorkflowStaticData('node');\n\nstaticData.count = staticData.count || 0;\nstaticData.count += 1;\n\n// Data can also be deleted again\n//delete staticData.count;\n\nitems[0].json.count = staticData.count;\n\nreturn items;"
      },
      "name": "Function",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        450,
        500
      ]
    },
    {
      "parameters": {
        "interval": 4
      },
      "name": "Interval",
      "type": "n8n-nodes-base.interval",
      "typeVersion": 1,
      "position": [
        250,
        500
      ]
    }
  ],
  "connections": {
    "Interval": {
      "main": [
        [
          {
            "node": "Function",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Be aware that the static data does not get persisted when testing via the Editor-UI. Only if it is in production mode will the static data be persisted and it will count up.

I made a version of this that is really horrible! But it does work. Basically I have a Google sheet connected to a form (INPUT), and another tab in the sheet that serves as a log (LOG). As submissions from the form come into the sheet, n8n checks both tabs and adds an boolean attribute “fromLOG” depending on which tab it came from. A merge node combines them and overwrites all ‘false’ values from the INPUT tab as ‘true’ if they already exist in LOG. Then a function node filters out so only rows that were unique to the INPUT tab pass through.

{
“nodes”: [
{
“parameters”: {
“values”: {
“boolean”: [
{
“name”: “fromLOG”,
“value”: true
}
]
}
},
“name”: “Set”,
“type”: “n8n-nodes-base.set”,
“typeVersion”: 1,
“position”: [
450,
400
]
},
{
“parameters”: {
“values”: {
“boolean”: [
{
“name”: “fromLOG”
}
]
}
},
“name”: “Set1”,
“type”: “n8n-nodes-base.set”,
“typeVersion”: 1,
“position”: [
450,
200
]
},
{
“parameters”: {
“mode”: “mergeByIndex”
},
“name”: “Merge”,
“type”: “n8n-nodes-base.merge”,
“typeVersion”: 1,
“position”: [
600,
300
]
},
{
“parameters”: {
“functionCode”: “let result = items.filter(item => !item.json.fromLOG);\nreturn result;”
},
“name”: “Function”,
“type”: “n8n-nodes-base.function”,
“typeVersion”: 1,
“position”: [
750,
300
]
}
],
“connections”: {
“Set”: {
“main”: [
[
{
“node”: “Merge”,
“type”: “main”,
“index”: 1
}
]
]
},
“Set1”: {
“main”: [
[
{
“node”: “Merge”,
“type”: “main”,
“index”: 0
}
]
]
},
“Merge”: {
“main”: [
[
{
“node”: “Function”,
“type”: “main”,
“index”: 0
}
]
]
}
}
}
Let me know how I could do this better!