Post To Chat Webhook

You want the nightly job to say “done, 42 rows” (or “failed”) in the team’s Google Chat space instead of somebody’s inbox. Incoming webhooks make that a single POST. postToChatWebhook(webhookUrl, text) sends { text } as application/json with muteHttpExceptions: true. On a non-2xx response it throws a readable Error that includes the HTTP status and the start of the response body, so the failure shows up in your logs and failure emails with a reason attached. Otherwise it returns the parsed response.

When to use

  • Job-finished / job-failed pings into a Google Chat space (Slack incoming webhooks take the same { text } shape)
  • “New row needs review” nudges from an onEdit or form-submit handler
  • Anywhere you would otherwise email yourself a one-liner

How to use this snippet

/** * POST a plain-text message to a Chat (or Slack) incoming webhook. * Throws a readable Error on non-2xx so failures show up in Executions. * * @param {string} webhookUrl incoming webhook URL (keep it in Script Properties) * @param {string} text message text * @return {Object|string} parsed JSON response (or raw text if not JSON) */ function postToChatWebhook(webhookUrl, text) { if (!webhookUrl) throw new Error('postToChatWebhook: missing webhook URL'); var res = UrlFetchApp.fetch(webhookUrl, { method: 'post', contentType: 'application/json', payload: JSON.stringify({ text: String(text) }), muteHttpExceptions: true }); var code = res.getResponseCode(); var body = res.getContentText() || ''; if (code < 200 || code >= 300) { throw new Error('Chat webhook failed (HTTP ' + code + '): ' + body.slice(0, 200)); } try { return body ? JSON.parse(body) : {}; } catch (e) { return body; // Slack answers with plain "ok" } }

Example

function nightlySync() { var url = PropertiesService.getScriptProperties().getProperty('CHAT_WEBHOOK_URL'); try { var n = syncRows_(); // your job postToChatWebhook(url, '✅ Nightly sync done: ' + n + ' rows'); } catch (err) { // Don't let a broken webhook hide the real error try { postToChatWebhook(url, '❌ Nightly sync failed: ' + err.message); } catch (e) {} throw err; } }

Tips:

  • Treat the webhook URL like a password. Anyone holding it can post to the space. Keep it in Script Properties, not in code or a visible sheet cell.
  • Never log the URL itself. The thrown error includes the status and body, not the URL.
  • Keep messages short. Chat and Slack both rate-limit webhooks, so batch “42 rows done” rather than one message per row.
  • Wrap the failure-path post in its own try so a dead webhook doesn’t replace the real error.
  • Need retries on 429/5xx? Wrap the fetch with retry-urlfetch-with-backoff rather than looping here.

Tip: NitroGAS Co-Pilot can add a done/failed postToChatWebhook ping around an existing job and move the URL into Script Properties. Paste the job function.

Happy Coding!

NitroGAS Chrome Extension

Want this snippet handy inside the Apps Script editor? NitroGAS gives you free themes and snippets — plus optional Co-Pilot when you want a boost (1-week, 1-month, or yearly passes — no subscription). Happy Coding!

Get the Extension