add support for Buttons and Lists (CTA limited)#119
Conversation
WalkthroughThis change introduces environment variable-driven mode configuration across npm scripts, improves credential persistence through await enforcement and return value propagation, enhances interactive message handling with native WhatsApp flow support and fallback options, and adds dependency injection for contact handling in the web module. Changes
Sequence Diagram(s)sequenceDiagram
participant App as Application<br/>(via npm script)
participant Env as Environment<br/>Variables
participant Web as web.ts<br/>Bootstrap
participant Contact as Contact<br/>Handler
participant Transformer as transformer.ts<br/>(Message Flow)
participant Baileys as Baileys
App->>Env: UNOAPI_MODE=web
Env-->>Web: Set MODE & detect cloud
Web->>Contact: Load ContactBaileys<br/>or ContactDummy
Contact-->>Web: contactType selected
Note over Web,Contact: App initialized with DI
Transformer->>Env: Check UNOAPI_NATIVE_FLOW_BUTTONS
alt Native Flow Enabled
Transformer->>Transformer: Build interactive message<br/>with buttons array
Transformer->>Baileys: Send native interactive
else Native Flow Disabled (default)
Transformer->>Transformer: Build classic<br/>buttonsMessage
Transformer->>Baileys: Send legacy format
end
sequenceDiagram
participant Socket as socket.ts
participant Auth as auth_state.ts
participant Redis as session_redis.ts
participant Storage as Persistent<br/>Storage
Socket->>Socket: firstSaveCreds() triggered
alt Phone number matches config
Socket->>Auth: saveCreds()
Auth->>Redis: writeData()
Redis->>Storage: setAuth(...)
Storage-->>Redis: result
Redis-->>Auth: return result
Auth->>Auth: await completion
Auth-->>Socket: ✓ Creds persisted
else Number mismatch
Socket-->>Socket: Skip persistence
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Tip 📝 Customizable high-level summaries are now available!You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
src/web.ts (2)
62-68: Consider validating UNOAPI_MODE to prevent silent fallback.The current logic defaults to
ContactDummyfor any non-'cloud' value ofUNOAPI_MODE. If an invalid or misspelled mode is provided, the application will silently use the dummy implementation rather than failing fast.Consider adding validation:
let contactType: Contact -if (process.env.UNOAPI_MODE == 'cloud') { +const validModes = ['cloud', 'web', 'simple', 'standalone', 'worker', 'bulker', 'broker', 'bridge', 'waker'] +if (!validModes.includes(process.env.UNOAPI_MODE || '')) { + throw new Error(`Invalid UNOAPI_MODE: ${process.env.UNOAPI_MODE}. Must be one of: ${validModes.join(', ')}`) +} +if (process.env.UNOAPI_MODE === 'cloud') { let listener: Listener = new ListenerBaileys(outgoing, broadcast, getConfigRedis) contactType = new ContactBaileys(listener, getConfigRedis, getClientBaileys, onNewLogin) } else { contactType = new ContactDummy() }
64-64: Review listener variable scope.The
listenervariable is block-scoped and only used for theContactBaileysconstructor. Consider whether it should be declared in a wider scope for potential future use, or if this scoping is intentional.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (9)
.gitignore(1 hunks)package.json(3 hunks)src/cloud.ts(1 hunks)src/defaults.ts(1 hunks)src/services/auth_state.ts(1 hunks)src/services/session_redis.ts(1 hunks)src/services/socket.ts(1 hunks)src/services/transformer.ts(2 hunks)src/web.ts(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
src/services/auth_state.ts (2)
src/services/session.ts (1)
writeData(1-3)src/services/session_file.ts (2)
key(49-59)phone(6-92)
src/services/session_redis.ts (1)
src/services/redis.ts (1)
setAuth(348-352)
src/web.ts (6)
src/services/client.ts (1)
Contact(10-14)src/services/listener.ts (1)
Listener(3-5)src/services/contact_baileys.ts (1)
ContactBaileys(8-53)src/services/client_baileys.ts (2)
getClientBaileys(49-85)logout(408-412)src/services/contact_dummy.ts (1)
ContactDummy(3-7)src/app.ts (1)
App(21-101)
src/services/transformer.ts (1)
src/defaults.ts (1)
UNOAPI_NATIVE_FLOW_BUTTONS(30-31)
🪛 Biome (2.1.2)
src/services/transformer.ts
[error] 233-233: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 234-234: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 235-235: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 236-236: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 237-237: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
🔇 Additional comments (9)
src/services/auth_state.ts (1)
47-50: saveCreds awaiting persistence looks correctAwaiting
writeData('', creds)alignssaveCredswith the updated session backends and ensures callers only proceed after credential persistence completes..gitignore (1)
12-13: Ignoring local tooling/config directories is sensibleAdding
.vscode/(and keeping.yarnrc.yml) in.gitignoreavoids committing local/editor configuration, which is standard practice.src/services/session_redis.ts (1)
10-18: writeData now correctly propagates Redis write completionReturning
setAuth(getBase(key), data, …)from the asyncwriteDataensures callers truly await the Redis persistence and see any failures.src/services/socket.ts (1)
151-165: Immediate first credential save is a good safety improvementOn first valid
creds.update, switchingcurrentSaveCredstosaveCredsand immediatelyawait‑ing it ensures the initial session state is durably stored before further use. The added await is localized and should be safe.If you notice any unexpected latency spikes on initial login, consider logging timing around
saveCreds()to confirm Redis/storage performance.src/services/transformer.ts (2)
7-7: New UNOAPI_NATIVE_FLOW_BUTTONS import is consistent with usageImporting
UNOAPI_NATIVE_FLOW_BUTTONShere matches its use to branch between legacy quick‑reply buttons and native flow interactive messages. Once the flag logic indefaults.tsis corrected, this wiring will behave as intended.
230-456: Wrapcase 'interactive':in block braces to satisfynoSwitchDeclarationslint rule (line 229)Verified that
case 'interactive':at line 229 declares multiple const bindings without block scope. Biome'snoSwitchDeclarationsrule (enabled via"recommended": truein biome.json) flags this pattern. The suggested fix—wrapping the case body in braces—is correct and will resolve the lint error without any runtime changes.- case 'interactive': + case 'interactive': { // Build payload according to whaileys / baileys interactive format // ... rest of case body } break + }package.json (1)
18-44: Verify cross-platform compatibility of inline environment variables.The inline environment variable syntax (e.g.,
UNOAPI_MODE=simple) works on Unix-like systems but will fail on Windows CMD/PowerShell. Consider usingcross-envpackage for cross-platform compatibility.For Windows users, these scripts will fail. If Windows support is required:
"dependencies": { "cross-env": "^7.0.3" }Then update scripts like:
"dev": "cross-env UNOAPI_MODE=simple tsx watch src/index.ts",src/cloud.ts (1)
4-4: LGTM: Proper environment variable initialization order.Setting
UNOAPI_CLOUDafterdotenv.config()and before importing dependent modules ensures the flag is available when needed.src/web.ts (1)
31-40: LGTM: Clean dependency injection pattern for mode-based contact handling.The conditional wiring of
Contactimplementation based onUNOAPI_MODEfollows good DI principles and enables testability through the dummy implementation.Also applies to: 62-68, 70-70
| "audio2textjs": "^1.0.5", | ||
| "awesome-phonenumber": "^6.8.0", | ||
| "baileys": "npm:whaileys@6.3.9", | ||
| "baileys": "npm:whaileys@6.3.10", |
There was a problem hiding this comment.
🧩 Analysis chain
Verify the Baileys library version for security and compatibility.
The update from whaileys@6.3.9 to whaileys@6.3.10 should be verified for security advisories and breaking changes, especially since this PR adds button support functionality.
🌐 Web query:
What are the changes and security advisories for whaileys version 6.3.10?
💡 Result:
I can find that — do you mean the Zoom client (version 6.3.10) or a different project/package named "whaileys"? If you mean Zoom 6.3.10 I can summarize its changes and security advisories now.
The initial search was inconclusive. Let me try a more specific search for the whaileys package:
Let me try a more direct search for the whaileys package:
Let me search for the Baileys library directly, as whaileys appears to be a fork or wrapper:
Unable to locate package whaileys@6.3.10.
The package "whaileys" does not exist on the public npm registry, and Baileys only has versions up to 6.7.10, with 6.3.0 and 6.3.1 available — there is no 6.3.10 version. The npm alias in package.json attempts to map baileys to npm:whaileys@6.3.10, which would fail during installation. Verify that the intended package name and version are correct.
🤖 Prompt for AI Agents
In package.json around line 87, the dependency entry "baileys":
"npm:whaileys@6.3.10" references a non‑existent package/version and will fail
install; update this entry to the correct package and version (either point to
the real Baileys version, e.g. "baileys": "6.7.10", or remove the npm alias and
use the intended package name/version), or if you intentionally depended on a
private fork, replace the alias with a valid install source (git URL or correct
npm package and version); after updating, run npm install to verify the
dependency resolves.
| export const UNOAPI_NATIVE_FLOW_BUTTONS: boolean = | ||
| process.env.UNOAPI_NATIVE_FLOW_BUTTONS === _undefined ? false : process.env.UNOAPI_NATIVE_FLOW_BUTTONS == 'false' |
There was a problem hiding this comment.
UNOAPI_NATIVE_FLOW_BUTTONS logic is inverted
The flag currently becomes true only when UNOAPI_NATIVE_FLOW_BUTTONS === 'false', meaning UNOAPI_NATIVE_FLOW_BUTTONS=false in the environment enables native buttons, while UNOAPI_NATIVE_FLOW_BUTTONS=true disables them. This is the opposite of the intended “enable native flow with CTA” behavior and will be very confusing operationally.
Switch the logic so that 'true' enables native flow and the default remains false:
-export const UNOAPI_NATIVE_FLOW_BUTTONS: boolean =
- process.env.UNOAPI_NATIVE_FLOW_BUTTONS === _undefined ? false : process.env.UNOAPI_NATIVE_FLOW_BUTTONS == 'false'
+export const UNOAPI_NATIVE_FLOW_BUTTONS: boolean =
+ process.env.UNOAPI_NATIVE_FLOW_BUTTONS === _undefined
+ ? false
+ : process.env.UNOAPI_NATIVE_FLOW_BUTTONS == 'true'That way:
- Not set →
false(fallback to classic quick‑reply buttons) "true"→true(enable native flow/CTA buttons)- Anything else (including
"false") →false.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export const UNOAPI_NATIVE_FLOW_BUTTONS: boolean = | |
| process.env.UNOAPI_NATIVE_FLOW_BUTTONS === _undefined ? false : process.env.UNOAPI_NATIVE_FLOW_BUTTONS == 'false' | |
| export const UNOAPI_NATIVE_FLOW_BUTTONS: boolean = | |
| process.env.UNOAPI_NATIVE_FLOW_BUTTONS === _undefined | |
| ? false | |
| : process.env.UNOAPI_NATIVE_FLOW_BUTTONS == 'true' |
🤖 Prompt for AI Agents
In src/defaults.ts around lines 30-31, the environment flag logic is inverted:
it currently treats the string "false" as enabling native flow. Change the
expression so UNOAPI_NATIVE_FLOW_BUTTONS is true only when
process.env.UNOAPI_NATIVE_FLOW_BUTTONS === 'true' (optionally normalize case),
and otherwise false; ensure undefined or any other value yields false and remove
reliance on _undefined.
This application adds support for buttons via Whaileys.
There's the UNOAPI_NATIVE_FLOW_BUTTONS environment variable for those interested in testing buttons with functionality (CTA) (currently only functional on Android) or by default, quick reply (compatible with web/Android/iOS).
Summary by CodeRabbit
New Features
Bug Fixes
Chores