Skip to content

devlikeapro/waha-browser-extension

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WhatsApp Browser Extension

Browser extension that signs WebAuthn passkey requests required by WhatsApp to link a device on some accounts (clients hit this when the server flags an account for passkey pairing instead of a plain QR code).

Two builds, one per browser family, because the page-to-extension messaging mechanism differs between them:

  • chrome/ — Chromium-based browsers (Chrome, Edge, Brave, ...). Pages talk to it directly via chrome.runtime.sendMessage(extensionId, ...).
  • firefox/ — Firefox. Uses a content script bridge instead, since Firefox doesn't support page-to-extension messaging via externally_connectable.

See each folder's own README for the message contract, integration examples, and how to load it locally for development.

Publishing

Version

Bump version.json — the single source of truth — then:

make sync-version   # writes it into both manifests

Scheme is YYYY.M.PATCH (e.g. 2026.7.1); no leading zeros, so July is 7. Stores reject a version that already exists. make release runs this for you.

Make zip

make release
#   .out/chrome-2026.7.1.zip  (16 locales)
#   .out/firefox-2026.7.1.zip (18 locales)

Syncs the version and locales, validates both extensions, writes the zips. Aborts on a manifest that drifted from version.json, a __MSG_ placeholder with no default_locale, a missing locale key, an over-long name/description, or a missing file.

Needs node >= 14, zip, unzip. Also: make check (validate only), make sync-version, make locales, make version, make clean.

Chrome

Developer Dashboard → the existing item ghpdcgnjffaaekflfpcgkgpbafmjldcp (unlisted) → Package → Upload new package.out/chrome-<version>.zip → submit for review.

Never create a new item: a new ID breaks every integrator's chrome.runtime.sendMessage(EXTENSION_ID, ...). Leave the listing name and description blank — they come from _locales/.

Firefox

Developer HubSubmit a New Add-on.out/firefox-<version>.zip. First upload is a new submission (the add-on ID changed during de-branding); later ones use Upload New Version.

Pick "On your own" for a signed self-hosted .xpi, or "On this site" to publish. Name and short description come from _locales/; the long description is edited per-locale in the Hub. No source upload needed. Firefox won't permanently install an unsigned extension, so self-hosted builds still need AMO signing.

Translations

The extension is available in 18 languages, matching the dashboard's language set. Both the store listing (name + description) and the confirmation card shown on web.whatsapp.com are translated.

The language is detected automatically from the browser's UI language and is not configurable: neither Chrome nor Firefox exposes an API to override the locale that i18n.getMessage() resolves against. Unknown languages fall back to English via default_locale. Right-to-left languages (Arabic, Persian, Hebrew, Urdu) lay the card out RTL, driven by the predefined @@bidi_dir message.

Editing or adding a language

Translations live in i18n/messages/<code>.json — the single source of truth. chrome/_locales/ and firefox/_locales/ are generated from it and committed (so both folders stay loadable unpacked, with no build step):

make locales   # regenerate both _locales trees
make check     # fail if they're out of date (also checks version.json)

version.json works the same way: it's the source of truth for the version, written into both manifests by make sync-version.

Never hand-edit a file under _locales/ — the next sync overwrites it. The script also validates that every locale has the same key set as en.json (a missing key would silently render as an empty string), that extName and extDescription fit the stores' 45/132-character limits, and that they stay vendor-neutral.

Store locale quirks

Neither store takes the bare pt or zh codes — only regional variants. Chrome ignores an unknown locale directory silently (the upload succeeds, the language just never appears in the listing), and AMO guesses, which filed our Brazilian pt under "Português (Europeu)". So the sync script writes the variants explicitly, for both browsers: pt.jsonpt_BR + pt_PT, zh.jsonzh_CN. There is deliberately no zh_TW — the translation is Simplified, and Traditional readers are better served by the en fallback than by mislabelled Simplified text.

Beyond that, each store drops locales for its own reasons, and the two are not the same thing:

  • Chrome accepts locale directories only from a fixed table, which has no Punjabi (pa) or Urdu (ur). Those ship in the Firefox build only; the sync script skips them for Chrome automatically, and Chrome users with that UI language fall back to en.
  • AMO translates a listing only into locales in its PROD_LANGUAGES set, which excludes ar, bn, fa, hi, id, pa, ur — so the Firefox store page shows English for those. This is a listing-only limit and not a reason to remove them: Firefox reads _locales/ out of the XPI at runtime, so those users still get a fully translated extension.

What the stores pick up

Both stores read the localized name and description straight out of _locales/ at upload time, so the install page is translated with no extra work. One exception: AMO's long listing description is edited per-locale in the Developer Hub and cannot be checked into this repo.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors