gmsg is a small command line tool for Google Messages for Web. It can check readiness, list chats, read recent conversation history, compose drafts, send messages, and manage local route aliases.
This project is early and sharp-edged. It automates a browser session, so treat live sends with the same care you would treat any messaging automation.
gmsg statuschecks whether Messages for Web looks usable.gmsg chats --limit 20lists visible conversations.gmsg history --to "Alex" --limit 10reads recent messages from a conversation.gmsg send --to "Alex" --text "On my way"sends a message.gmsg send --to "Alex" --text "Draft only" --draftcomposes without sending.gmsg route set partner "Alex"stores local aliases in~/.config/gmsg/routes.json.
- Python 3.14.7
- Google Chrome, if using the
chrome,automation, orcdpbackends - macOS, for the default
litebackend and thechromeAppleScript backend - A phone paired with Google Messages for Web: https://messages.google.com/web
Backend support:
| Backend | Platform | Install extras | Notes |
|---|---|---|---|
lite |
macOS | none | Default. Drives a lightweight Google Messages app wrapper via Accessibility. |
chrome |
macOS | none | Drives normal Google Chrome via AppleScript. |
automation |
macOS/Linux/Windows-ish | .[playwright] |
Uses Playwright with an isolated browser profile. |
cdp |
macOS/Linux/Windows-ish | .[playwright] |
Attaches to Chrome through a remote debugging port. |
The default is GMSG_AUTH_MODE=lite. If you do not have a Google Messages Lite wrapper app, use chrome first.
Clone the repo, create a virtual environment, and install the CLI:
git clone https://github.com/<owner>/gmsg.git
cd gmsg
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
gmsg --helpFor Playwright-backed modes:
pip install -e '.[playwright]'
playwright install chromiumFor development tools:
pip install -e '.[dev,playwright]'This is the easiest setup if you already use Google Messages in Chrome.
- Open Chrome and go to https://messages.google.com/web.
- Pair your phone if Google asks.
- Allow macOS Automation permissions if prompted.
- Run:
export GMSG_AUTH_MODE=chrome
gmsg status
gmsg chats --limit 5If macOS asks for permissions, allow Terminal or your shell app to control Google Chrome and System Events.
This keeps a separate browser profile under ~/.config/gmsg/chrome-profile.
pip install -e '.[playwright]'
playwright install chromium
export GMSG_AUTH_MODE=automation
gmsg pairA browser opens. Pair Google Messages there, then verify:
gmsg status --json
gmsg chats --limit 5Use this if you want gmsg to attach to a Chrome instance with remote debugging enabled.
export GMSG_AUTH_MODE=cdp
export GMSG_CDP_PORT=9222
gmsg statusIf Chrome is not already listening on that port, gmsg tries to launch it with --remote-debugging-port.
The default lite backend expects a macOS app named Google Messages Lite with process name pake-googlemessageslite.
Override those if your wrapper differs:
export GMSG_AUTH_MODE=lite
export GMSG_LITE_APP_NAME="Google Messages Lite"
export GMSG_LITE_PROCESS_NAME="pake-googlemessageslite"
gmsg statusgmsg status
gmsg chats --limit 10 --json
gmsg history --to "Alex" --limit 10
gmsg send --to "Alex" --text "On my way"
gmsg send --to "Alex" --text "Draft test" --draft
gmsg route set partner "Alex"
gmsg route resolve partnerBefore sending anything live, use drafts:
gmsg chats --limit 10
gmsg history --to "Alex" --limit 5
gmsg send --to "Alex" --text "draft route test" --draft --jsonOnly send live after the draft lands in the correct conversation:
gmsg send --to "Alex" --text "Hello from gmsg" --jsonAliases are local shortcuts. They are stored in ~/.config/gmsg/routes.json unless GMSG_ROUTES_PATH is set.
gmsg route set partner "Alex"
gmsg route resolve partner
gmsg send --to partner --text "Draft only" --draft
gmsg route list
gmsg route remove partnerAliases are not stable Google conversation IDs. If Google Messages changes the displayed conversation title, update the alias.
Environment variables:
| Variable | Default | Purpose |
|---|---|---|
GMSG_AUTH_MODE |
lite |
Browser backend: lite, chrome, automation, or cdp. |
GMSG_ROUTES_PATH |
~/.config/gmsg/routes.json |
Alias route file. |
GMSG_USER_DATA_DIR |
~/.config/gmsg/chrome-profile |
Isolated browser profile for automation mode. |
GMSG_PROFILE_DIRECTORY |
Default |
Chrome profile directory. |
GMSG_CDP_PORT |
9222 |
Chrome DevTools Protocol port for CDP mode. |
GMSG_LITE_APP_NAME |
Google Messages Lite |
macOS Lite wrapper app name. |
GMSG_LITE_PROCESS_NAME |
pake-googlemessageslite |
macOS Lite wrapper process name. |
Open https://messages.google.com/web in the backend browser and pair your phone again.
For Chrome mode:
export GMSG_AUTH_MODE=chrome
gmsg status --jsonFor Playwright automation mode:
export GMSG_AUTH_MODE=automation
gmsg pair
gmsg status --jsonOpen System Settings and check:
- Privacy & Security → Accessibility
- Privacy & Security → Automation
Allow your terminal app to control Google Chrome and System Events.
Use the exact title from gmsg chats, then test with --draft:
gmsg chats --limit 20
gmsg send --to "Exact Chat Title" --text "draft test" --draft --jsonIf you use route aliases, update the alias after verifying the correct title.
Install the optional dependency:
pip install -e '.[playwright]'
playwright install chromium- Prefer
--draftwhen testing routes. - Verify the target conversation with
historybefore first live send. - Route aliases are local convenience only. They are not stable IDs from Google.
- Browser DOM selectors can break when Google changes Messages for Web.
- Do not put phone numbers, private chat names, auth state, screenshots, or local browser profiles in git.
src/gmsg/cli.py # argument parsing and backend dispatch
src/gmsg/config.py # environment-backed runtime settings
src/gmsg/routes.py # local route alias storage
src/gmsg/utils.py # shared normalization / JSON helpers
src/gmsg/backends/chrome.py # macOS Chrome + AppleScript backend
src/gmsg/backends/lite.py # macOS Google Messages Lite accessibility backend
src/gmsg/backends/playwright.py # Playwright / CDP backend
python -m compileall src tests
pytest
PYTHONPATH=src python -m gmsg --helpIf you installed the dev extras:
ruff check src testsMIT. See LICENSE.
Rebuild after a wiped drive: see RESTORE.md.