DEV Community

Ujjwal Dubey
Ujjwal Dubey

Posted on

Log Every Automated WhatsApp Reply to a Google Sheet: A Tiny Audit Trail Small Teams Will Actually Read

Small businesses rarely look at dashboards. They do look at Google Sheets. So if you build or review a WhatsApp automation for a shop, clinic or caterer, log every automated action to a sheet the owner already opens.

It is also a fair question to put to any agency you are vetting as the best AI automation agency in Mumbai for small businesses that live in spreadsheets: "Where can I read what the system did yesterday?"

The columns

time_ist direction phone_masked intent action approved_by note

Keep it to seven columns. Owners stop reading wide sheets.

Appending a row (Python, gspread)

import gspread
from datetime import datetime
from zoneinfo import ZoneInfo

gc = gspread.service_account(filename='sa.json')
ws = gc.open('WhatsApp Log').worksheet('log')

def mask(phone: str) -> str:
    return phone[:3] + 'XXXXXX' + phone[-4:]

def log(direction, phone, intent, action, approved_by='', note=''):
    ts = datetime.now(ZoneInfo('Asia/Kolkata')).strftime('%Y-%m-%d %H:%M')
    ws.append_row([ts, direction, mask(phone), intent, action, approved_by, note],
                  value_input_option='USER_ENTERED')
Enter fullscreen mode Exit fullscreen mode

Rules that keep it useful

  • Mask phone numbers. The sheet will be shared with staff.
  • One row per event, not per conversation.
  • Write the approver's name whenever a person approved something.
  • Never log message bodies with payment or health details. Log the intent ("payment_query") instead.
  • Rotate monthly. A new tab each month keeps the sheet fast.

A daily summary from the same sheet

A small scheduled script can count yesterday's rows by action and send the owner one WhatsApp or email line: how many replies were drafted, sent, handed to a person, or failed. That one line is often the only monitoring a small team will actually read.

Why this matters

When something goes wrong, the first question is always "what happened?" A readable log turns an argument into a lookup. If you are earlier in the process, the build-or-buy chatbot comparison helps decide what to build at all.

I run NxFlowAI (Mumbai). Code is illustrative.

Top comments (1)

Collapse
 
hayrullahkar profile image
Hayrullah Kar •

Masking the numbers and logging the intent instead of the message body are the right defaults. One setting in the snippet works against them. value_input_option='USER_ENTERED' makes Sheets parse every cell as if a person typed it. A masked number like +91XXXXXX1234 starts with a plus sign, which Sheets can read as the start of a formula, so that column may fill with parse errors. The note column carries the bigger risk: any text that begins with = is evaluated as a formula, in a sheet the owner and staff open every day. I would switch to RAW and write the timestamp as a plain ISO string. The other option is to keep USER_ENTERED and prefix the text columns with an apostrophe. Separately, the monthly rotation rule and the code disagree, because worksheet('log') always writes to the same tab. The fix is to build the tab name from the same IST timestamp, for example 2026-10, and create the tab when gspread raises WorksheetNotFound. Then the rotation actually happens.