Send Google Chat direct messages to individual users from Google Sheets using Google Apps Script.
A free, open-source tool for Google Workspace organizations (businesses, schools, nonprofits) to send personal Chat DMs directly from a spreadsheet β with a polished sidebar UI, bulk sending, filtering, rate limiting, and full send logging.
- Direct Messages β Send personal DMs to any user in your Google Workspace domain
- Sidebar UI β A polished compose interface inside Google Sheets with search, filtering, and multi-select
- Bulk Sending β Select multiple recipients and send with one click
- Recipient Management β Organize recipients by school/organization, role, and group
- IMPORTRANGE Support β Pull recipient lists from other spreadsheets (e.g., student databases, HR systems)
- Rate Limiting β Configurable rate limit to stay within Google Chat API quotas
- Send Log β Automatic audit trail of every message sent, with color-coded status
- Rich Card Messages β Send formatted card messages with headers and timestamps (via script)
- No Bot Required β Messages appear from your Google account, not a bot. No prior interaction needed.
- Completely Free β Uses Google's free APIs with no third-party services
| Requirement | Details |
|---|---|
| Google Workspace | Any paid plan (Business, Enterprise, Education, Nonprofits). Free Gmail accounts will NOT work. |
| Google Cloud Project | Free β needed only to enable the Chat API (~10 min one-time setup) |
| Admin Access | Not required. Any Workspace user can set this up for their domain. |
- Go to sheets.google.com and create a new blank spreadsheet
- Name it whatever you like (e.g.,
Chat DMs,Staff Messenger, etc.)
- In your new spreadsheet, go to Extensions β Apps Script
- The Apps Script editor will open in a new tab
- Delete the default
Code.gscontent - Create the following files and paste the code from this repository:
| File | Type | Source |
|---|---|---|
Code.gs |
Script | Code.gs |
ChatDM.gs |
Script | ChatDM.gs |
RecipientManager.gs |
Script | RecipientManager.gs |
MessageEngine.gs |
Script | MessageEngine.gs |
SendLogger.gs |
Script | SendLogger.gs |
Sidebar.html |
HTML | Sidebar.html |
Tip: To create a new file in the Apps Script editor, click the + button next to "Files" and select "Script" (for
.gsfiles) or "HTML" (for.htmlfiles).
- Click on the gear icon (βοΈ) in the left sidebar β Project Settings
- Check "Show 'appsscript.json' manifest file in editor"
- Go back to the editor, click on
appsscript.json, and replace its content with the appsscript.json from this repo - Save all files (Cmd+S / Ctrl+S)
You need a GCP project to enable the Google Chat API. This is free.
- Go to Google Cloud Console
- Create a new project (or use an existing one):
- Click the project dropdown at the top β New Project
- Name it something like
Chat DMsorWorkspace Automations - Click Create
- In your GCP project, go to APIs & Services β Library
- Direct link:
https://console.cloud.google.com/apis/library
- Direct link:
- Search for "Google Chat API"
- Click on it and click Enable
- Go to APIs & Services β OAuth consent screen
- Direct link:
https://console.cloud.google.com/apis/credentials/consent
- Direct link:
- Select Internal (this makes it available only to your organization)
- Fill in:
- App name:
Chat DMs(anything you like) - User support email: your email
- Developer contact email: your email
- App name:
- Click Save and Continue through the remaining steps (no changes needed)
- Go to: APIs & Services β Google Chat API β Configuration
- Or search for the Google Chat API in the Enabled APIs list and click on it, then go to the Configuration tab
- Fill in:
- App name:
Chat DMs(anything descriptive) - Avatar URL: leave blank (or optionally add your org logo URL)
- Description:
Direct messaging system - Enable Interactive features: OFF
- Visibility: Specific people and groups β add your email
- App name:
- Click Save
- In your GCP project dashboard, note the Project Number (shown on the Home page)
- Go back to the Apps Script editor β Project Settings (gear icon)
- Under "Google Cloud Platform (GCP) Project", click Change project
- Enter your GCP project number and click Set project
- Go back to your Google Sheet and refresh the page
- You should see a π¬ Chat DM menu in the menu bar
- Click π¬ Chat DM β βοΈ Setup β Initialize Sheet Tabs β this creates the Recipients, Send Log, and Config tabs
- Click π¬ Chat DM β π¨ Send Test to Myself
- Note: Google Chat doesn't allow DMs to yourself, so it'll prompt for a colleague's email
- Enter a colleague's Workspace email and send
- The first time, Google will ask you to authorize the app β click through to approve
- Ask your colleague to check their Google Chat β they should have received the message!
Go to the Recipients tab and add your users:
| Name | School | Role | Group | Active | |
|---|---|---|---|---|---|
| Alice Johnson | alice@example.com | Main Campus | Staff | Teachers | TRUE |
| Bob Smith | bob@example.com | Main Campus | Student | Class 10-A | TRUE |
| Carol Davis | carol@example.com | West Branch | Staff | Admin | TRUE |
- School/Role/Group: These are filter categories β name them however makes sense for your organization
- Active: Set to
FALSEto temporarily exclude someone without deleting their row - IMPORTRANGE: You can use
=IMPORTRANGE("spreadsheet_url", "Sheet!A:F")to pull data from another spreadsheet (e.g., an HR database or student information system)
- Click π¬ Chat DM β π Compose Message to open the sidebar
- Search/filter recipients by name, email, school, role, or group
- Select recipients (checkboxes) β use "Select All" for bulk sends
- Type your message β supports Google Chat formatting:
*bold*for bold_italic_for italic~strikethrough~forstrikethrough
- Click Send Message
The Send Log tab automatically records:
- Timestamp, recipient name, email, message preview, status, and who sent it
- Status cells are color-coded: π’ green = sent, π΄ red = failed
The Config tab lets you customize:
| Setting | Default | Description |
|---|---|---|
| School 1/2/3 Name | (blank) | Names of your schools/locations (for reference) |
| Default Message Title | School Notification | Default title for card messages |
| Rate Limit (messages per minute) | 30 | Pause after this many sends to avoid API rate limits |
| Enable Send Log | TRUE | Toggle send logging on/off |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Google Sheet β
β ββββββββββββ ββββββββββββ ββββββββββ ββββββββββββ β
β βRecipientsβ β Send Log β β Config β β Sheet1 β β
β ββββββββββββ ββββββββββββ ββββββββββ ββββββββββββ β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββ
β
βββββββββββββ΄ββββββββββββ
β Apps Script β
β β
β Code.gs ββββββββββββ β β Menu, sidebar, handlers
β ChatDM.gs βββββββββ β β Chat API layer
β RecipientManager.gs β β Read/filter recipients
β MessageEngine.gs βββ β β Bulk send + rate limiting
β SendLogger.gs ββββββ β β Audit trail
β Sidebar.html βββββββ β β Compose UI
β appsscript.json ββββ β β Manifest + OAuth scopes
β β
βββββββββββββ¬ββββββββββββ
β
βΌ
βββββββββββββββββββββββββ
β Google Chat API v1 β
β (Advanced Service) β
β β
β β’ Spaces.setup() β β Create/find DM space
β β’ Messages.create() β β Send the message
β β
β User Authentication β β Messages appear from YOU
βββββββββββββββββββββββββ
- User auth, not bot auth: Messages come from the person running the script, making them feel personal and trustworthy
- IIFE module pattern: Each
.gsfile is wrapped in an IIFE to avoid global namespace pollution - Rate limiting: Configurable via the Config tab to prevent hitting API quotas
- Idempotent DM setup:
Chat.Spaces.setup()finds existing DM spaces rather than creating duplicates
| Limitation | Details |
|---|---|
| Workspace only | Free/personal Gmail accounts cannot use the Chat API |
| Can't DM yourself | Google Chat API prevents creating a DM space with yourself |
| Same domain only | You can only DM users within your Google Workspace domain |
| API quotas | Google Chat API has usage limits β the built-in rate limiter helps avoid hitting them |
| No scheduled messages | Currently all sends are immediate (scheduled sends are a planned enhancement) |
Edit appsscript.json and change the timeZone value:
{
"timeZone": "America/New_York",
...
}See supported timezone values.
The ChatDM module supports rich card messages. You can call this from the script editor or a custom function:
ChatDM.sendCardMessage(
'user@yourdomain.com',
'Meeting rescheduled to 3 PM tomorrow.',
'Schedule Update', // Card title
'From the Admin Office' // Card subtitle
);// Send to all recipients in a group
MessageEngine.sendToGroup('Class 10-A', 'Reminder: Field trip tomorrow!');
// Send to all recipients at a school/location
MessageEngine.sendToSchool('Main Campus', 'Campus closed Friday for maintenance.');Contributions are welcome! Feel free to open issues or submit pull requests.
- Scheduled/deferred message sending
- Message templates (reusable, stored in Config)
- Delivery read receipts
- Bulk import/export of recipients
- Dashboard with send analytics
This project is licensed under the MIT License.
Built with:
Originally developed for K-12 schools using Google Workspace for Education, but works for any Google Workspace organization.