add_google_sheets_row
Append a row to a Google Sheet.
add_google_sheets_row(sheet_id: str, data: dict, sheet_name: str = None) -> dictAdds a row to a Google Sheet. Each key in the data dict maps to a column header, and the value becomes the cell content.
By default the row goes to the first tab. Pass sheet_name to append to a specific tab instead — useful for keeping several trackers in one spreadsheet.
Parameters
| Name | Type | Description |
|---|---|---|
sheet_id | str | The spreadsheet ID — the part of the Google Sheets URL between /d/ and /edit |
data | dict | Column-value pairs. Keys are column headers, values are cell contents. All values are converted to strings |
sheet_name | str | Optional. The tab to append to, named exactly as it appears on the tab at the bottom of the spreadsheet. Defaults to the first tab |
Returns
dict — {"success": bool, "message": str, "row": {"rowNumber": int, "values": dict}}
The returned rowNumber can be used with
update_google_sheets_row.
Because people can sort or insert rows, always pass expected values along with
the row number so an update fails instead of changing the wrong row.
Prerequisites
The Google Sheet must be shared with the Octocom service account:
Give it Editor access. The sheet must have a header row — column names in the first row that match the keys in your data dict.
Tab names must match exactly
sheet_name must match the tab name exactly, including capitalization and any
spaces. If it doesn't match, the call fails with a 404 listing the tabs that
do exist, and nothing is written.
Examples
Log refund events to a spreadsheet
def execute_action(context):
order_id = context["args"]["orderId"]
amount = process_refund(order_id)
add_google_sheets_row("1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms", {
"Order ID": order_id,
"Refund Amount": amount,
"Reason": context["args"].get("reason", ""),
"Date": datetime.now().isoformat(),
"Conversation ID": context["conversation"]["id"],
})
return {"success": True, "amount": amount}Keep several trackers in one spreadsheet
Each tracker writes to its own tab of the same spreadsheet, so everything stays in one file.
def execute_action(context):
add_google_sheets_row(
"1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms",
{
"Conversation ID": context["conversation"]["id"],
"Topic": context["args"]["topic"],
"Resolved": context["args"]["resolved"],
},
sheet_name="Escalations",
)
return {"success": True}Each tab keeps its own header row, so different trackers can have completely different columns.
Collect lead information
def execute_action(context):
add_google_sheets_row("1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms", {
"Name": context["args"]["name"],
"Email": context["args"]["email"],
"Company": context["args"]["company"],
"Interest": context["args"]["interest"],
})
return {"success": True, "message": "Thank you, we'll be in touch!"}