-
-
Notifications
You must be signed in to change notification settings - Fork 87
add WABA support #117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
add WABA support #117
Conversation
WalkthroughAdds WABA and BUSINESS_ID compatibility routes and new Graph API–style endpoints (accounts, debug_token, waba, subscriptions); extends PhoneNumberController with new methods, persistence via Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Router
participant Controller as PhoneNumberController
participant Config as Config Store
rect rgba(230,245,255,0.9)
note right of Client: Token debug flow
Client->>Router: GET /debug_token?input_token=...&access_token=...
Router->>Controller: debugToken(req,res)
Controller->>Config: getConfig()
Controller->>Controller: compare tokens / lookup app metadata
Controller-->>Client: Graph-format token/app metadata
end
rect rgba(235,255,235,0.9)
note right of Client: Create or update subscription
Client->>Router: POST /:phone/subscriptions
Router->>Controller: addsubs(req,res)
Controller->>Config: getConfig() -> find or create meta webhook entry
Controller->>Config: setConfig(updated)
Controller->>Controller: reload.run(phone)
Controller-->>Client: webhook creation/update result (Graph-format)
end
rect rgba(255,250,235,0.9)
note right of Client: Accounts / WABA listing
Client->>Router: GET /:version/{BUSINESS_ID}/owned_whatsapp_business_accounts
Router->>Controller: accounts(req,res)
Controller->>Config: getConfig() -> gather accessible accounts/phones
Controller-->>Client: Graph-format account/phone list
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Potential review focal points:
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used🧬 Code graph analysis (1)src/web.ts (5)
🪛 Biome (2.1.2)src/web.ts[error] 31-31: Unexpected token (parse) [error] 31-32: Unexpected token (parse) [error] 32-32: Unexpected token (parse) [error] 33-33: Unexpected token (parse) [error] 33-33: Unexpected token (parse) [error] 34-34: Unexpected token (parse) [error] 34-34: Unexpected token (parse) [error] 35-35: Unexpected token (parse) [error] 35-35: Unexpected token (parse) 🔇 Additional comments (3)
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Nitpick comments (3)
src/router.ts (1)
32-32: Fix spacing in import statement.The import has inconsistent spacing around the comma.
Apply this diff:
-import { WABA_ID ,BUSINESS_ID } from './defaults' +import { WABA_ID, BUSINESS_ID } from './defaults'src/controllers/phone_number_controller.ts (2)
6-6: Fix spacing in import statement.The import has inconsistent spacing around commas.
Apply this diff:
-import { UNOAPI_AUTH_TOKEN , WABA_ID , BUSINESS_ID } from '../defaults' +import { UNOAPI_AUTH_TOKEN, WABA_ID, BUSINESS_ID } from '../defaults'
285-285: Extract 'metaId' magic string to a constant.The string
'metaId'appears in multiple methods (getsubs,addsubs). Extract it to a constant at the top of the file for maintainability.At the top of the class:
private static readonly META_WEBHOOK_ID = 'metaId'Then use
PhoneNumberController.META_WEBHOOK_IDthroughout.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/controllers/phone_number_controller.ts(2 hunks)src/defaults.ts(1 hunks)src/router.ts(3 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/controllers/phone_number_controller.ts (5)
src/services/redis.ts (2)
getConfig(283-290)setConfig(293-315)src/services/config.ts (1)
getConfig(163-165)src/services/reload.ts (1)
Reload(8-17)src/services/security.ts (1)
getAuthHeaderToken(62-74)src/defaults.ts (2)
UNOAPI_AUTH_TOKEN(8-8)WABA_ID(71-71)
src/router.ts (4)
src/controllers/phone_number_controller.ts (1)
PhoneNumberController(10-409)src/services/config.ts (1)
getConfig(163-165)src/app.ts (1)
router(69-100)src/defaults.ts (2)
BUSINESS_ID(70-70)WABA_ID(71-71)
🔇 Additional comments (7)
src/defaults.ts (1)
70-71: LGTM!The new constants follow the established pattern in this file and provide sensible defaults for WABA integration.
src/router.ts (2)
56-56: LGTM!The controller instantiation correctly passes the
reloadparameter, aligning with the updated constructor signature.
73-82: LGTM!The new WABA and Business ID compatibility routes are properly configured with middleware and follow the Graph API conventions.
src/controllers/phone_number_controller.ts (4)
15-18: LGTM!The constructor correctly accepts and stores the
reloadparameter, which is used by theaddsubsmethod to refresh configuration after updates.
89-97: Early break prevents listing multiple accounts.The loop breaks after finding the first authorized phone (line 95), which means if multiple phone numbers are configured with valid tokens, only one WABA account entry is returned. This may be intentional for a single-WABA setup, but could be problematic if the system should support multiple accounts.
Verify whether this behavior is correct for your use case. If multiple WABAs should be supported, remove the
breakstatement and adjust the logic to track unique WABA IDs.
140-146: Verify token validation requirements.The validation requires both
inputTokenandaccessTokento be identical and equal toconfig.authToken. This differs from typical OAuth debug_token flows whereinput_tokenis the token being validated andaccess_tokenis used to authorize the validation request. Confirm this matches your Graph API compatibility requirements.
389-390: LGTM!The configuration persistence and reload logic correctly saves the updated webhook configuration and triggers a reload to apply the changes immediately.
| const token = getAuthHeaderToken(req) | ||
| const { fields } = req.query | ||
|
|
||
| if (fields && (fields as string).split(',').includes('owned_whatsapp_business_accounts') || req.path.endsWith('/owned_whatsapp_business_accounts')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix operator precedence in condition.
The condition has a precedence issue. The || operator has lower precedence than the method call, so the current logic evaluates as (fields && fields.split(...).includes(...)) || (req.path.endsWith(...)), but the split could fail if fields is not a string.
Apply this diff:
- if (fields && (fields as string).split(',').includes('owned_whatsapp_business_accounts') || req.path.endsWith('/owned_whatsapp_business_accounts')) {
+ if ((fields && (fields as string).split(',').includes('owned_whatsapp_business_accounts')) || req.path.endsWith('/owned_whatsapp_business_accounts')) {📝 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.
| if (fields && (fields as string).split(',').includes('owned_whatsapp_business_accounts') || req.path.endsWith('/owned_whatsapp_business_accounts')) { | |
| if ((fields && (fields as string).split(',').includes('owned_whatsapp_business_accounts')) || req.path.endsWith('/owned_whatsapp_business_accounts')) { |
🤖 Prompt for AI Agents
In src/controllers/phone_number_controller.ts around line 84, the conditional
suffers from operator precedence and a potential runtime error when calling
split on a non-string; update it to explicitly check that fields is a string
before calling split and group the left side with parentheses so the overall
expression is ((typeof fields === 'string' && (fields as
string).split(',').includes('owned_whatsapp_business_accounts')) ||
req.path.endsWith('/owned_whatsapp_business_accounts')). Ensure the typeof check
comes first to prevent split on non-strings and add parentheses to make the
intended precedence explicit.
| public async waba(req: Request, res: Response) { | ||
| logger.debug('headers %s', JSON.stringify(req.headers)) | ||
| logger.debug('params %s', JSON.stringify(req.params)) | ||
| logger.debug('query %s', JSON.stringify(req.query)) | ||
| logger.debug('path %s', req.path) | ||
|
|
||
| try { | ||
| const token = getAuthHeaderToken(req) | ||
| const { waba_id } = req.params | ||
| const phones = await this.sessionStore.getPhones() | ||
| const foundConfigs: any[] = [] | ||
|
|
||
| for (const number of phones) { | ||
| const config = await this.getConfig(number) | ||
| if (token === config.authToken) { | ||
| foundConfigs.push({ ...config, number }) | ||
| } | ||
| } | ||
|
|
||
| if (foundConfigs.length === 0) { | ||
| return res.status(403).json({ error: 'Invalid or unauthorized token' }) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Validate waba_id parameter against WABA_ID constant.
The method extracts waba_id from req.params (line 181) but never validates that it matches the expected WABA_ID constant. This could allow requests to arbitrary WABA IDs to succeed as long as the token is valid.
Consider adding validation after line 181:
if (waba_id !== WABA_ID) {
return res.status(404).json({ error: 'WABA ID not found' })
}🤖 Prompt for AI Agents
In src/controllers/phone_number_controller.ts around lines 173 to 194, after
extracting waba_id from req.params (line ~181) add a validation that compares
waba_id to the WABA_ID constant and if they don't match return a 404 JSON
response; specifically, insert a check that if (waba_id !== WABA_ID) then return
res.status(404).json({ error: 'WABA ID not found' }) so only requests for the
expected WABA ID proceed.
| else { | ||
| logger.debug('Processing generic WABA info request') | ||
| const firstCfg = foundConfigs[0] | ||
|
|
||
| response = { | ||
| id: waba_id, | ||
| name: String(firstCfg.label || 'UNOAPI WABA ACCOUNT').toUpperCase(), | ||
| currency: 'BRL', | ||
| timezone_id: 42, | ||
| message_template_namespace: firstCfg.label.slice(0, 10), | ||
| primary_business_location: { country: 'BR' }, | ||
| creation_time: new Date().toISOString(), | ||
| tier: 'TIER_1', | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add null safety for label access.
Line 236 accesses firstCfg.label.slice(0, 10) which could throw if label is undefined or null, even though line 233 has a fallback.
Apply this diff:
- message_template_namespace: firstCfg.label.slice(0, 10),
+ message_template_namespace: (firstCfg.label || 'UNOAPI').slice(0, 10),📝 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.
| else { | |
| logger.debug('Processing generic WABA info request') | |
| const firstCfg = foundConfigs[0] | |
| response = { | |
| id: waba_id, | |
| name: String(firstCfg.label || 'UNOAPI WABA ACCOUNT').toUpperCase(), | |
| currency: 'BRL', | |
| timezone_id: 42, | |
| message_template_namespace: firstCfg.label.slice(0, 10), | |
| primary_business_location: { country: 'BR' }, | |
| creation_time: new Date().toISOString(), | |
| tier: 'TIER_1', | |
| } | |
| } | |
| else { | |
| logger.debug('Processing generic WABA info request') | |
| const firstCfg = foundConfigs[0] | |
| response = { | |
| id: waba_id, | |
| name: String(firstCfg.label || 'UNOAPI WABA ACCOUNT').toUpperCase(), | |
| currency: 'BRL', | |
| timezone_id: 42, | |
| message_template_namespace: (firstCfg.label || 'UNOAPI').slice(0, 10), | |
| primary_business_location: { country: 'BR' }, | |
| creation_time: new Date().toISOString(), | |
| tier: 'TIER_1', | |
| } | |
| } |
🤖 Prompt for AI Agents
In src/controllers/phone_number_controller.ts around lines 227 to 241, the code
uses firstCfg.label.slice(0, 10) which can throw if label is null/undefined;
change it to safely derive the namespace by coercing label to string with a
fallback before slicing (e.g., use (String(firstCfg.label || 'UNOAPI WABA
ACCOUNT')).slice(0, 10) or optional chaining with a default) so the slice call
never receives null/undefined and preserves the existing fallback behavior.
| if (!accessToken || !accessToken.includes('|')) { | ||
| return res.status(400).json({ error: 'Access token inválido ou ausente' }) | ||
| } | ||
|
|
||
| const [appId, userToken] = accessToken.split('|') | ||
|
|
||
| if (appId !== phone) { | ||
| return res.status(403).json({ error: 'appId não corresponde ao número de telefone' }) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add safer token parsing with error handling.
The token split at line 266 assumes exactly two parts, but doesn't handle cases where the token might contain multiple pipe characters or be malformed in other ways.
Apply this diff:
// Verificação básica
if (!accessToken || !accessToken.includes('|')) {
return res.status(400).json({ error: 'Access token inválido ou ausente' })
}
const [appId, userToken] = accessToken.split('|')
+
+ if (!appId || !userToken) {
+ return res.status(400).json({ error: 'Access token mal formatado' })
+ }
if (appId !== phone) {📝 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.
| if (!accessToken || !accessToken.includes('|')) { | |
| return res.status(400).json({ error: 'Access token inválido ou ausente' }) | |
| } | |
| const [appId, userToken] = accessToken.split('|') | |
| if (appId !== phone) { | |
| return res.status(403).json({ error: 'appId não corresponde ao número de telefone' }) | |
| } | |
| if (!accessToken || !accessToken.includes('|')) { | |
| return res.status(400).json({ error: 'Access token inválido ou ausente' }) | |
| } | |
| const [appId, userToken] = accessToken.split('|') | |
| if (!appId || !userToken) { | |
| return res.status(400).json({ error: 'Access token mal formatado' }) | |
| } | |
| if (appId !== phone) { | |
| return res.status(403).json({ error: 'appId não corresponde ao número de telefone' }) | |
| } |
🤖 Prompt for AI Agents
In src/controllers/phone_number_controller.ts around lines 262 to 270, the
current accessToken parsing assumes exactly one '|' and does a blind split;
change it to robustly validate and extract the two parts: first check
accessToken exists and contains a '|' then split with a limit of 2 (or use
indexOf to split into left/right only), trim both parts, verify neither part is
empty, and only then assign appId and userToken; if any validation fails return
a 400 with a clear error; keep the existing appId !== phone check and return 403
as before.
| const accessToken = req.query.access_token as string | ||
| const body = req.body || {} | ||
| const [appId, userToken] = accessToken.split('|') | ||
|
|
||
| // --- Validações --- | ||
| if (!config) { | ||
| return res.status(404).json({ error: 'Número não encontrado' }) | ||
| } | ||
| if (!accessToken || !accessToken.includes('|')) { | ||
| return res.status(400).json({ error: 'Access token inválido ou ausente' }) | ||
| } | ||
| if (appId !== phone || userToken !== config.authToken) { | ||
| return res.status(403).json({ error: 'appId ou Token não corresponde' }) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add safer token parsing and align validation with getsubs.
Two issues:
- The token split at line 328 lacks validation (same issue as in
getsubs). - The token validation at line 337 is stricter than in
getsubs(line 279), which also acceptsUNOAPI_AUTH_TOKEN. This inconsistency could cause unexpected behavior.
Apply this diff:
const accessToken = req.query.access_token as string
const body = req.body || {}
- const [appId, userToken] = accessToken.split('|')
// --- Validações ---
if (!config) {
return res.status(404).json({ error: 'Número não encontrado' })
}
if (!accessToken || !accessToken.includes('|')) {
return res.status(400).json({ error: 'Access token inválido ou ausente' })
}
- if (appId !== phone || userToken !== config.authToken) {
+
+ const [appId, userToken] = accessToken.split('|')
+ if (!appId || !userToken) {
+ return res.status(400).json({ error: 'Access token mal formatado' })
+ }
+ if (appId !== phone || (userToken !== config.authToken && userToken !== UNOAPI_AUTH_TOKEN)) {
return res.status(403).json({ error: 'appId ou Token não corresponde' })
}🤖 Prompt for AI Agents
In src/controllers/phone_number_controller.ts around lines 326 to 339, the
access token is split without checking it first and the validation rejects
tokens that would be accepted by getsubs; first ensure access_token exists and
contains '|' before calling split, parse into two parts safely (limit split to
two parts), and validate that appId matches phone and that userToken equals
either config.authToken or process.env.UNOAPI_AUTH_TOKEN to match getsubs
behavior; return the same error codes/messages already used, keeping the config
existence check and token-format check ordered so you never split undefined.
| const newWebhook = { | ||
| sendNewMessages: true, | ||
| id: 'metaId', | ||
| urlAbsolute: callback_url, | ||
| token: verify_token, | ||
| header: 'Authorization', | ||
| sendGroupMessages: false, | ||
| sendNewsletterMessages: false, | ||
| sendOutgoingMessages: true, | ||
| sendUpdateMessages: true, | ||
| sendIncomingMessages: true, | ||
| sendTranscribeAudio: false, | ||
| url:"http://localhost:9876/webhooks/fake", | ||
| addToBlackListOnOutgoingMessageWithTtl:0, | ||
| timeoutMs:360000 | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove hard-coded localhost URL and make webhook configuration more flexible.
Line 365 contains a hard-coded url: "http://localhost:9876/webhooks/fake" which appears incorrect for a production webhook subscription. Additionally, many webhook settings are hard-coded and might need to be configurable based on the subscription request.
At minimum, apply this diff to remove the hard-coded URL:
const newWebhook = {
sendNewMessages: true,
id: 'metaId',
urlAbsolute: callback_url,
token: verify_token,
header: 'Authorization',
sendGroupMessages: false,
sendNewsletterMessages: false,
sendOutgoingMessages: true,
sendUpdateMessages: true,
sendIncomingMessages: true,
sendTranscribeAudio: false,
- url:"http://localhost:9876/webhooks/fake",
addToBlackListOnOutgoingMessageWithTtl:0,
timeoutMs:360000
}Consider whether other hard-coded boolean flags should be derived from the fields parameter in the request body.
📝 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.
| const newWebhook = { | |
| sendNewMessages: true, | |
| id: 'metaId', | |
| urlAbsolute: callback_url, | |
| token: verify_token, | |
| header: 'Authorization', | |
| sendGroupMessages: false, | |
| sendNewsletterMessages: false, | |
| sendOutgoingMessages: true, | |
| sendUpdateMessages: true, | |
| sendIncomingMessages: true, | |
| sendTranscribeAudio: false, | |
| url:"http://localhost:9876/webhooks/fake", | |
| addToBlackListOnOutgoingMessageWithTtl:0, | |
| timeoutMs:360000 | |
| } | |
| const newWebhook = { | |
| sendNewMessages: true, | |
| id: 'metaId', | |
| urlAbsolute: callback_url, | |
| token: verify_token, | |
| header: 'Authorization', | |
| sendGroupMessages: false, | |
| sendNewsletterMessages: false, | |
| sendOutgoingMessages: true, | |
| sendUpdateMessages: true, | |
| sendIncomingMessages: true, | |
| sendTranscribeAudio: false, | |
| addToBlackListOnOutgoingMessageWithTtl:0, | |
| timeoutMs:360000 | |
| } |
🤖 Prompt for AI Agents
In src/controllers/phone_number_controller.ts around lines 353 to 368, remove
the hard-coded url ("http://localhost:9876/webhooks/fake") and replace it with
the incoming callback_url (already present) so the webhook points to the
request-supplied endpoint; also stop hard-coding boolean flags and timeout by
reading them from the request body (e.g., a fields or options object) with
sensible default fallbacks (keep current true/false values if the request does
not supply them) so webhook configuration is flexible for production and tests.
Ensure id/token/header remain set from existing variables, validate/normalize
the incoming values (types and allowed ranges like timeoutMs), and keep backward
compatibility by defaulting to the current values when fields are absent.
| router.get(`/:phone/subscriptions`, phoneNumberController.getsubs.bind(phoneNumberController)) | ||
| router.post(`/:phone/subscriptions`, phoneNumberController.addsubs.bind(phoneNumberController)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add middleware to subscription routes for consistency and security.
The subscription routes (lines 84-85) don't use the middleware parameter, unlike most other routes in this file. The POST route at line 85 modifies webhook configuration, so it should be protected by authentication middleware to prevent unauthorized changes.
Apply this diff:
- router.get(`/:phone/subscriptions`, phoneNumberController.getsubs.bind(phoneNumberController))
- router.post(`/:phone/subscriptions`, phoneNumberController.addsubs.bind(phoneNumberController))
+ router.get(`/:phone/subscriptions`, middleware, phoneNumberController.getsubs.bind(phoneNumberController))
+ router.post(`/:phone/subscriptions`, middleware, phoneNumberController.addsubs.bind(phoneNumberController))📝 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.
| router.get(`/:phone/subscriptions`, phoneNumberController.getsubs.bind(phoneNumberController)) | |
| router.post(`/:phone/subscriptions`, phoneNumberController.addsubs.bind(phoneNumberController)) | |
| router.get(`/:phone/subscriptions`, middleware, phoneNumberController.getsubs.bind(phoneNumberController)) | |
| router.post(`/:phone/subscriptions`, middleware, phoneNumberController.addsubs.bind(phoneNumberController)) |
🤖 Prompt for AI Agents
In src/router.ts around lines 84 to 85, the subscription GET and POST routes
currently omit the shared authentication/authorization middleware; update both
route declarations to include the existing middleware parameter as the second
argument (i.e., router.get('/:phone/subscriptions', middleware,
phoneNumberController.getsubs.bind(phoneNumberController)) and
router.post('/:phone/subscriptions', middleware,
phoneNumberController.addsubs.bind(phoneNumberController))) so the endpoints are
protected and consistent with other routes; ensure the middleware variable is in
scope where the routes are defined.
…_service add_contactEndpoint_on_web_service
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/defaults.ts(1 hunks)
🔇 Additional comments (1)
src/defaults.ts (1)
71-71: The default value is appropriate—no action needed.The WABA_ID default (
'WABA_UNOAPI') is used consistently as a compatibility identifier for fallback WABA account routes. It's referenced in route patterns (router.ts lines 79-80) and API responses (phone_number_controller.ts lines 94, 101) with clear, intentional naming. Production deployments can override this via theWABA_IDenvironment variable as designed.
| export const AMQP_URL = process.env.AMQP_URL || 'amqp://guest:guest@localhost:5672' | ||
| export const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379' | ||
| export const PROXY_URL = process.env.PROXY_URL | ||
| export const BUSINESS_ID = process.env.FB_ID || 'FB_UNOAPI' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Consider aligning the environment variable name with the constant name.
The environment variable FB_ID maps to the constant BUSINESS_ID, which could confuse developers during configuration. Additionally, the default value 'FB_UNOAPI' appears to be a placeholder. Since this constant is used in route patterns (per the PR summary), ensure that either:
- The default is appropriate for development/testing, or
- Validation is added to require this environment variable in production
Consider renaming the environment variable to BUSINESS_ID for consistency, or add a comment explaining the naming:
-export const BUSINESS_ID = process.env.FB_ID || 'FB_UNOAPI'
+// Maps to FB_ID environment variable for backward compatibility
+export const BUSINESS_ID = process.env.FB_ID || 'FB_UNOAPI'To verify whether this default value is validated elsewhere in the codebase:
🏁 Script executed:
#!/bin/bash
# Search for validation or usage of BUSINESS_ID to confirm if the default is safe
rg -n --type=ts -C3 'BUSINESS_ID' -g '!src/defaults.ts'Length of output: 1666
🏁 Script executed:
#!/bin/bash
# Search for validation of these environment variables or constants
rg -n --type=ts 'FB_ID|validate|process.env' src/defaults.ts -A 2 -B 2Length of output: 13763
🏁 Script executed:
#!/bin/bash
# Search for any validation or checks on BUSINESS_ID or WABA_ID values in the entire codebase
rg -n --type=ts '(BUSINESS_ID|WABA_ID|FB_ID)' -C 2 | rg -i 'validate|check|if.*BUSINESS_ID|if.*WABA_ID|if.*FB_ID' -C 3Length of output: 0
🏁 Script executed:
#!/bin/bash
# Check if there's a config validation file or startup validation
fd -e ts -g '*valid*' -g '*config*' -g '*startup*' -g '*init*' | head -20Length of output: 204
🏁 Script executed:
#!/bin/bash
# Look for comments explaining BUSINESS_ID usage
rg -n --type=ts 'BUSINESS_ID.*COMPATIBILITY|BUSINESS.*ID' -B 3 -A 3Length of output: 4612
🏁 Script executed:
#!/bin/bash
# Check the entire defaults.ts file to understand the context and patterns
cat src/defaults.tsLength of output: 15456
Add a comment explaining the naming mismatch and compatibility route purpose.
The environment variable FB_ID maps to the constant BUSINESS_ID due to a naming inconsistency, which could confuse developers during configuration. The defaults are used as literal route identifiers in compatibility routes (per the router comments), so they serve a functional purpose—but this design should be documented.
Suggested change:
-export const BUSINESS_ID = process.env.FB_ID || 'FB_UNOAPI'
-export const WABA_ID = process.env.WABA_ID || 'WABA_UNOAPI'
+// Routes identifiers for backward compatibility; FB_ID env var controls BUSINESS_ID for legacy naming reasons
+export const BUSINESS_ID = process.env.FB_ID || 'FB_UNOAPI'
+export const WABA_ID = process.env.WABA_ID || 'WABA_UNOAPI'🤖 Prompt for AI Agents
In src/defaults.ts around line 70, add an inline comment above the BUSINESS_ID
export that explains the naming mismatch (the environment var FB_ID is mapped to
the BUSINESS_ID constant for backwards compatibility) and state that this
constant is used as a literal route identifier in compatibility routes; mention
the expected env var name (FB_ID) and the default value ('FB_UNOAPI') so future
developers understand why the mapping exists and that changing the constant
affects route behavior.
Summary by CodeRabbit
New Features
Chores