dusk bot
integrationsupsert rows

dusk botintegrationsgoogle sheets

match google sheets rows by a unique number before updating them

stop adding a fresh row every time a delivery changes. a bot matches records to a key column, updates existing rows and appends new ones.

by the dusk bot team · checked · how we made this

header names do the matching, whatever their order. missing headers become new columns. name the key and preview new headers first, then ask for confirmation before the bot writes to your sheet.

pixel art: a purple cat bot, a blue pixel bot and a green pixel bot beside the Google Sheets mark on a white tile, a chart on an easel and a key with a tag, on a lilac hill in front of an open blue sky, one saying "match before adding"

what it does

upsert means update a match, add the rest. give the spreadsheet link, exact tab and a header that uniquely names each record. use an asset number rather than a person's name. without a chosen key, the first column wins.

  • give headers separately if every incoming row contains data; otherwise the first row becomes headers
  • partial updates can leave other columns alone
  • missing headers create columns automatically
  • name the table's start cell if its headers don't sit at a1

when you would use it

  • keep equipment records current. match each approved change by asset number.
  • refresh delivery status. update known consignments and add new consignment numbers.
  • merge membership changes. match stable references rather than people's positions in the sheet.
  • touch only what's changed. update one or two columns while leaving the others alone.

try it

paste this into a chat with your bot

every thursday at 17:20, read equipment change files added this week to the approved equipment changes folder. compare them with the moonwillow stores register, tab equipment, with headers at c5.

match on the asset number header. show updates, new rows and any new column names here. stop for missing or repeated keys, or rows with more values than columns. ask me before you change anything. apply only the batch i confirm, then report the result. never add an unapproved column or guess a missing reference.
when
thursdays at 17:20
needs
access to approved change files; google sheets read and write for register reads and upsert rows

what comes back looks like this (an example)

moonwillow equipment review

m-42: update condition to inspected
m-87: add portable stand
new columns: none

dorian must confirm before writing. headers start at c5.

set it up

  1. allow the register actions only. connect google sheets with read and write for this bot.
  2. read the destination back. confirm the file, tab, header cell and matching header before giving it changes.
  3. preview the whole effect. ask for matches, additions and new headers before any write.
  4. try a small batch. inspect it once. pause the routine whenever the register's headers change.

what it needs from you

inputrequiredwhat it is
rowsyes2D array of data rows to upsert.
sheetNameyesThe name of the sheet/tab within the spreadsheet.
spreadsheetIdyesThe ID of the spreadsheet.
headersnoList of column names for the data.
keyColumnnoThe column NAME (header text) to use as unique identifier for matching rows.
strictModenoControls how rows with mismatched column counts are handled.

from composio's catalog for Google Sheets (action GOOGLESHEETS_UPSERT_ROWS, read 12 november 20264). your bot fills these in from what you tell it.

how dusk bot handles it

dusk bot counts Upsert Rows (Smart Update/Insert) as a change: it alters something in Google Sheets, and the sending setting does not cover it. a bot you allow only to read can never call it.

the permissions Google Sheets asks for to run it: spreadsheets, drive, drive.file.

where it stops

  • a spelling mistake can become a column. a missing header doesn't simply fail; the action adds it.
  • the first data row can disappear into headers. give column names separately when every incoming row is data.
  • keep rejection of extra values on. rows wider than their headers fail by default. turn that off and extra values silently disappear.
  • don't let the default choose your key. without one, it uses the first column. stop on blank or repeated references.

try it in 2 minutes

  1. paste a sheet link and name its tab
  2. choose the matching header and table start
  3. give one known record and one new record
  4. review the proposed updates and additions first

what it looks like

before

equipment table at c5:
m-42 | condition: awaiting inspection

incoming changes:
m-42 | condition: inspected
m-87 | item: portable stand

after the bot

proposed result:
m-42 updates its condition
m-87 becomes a new row

new columns: none. preview ready for dorian.

an illustration with made-up names and numbers.

mistakes people make

matching on a column letter

name the actual header. the meaning should survive someone moving a column.

letting a header typo through

compare incoming names with the sheet first. a typo can add a whole new column.

questions

does the incoming column order have to match the sheet?

no, header names do the matching. make them exact. review any unfamiliar name before it becomes a new column.

what if my table starts below the top row?

give the header cell. the default is a1. a title or notes above the table can make that wrong.

should i use a person's name as the key?

choose a reference that stays unique. an order or asset number is safer when names can repeat or change.

sources

  1. dusk bot docs: files and apps
  2. dusk bot docs: routines
  3. dusk bot docs: a bot's computer
  4. composio, Google Sheets toolkit (catalog version 20261101_00), checked 12 november 2026

drafted with ai help from the dusk bot docs and the sources listed on this page, then checked against them. if something here is wrong or out of date, write to [email protected].