From 3e55610d737b2594fabc24a93b91f352bedf6a11 Mon Sep 17 00:00:00 2001 From: Leandro Campos Date: Tue, 28 Jul 2026 15:21:00 -0300 Subject: [PATCH 1/2] feat: add WhatsApp BSUID recipient examples (NN-3681) --- README.md | 8 ++++++++ examples/send_whatsapp_template.lua | 16 ++++++++++++--- nvoip.lua | 31 ++++++++++++++++++++++++++++- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7c7eef1..d672e8d 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,14 @@ Enviar template de WhatsApp: lua examples/send_whatsapp_template.lua ``` +### Destinatário WhatsApp + +O exemplo mantém `NVOIP_WA_DESTINATION` para telefone. Para o contrato tipado, +use `NVOIP_WA_RECIPIENT_TYPE=phone|bsuid|parent_bsuid` e +`NVOIP_WA_RECIPIENT_VALUE`, sem `destination`. BSUID é opaco; não use +`@username` nem o coloque em campo de telefone. Exemplos mascarados: +`US.MASKED_BSUID_001` e `PARENT.MASKED_BSUID_001`. + ## Onde este repositório ajuda mais Lua é especialmente útil em cenários de automação e telefonia embarcada, como integrações com serviços e middlewares que já usam scripts leves para orquestração. diff --git a/examples/send_whatsapp_template.lua b/examples/send_whatsapp_template.lua index 0c33f5c..b08a79c 100644 --- a/examples/send_whatsapp_template.lua +++ b/examples/send_whatsapp_template.lua @@ -12,13 +12,23 @@ local oauth = client:create_access_token( assert(os.getenv("NVOIP_USER_TOKEN"), "NVOIP_USER_TOKEN is required") ) -local response = client:send_whatsapp_template({ +local recipient_type = os.getenv("NVOIP_WA_RECIPIENT_TYPE") +local options = { access_token = oauth.access_token, id_template = assert(os.getenv("NVOIP_WA_TEMPLATE_ID"), "NVOIP_WA_TEMPLATE_ID is required"), - destination = assert(os.getenv("NVOIP_WA_DESTINATION"), "NVOIP_WA_DESTINATION is required"), instance = assert(os.getenv("NVOIP_WA_INSTANCE"), "NVOIP_WA_INSTANCE is required"), language = os.getenv("NVOIP_WA_LANGUAGE") or "pt_BR", to_flow = (os.getenv("NVOIP_WA_TO_FLOW") or "false") == "true", -}) +} +if recipient_type then + options.recipient = { + type = recipient_type, + value = assert(os.getenv("NVOIP_WA_RECIPIENT_VALUE"), "NVOIP_WA_RECIPIENT_VALUE is required"), + } +else + options.destination = assert(os.getenv("NVOIP_WA_DESTINATION"), "NVOIP_WA_DESTINATION is required") +end + +local response = client:send_whatsapp_template(options) print(cjson.encode(response)) diff --git a/nvoip.lua b/nvoip.lua index e0cf5bf..8da4fff 100644 --- a/nvoip.lua +++ b/nvoip.lua @@ -154,10 +154,39 @@ end function Client:send_whatsapp_template(options) local payload = { idTemplate = options.id_template, - destination = options.destination, instance = options.instance, language = options.language, } + local recipient = options.recipient + if recipient ~= nil then + local recipient_type = string.lower(recipient.type or "") + local recipient_value = recipient.value or "" + if recipient_type ~= "phone" and recipient_type ~= "bsuid" and recipient_type ~= "parent_bsuid" then + error("recipient.type must be phone, bsuid or parent_bsuid", 2) + end + if recipient_value == "" or string.sub(recipient_value, 1, 1) == "@" then + error("recipient.value is required and @username is not accepted", 2) + end + local recipient_digits = string.gsub(recipient_value, "^%+", "") + if recipient_type == "phone" + and (not string.match(recipient_digits, "^%d+$") or #recipient_digits < 8 or #recipient_digits > 20) then + error("a phone recipient must contain only an optional leading + and 8 to 20 digits", 2) + end + if recipient_type ~= "phone" and (string.match(recipient_value, "%s") or #recipient_value > 256) then + error("a BSUID must be an opaque value without whitespace (maximum 256 characters)", 2) + end + if options.to_flow and recipient_type ~= "phone" then + error("WhatsApp Flow and attendance require a phone recipient", 2) + end + payload.recipient = { type = recipient_type, value = recipient_value } + else + local destination = options.destination or "" + local phone_digits = string.gsub(destination, "^%+", "") + if not string.match(phone_digits, "^%d+$") or #phone_digits < 8 or #phone_digits > 20 then + error("destination must be a phone number; use recipient for BSUID", 2) + end + payload.destination = options.destination + end if options.body_variables ~= nil then payload.bodyVariables = options.body_variables From af1489508f22066801e856c87693952783bb73ee Mon Sep 17 00:00:00 2001 From: Leandro Campos Date: Tue, 28 Jul 2026 15:35:36 -0300 Subject: [PATCH 2/2] chore: prepare Lua SDK release 0.1.1 --- nvoip-0.1.0-1.rockspec => nvoip-0.1.1-1.rockspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename nvoip-0.1.0-1.rockspec => nvoip-0.1.1-1.rockspec (93%) diff --git a/nvoip-0.1.0-1.rockspec b/nvoip-0.1.1-1.rockspec similarity index 93% rename from nvoip-0.1.0-1.rockspec rename to nvoip-0.1.1-1.rockspec index 0ff3e67..c8bf26b 100644 --- a/nvoip-0.1.0-1.rockspec +++ b/nvoip-0.1.1-1.rockspec @@ -1,9 +1,9 @@ package = "nvoip" -version = "0.1.0-1" +version = "0.1.1-1" source = { url = "git+https://github.com/Nvoip/nvoip-lua.git", - tag = "v0.1.0" + tag = "v0.1.1" } description = {