A free monday.com marketplace app that sends one-way SMS through the kwtSMS gateway. Built for GCC customers who keep contacts on monday boards and want to text them without bouncing to a separate tool.
kwtSMS is a Kuwait-based SMS gateway operating since 2007, offering Bulk SMS, an SMS API, OTP SMS, Reminder SMS, and sender IDs. Proudly made in Kuwait.
- Account Settings: login with kwtSMS credentials, set default sender ID / country prefix, manage templates, inspect delivery logs, configure bell notifications.
- Item View tab: send a single SMS from any item using Phone columns or assigned People on the item. Full per-item history on the timeline.
- Right-click item action: quick single-item send from the context menu with "From this item / Custom number" modes.
- Bulk send: board menu action over selected items: pick a phone source once (Phone column or People column), preview per-item resolution, send to many with per-batch dedup.
- Board view: free-form quick send to arbitrary numbers with recent-messages log scoped to the board.
- Dashboard widget: balance, sent today, sent this month, 7-day failure rate + stacked delivered/failed bar chart.
- Integration recipes (automation): four triggers:
- When an item is created
- When a status column changes to a value
- When any column changes
- T-N days before a date column
- Template placeholders:
{item.name},{item.id},{item.url},{item.group},{item.created_at},{item.updated_at},{item.creator_name},{item.creator_email},{column.<Title>}(case-insensitive),{user.name},{user.email},{user.phone},{user.title},{user.location},{board.name},{board.url},{date},{time}. Missing values substitute to empty: never ship a literal{...}in an SMS.
- Runtime: hosted on monday-code (Cloud Run). Node 20, Express 4, React 18 + Vibe.
- Storage:
SecureStoragefrom@mondaycom/apps-sdkfor credentials, config, templates, logs, and dedup indexes. Module-level in-process cache (10-60s TTL) fronts every read to keep the warm path fast. - Cold-start mitigation: Express awaits
SecureStorageGCP-identity warmup before opening the port; a 2-minute keep-alive refreshes the auth token before its 3-minute TTL; a/api/prewarmGET endpoint is hit by every iframe on mount so POSTs (non-idempotent) never race a cold instance. - Phone normalisation: GCC-aware with
libphonenumber-js: accepts bare national,00-prefixed,+-prefixed, Arabic-Indic and Persian digits, leading zero trim, first-valid-match fallback across coverage countries. - Dedup: per-batch only (in-memory
Set<string>keyed by phone + cleaned body + sender). No time window, no persisted deduplication: two manual sends to the same number minutes apart always go through.
Requires Node 20 and the kwtSMS + monday credentials listed in .env.test (gitignored).
npm install
npm run build:server # tsc → dist/
npm run build:client # vite → dist-client/
npm run build # both
npm test # unit only
npm run test:integration # hits real kwtSMS API; consumes pointsFor deployment onto monday-code, mapps code:push -i <draft-version-id>.
boards:read: read column values, items, boards for placeholder and phone resolutionboards:write: write status column after a sendnotifications:write: post in-app bell notifications on zero balance / gateway offlineusers:read: resolve assigned People on items to their profile phoneupdates:write: post timeline updates from recipes