Two-Way Sync Setup: Google Sheets ↔ Ainisa
This guide connects your Google Sheet to Ainisa so that changes you make in the sheet flow back into Ainisa automatically. Once set up, when your team edits an order in the sheet (for example correcting the order details or a phone number), Ainisa updates that lead too.
It takes about 5 minutes and only has to be done once per sheet.
Before you start
You will need two values from your Ainisa lead action settings:
- Sync Secret — a unique key Ainisa generated for this action (looks like
sync_xxxxxxxx…). - Hidden ID Column — the column letter you chose in Ainisa where the hidden ID is stored (for example
G).
You can find both in Ainisa under your assistant → Actions list → Your Action → the Google Sheets destination settings, after you turn on Enable two-way sync and save.
Keep the Sync Secret private. Anyone who has it can send updates to your leads.
Step 1 — Open the Apps Script editor
- Open your Google Sheet in the browser.
- In the top menu, click Extensions → Apps Script.
- A new tab opens with a code editor. Delete any sample code you see there (for example an empty
function myFunction() {}).
Step 2 — Paste the sync script
Copy the script below and paste it into the editor, replacing everything.
/**
* Ainisa ↔ Google Sheets two-way sync.
*/
// ── CONFIG — fill these in ──
const AINISA_WEBHOOK_URL = 'https://api.ainisa.com/api/v1/webhooks/sheets/sync';
const SYNC_SECRET = 'PASTE_YOUR_SYNC_SECRET_HERE'; // from your Ainisa action settings
const ID_COLUMN_LETTER = 'G'; // the hidden ID column you chose in Ainisa
function onEdit(e) {
try {
const range = e.range;
const sheet = range.getSheet();
const row = range.getRow();
if (row === 1) return; // header row, ignore
// Read the hidden Ainisa lead id for this row
const idCol = columnLetterToNumber(ID_COLUMN_LETTER);
const leadUuid = sheet.getRange(row, idCol).getValue();
if (!leadUuid) return; // not an Ainisa-managed row
// Which column changed, and its new value
const changedColLetter = columnNumberToLetter(range.getColumn());
const payload = {
secret: SYNC_SECRET,
lead_uuid: leadUuid,
row_number: row,
changes: {}
};
payload.changes[changedColLetter] = (e.value !== undefined) ? e.value : range.getValue();
UrlFetchApp.fetch(AINISA_WEBHOOK_URL, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload),
muteHttpExceptions: true
});
} catch (err) {
console.error(err); // never block the user's edit
}
}
function columnLetterToNumber(letter) {
let num = 0;
letter = letter.toUpperCase();
for (let i = 0; i < letter.length; i++) {
num = num * 26 + (letter.charCodeAt(i) - 64);
}
return num;
}
function columnNumberToLetter(num) {
let letter = '';
while (num > 0) {
const rem = (num - 1) % 26;
letter = String.fromCharCode(65 + rem) + letter;
num = Math.floor((num - 1) / 26);
}
return letter;
}Step 3 — Fill in your two values
At the top of the script, change these two lines:
SYNC_SECRET— paste your Sync Secret from Ainisa (keep the quotes).ID_COLUMN_LETTER— set it to your hidden ID column letter, for example'G'(keep the quotes).
Leave AINISA_WEBHOOK_URL as it is.
Then click the Save icon (or press Ctrl+S / Cmd+S) and give the project a name such as Ainisa Sync.
Step 4 — Add the trigger (the important part)
Pasting the script is not enough on its own — Google needs an installable trigger so the script is allowed to contact Ainisa. Without this step nothing will sync.
- In the Apps Script editor, click the clock icon on the left sidebar (Triggers).
- Click Add Trigger (bottom right).
- Set the options exactly like this:
- Choose which function to run: onEdit
- Which runs at deployment: Head
- Select event source: From spreadsheet
- Select event type: On edit
- Click Save.
- Google will ask you to authorize the script. Choose your Google account and allow the requested permissions. (You may see a "Google hasn't verified this app" screen — click Advanced → Go to … (unsafe) to continue; this is your own script.)
Step 5 — Hide the ID column
The ID column (for example G) holds a hidden identifier Ainisa uses to match rows. Keep it out of the way so no one edits it by accident:
- Right-click the column letter (for example G) at the top.
- Choose Hide column.
The data stays there, just out of sight. Do not delete this column.
Step 6 — Test it
- Find a row that Ainisa created (it will have a value in the hidden ID column).
- Change something in a mapped column — for example the order details.
- Within a second or two, Ainisa should reflect the change on that lead.
To confirm it fired: in the Apps Script editor, open Executions (the list icon on the left). You should see an onEdit run each time you edit a synced row.
What syncs and what doesn't
- Synced: edits to the columns you mapped in Ainisa (name, phone, order details, and so on).
- Not synced: any extra columns you added yourself, and the hidden ID column. Ainisa ignores those — your own notes and helper columns are safe.
- Changes flow one way here: sheet → Ainisa. Ainisa still writes new and updated orders into the sheet as before.
Troubleshooting
Nothing happens when I edit a cell. Check Executions in the Apps Script editor. If there are no runs, the trigger from Step 4 is missing or wasn't authorized — redo Step 4. A simple pasted onEdit without an installable trigger cannot reach Ainisa.
Executions show an error.
- If it mentions authorization, redo Step 4 and accept the permissions.
- If Ainisa rejects it, your
SYNC_SECRETis wrong or two-way sync was turned off in Ainisa. Re-copy the secret and make sure sync is enabled.
I edited a row but it didn't sync. That row probably has no ID in the hidden column (for example an order created before sync was enabled, or a row you typed by hand). Only rows Ainisa created — which carry a hidden ID — sync back.
I turned sync off and on again in Ainisa. Your existing secret keeps working, so you don't need to change the script. If you ever regenerate the secret, update SYNC_SECRET in Step 3.