@omnizapi/connect 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +24 -13
- package/dist/cjs/index.js +11 -5
- package/dist/esm/index.mjs +11 -5
- package/dist/omnizapi.min.js +1 -1
- package/examples/vanilla.html +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.0.4] - 2026-09-11
|
|
4
|
+
|
|
5
|
+
### Correcao
|
|
6
|
+
|
|
7
|
+
- Eventos do Embedded Signup passam a ser aceitos de qualquer origem HTTPS em `facebook.com` ou subdominio (www, web, business). A allowlist exata de duas origens deixava a conexao nativa sem resposta quando o dialogo da Meta era servido de outro host, e a tentativa ficava aberta ate o timeout.
|
|
8
|
+
- `FINISH_ONLY_WABA` conclui a conexao sem numero de telefone, em vez de ser ignorado.
|
|
9
|
+
|
|
3
10
|
## [1.0.3] - 2026-09-11
|
|
4
11
|
|
|
5
12
|
### Correcao
|
package/README.md
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
SDK Omnizapi para conectar canais Meta WhatsApp, Messenger, Instagram, Telegram e Z-API WhatsApp em aplicacoes web. Coleta o resultado da autorizacao; seu backend valida e finaliza a conexao. Nao envie secret keys ao frontend.
|
|
4
4
|
|
|
5
|
-
Versao atual: **1.0.
|
|
5
|
+
Versao atual: **1.0.4**. As mudancas desta versao estao no [changelog](https://unpkg.com/browse/@omnizapi/connect@1.0.4/CHANGELOG.md), disponivel com o pacote publicado.
|
|
6
6
|
|
|
7
7
|
## Instalacao e importacao
|
|
8
|
-
|
|
8
|
+
eu
|
|
9
9
|
```bash
|
|
10
10
|
npm install @omnizapi/connect
|
|
11
11
|
```
|
|
@@ -31,7 +31,7 @@ CommonJS: `const { Omnizapi } = require("@omnizapi/connect")`.
|
|
|
31
31
|
No navegador, o bundle expoe o global `Omnizapi`:
|
|
32
32
|
|
|
33
33
|
```html
|
|
34
|
-
<script src="https://unpkg.com/@omnizapi/connect@1.0.
|
|
34
|
+
<script src="https://unpkg.com/@omnizapi/connect@1.0.4/dist/omnizapi.min.js"></script>
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
O CDN usa uma versao fixa; homologue sua integracao antes do deploy. Imports ESM/CommonJS e `newClient` sao seguros em SSR; `connect` exige navegador e rejeita com `BROWSER_REQUIRED` no servidor. O bundle de script e exclusivo do navegador.
|
|
@@ -44,15 +44,15 @@ Dispare `client.connect({ channelId })` diretamente no clique, sem outro `await`
|
|
|
44
44
|
|
|
45
45
|
| Exemplo | Uso |
|
|
46
46
|
| --- | --- |
|
|
47
|
-
| [TypeScript basico](https://unpkg.com/browse/@omnizapi/connect@1.0.
|
|
48
|
-
| [HTML com CDN](https://unpkg.com/browse/@omnizapi/connect@1.0.
|
|
49
|
-
| [React / Next.js](https://unpkg.com/browse/@omnizapi/connect@1.0.
|
|
50
|
-
| [Angular](https://unpkg.com/browse/@omnizapi/connect@1.0.
|
|
51
|
-
| [Vue](https://unpkg.com/browse/@omnizapi/connect@1.0.
|
|
52
|
-
| [Opcoes](https://unpkg.com/browse/@omnizapi/connect@1.0.
|
|
53
|
-
| [Erros](https://unpkg.com/browse/@omnizapi/connect@1.0.
|
|
47
|
+
| [TypeScript basico](https://unpkg.com/browse/@omnizapi/connect@1.0.4/examples/basic.ts) | Botao e mensagem de status no DOM |
|
|
48
|
+
| [HTML com CDN](https://unpkg.com/browse/@omnizapi/connect@1.0.4/examples/vanilla.html) | Pagina sem bundler |
|
|
49
|
+
| [React / Next.js](https://unpkg.com/browse/@omnizapi/connect@1.0.4/examples/react.tsx) | `'use client'`, UI de conexao por componente |
|
|
50
|
+
| [Angular](https://unpkg.com/browse/@omnizapi/connect@1.0.4/examples/angular.ts) | Componente com guarda de navegador para SSR |
|
|
51
|
+
| [Vue](https://unpkg.com/browse/@omnizapi/connect@1.0.4/examples/vue.vue) | SFC com guarda de navegador para SSR |
|
|
52
|
+
| [Opcoes](https://unpkg.com/browse/@omnizapi/connect@1.0.4/examples/with-options.ts) | SANDBOX, URLs explicitas, logo, fluxo padrao/direto e timeout |
|
|
53
|
+
| [Erros](https://unpkg.com/browse/@omnizapi/connect@1.0.4/examples/error-handling.ts) | Mensagens para todos os motivos e codigos tipados |
|
|
54
54
|
|
|
55
|
-
Os links abrem o codigo-fonte dos exemplos da versao 1.0.
|
|
55
|
+
Os links abrem o codigo-fonte dos exemplos da versao 1.0.4, incluido no pacote npm. Nao sao demos hospedadas: adapte as chaves, o canal e o backend na sua aplicacao.
|
|
56
56
|
|
|
57
57
|
Os arquivos `examples/error-handling.ts` e `examples/react.tsx` demonstram `AbortSignal`. No React, o cliente fica em `useRef`, e so e criado no `try` do clique; o cleanup de `useEffect` aborta a tentativa/requisicao pendente sem atualizar a UI desmontada. O exemplo de erros usa `Record<OmnizapiErrorCode, string>` exaustivo e permite cancelar apenas a autorizacao, nao a finalizacao no backend. Nao ha botao para limpar a quarentena nativa.
|
|
58
58
|
|
|
@@ -172,12 +172,23 @@ if (window.opener) {
|
|
|
172
172
|
}
|
|
173
173
|
```
|
|
174
174
|
|
|
175
|
-
O Meta Embedded Signup **nativo** nao fornece `attemptId` nem uma referencia customizada da janela emissora (`event.source`) para correlacao. Ele
|
|
175
|
+
O Meta Embedded Signup **nativo** nao fornece `attemptId` nem uma referencia customizada da janela emissora (`event.source`) para correlacao. Ele aceita eventos `WA_EMBEDDED_SIGNUP` de qualquer origem HTTPS em `facebook.com` ou subdominio (www, web, business), como a Meta orienta, e o callback `FB.login`. Os eventos `FINISH`, `FINISH_ONLY_WABA` e `FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING` concluem a conexao; `CANCEL` e `ERROR` a encerram. Nao se pode garantir o isolamento de eventos nativos tardios entre tentativas; essas verificacoes nao sao garantia absoluta de seguranca.
|
|
176
176
|
|
|
177
177
|
Um login nativo fica em quarentena ate a Meta responder o callback `FB.login` (com codigo, cancelamento ou erro) ou ate a tentativa ter sucesso. O callback, inclusive tardio, libera apenas a quarentena da tentativa a que pertence; nao libera a de outra tentativa. Fechar/cancelar o dialogo ou receber um evento de cancelamento nao garante que esse callback ja tenha chegado. Se um login terminar por timeout, abort ou cancelamento **sem callback**, novas tentativas nativas continuam em `CONNECTION_IN_PROGRESS`: aguarde o callback ou **recarregue a pagina** para tentar outro login nativo. Um callback recebido de cancelamento nao exige reload. Um `FB.login` que falha ao iniciar (excecao sincrona, sem abrir dialogo e sem callback futuro) libera a quarentena imediatamente, sem exigir reload. Essa restricao reduz o risco de atribuir a uma nova tentativa a resposta tardia de um dialogo anterior; nao se aplica aos popups proxy.
|
|
178
178
|
|
|
179
179
|
Durante uma tentativa, apenas `__omnizapiPublicKey`, `__omnizapiCurrentChannel` e `__omnizapiGetQrCode` sao publicados temporariamente para o frontend externo. Uma funcao QR no `window` da aplicacao nao atravessa origens nem e serializada por `postMessage`: o frontend precisa de uma integracao explicitamente autorizada e compativel com a politica de mesma origem. Este repositorio nao valida por si so o fluxo Z-API real nem confirma essa integracao externa.
|
|
180
180
|
|
|
181
|
+
## CSP da pagina que roda o login nativo
|
|
182
|
+
|
|
183
|
+
O `FB.login` conclui por um iframe oculto de `staticxx.facebook.com` na propria pagina. Se a sua pagina tem Content-Security-Policy e usa `direct: true`, libere:
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
script-src https://connect.facebook.net
|
|
187
|
+
frame-src https://www.facebook.com https://web.facebook.com https://business.facebook.com https://staticxx.facebook.com
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Sem o `frame-src` acima, o dialogo da Meta abre, o usuario conclui, e o dialogo fica preso em `dialog/oauth/business/cancel` sem devolver o resultado. Sem `direct`, o login roda no frontend de conexao da plataforma e a sua pagina nao precisa de nada disso.
|
|
191
|
+
|
|
181
192
|
## App da Meta proprio (`appCustom`)
|
|
182
193
|
|
|
183
194
|
Por padrao o canal usa o app da Meta da plataforma, e a Meta so enxerga o `frontUrl` (`app.hubmessage.io` ou `app.omni.z-api.io`): o login do WhatsApp e o retorno do OAuth do Messenger e do Instagram acontecem na janela da plataforma. Nesse caso o seu dominio nao precisa de nada na Meta, so na allowlist de origens do canal.
|
|
@@ -240,4 +251,4 @@ O hook de versao `scripts/sync-version.mjs` sincroniza os links UNPKG e scripts
|
|
|
240
251
|
|
|
241
252
|
## Licenca
|
|
242
253
|
|
|
243
|
-
MIT - Copyright (c) 2026 FourPixel IT. Autor: FourPixel IT. Texto completo no arquivo local `LICENSE` e na [licenca do pacote](https://unpkg.com/browse/@omnizapi/connect@1.0.
|
|
254
|
+
MIT - Copyright (c) 2026 FourPixel IT. Autor: FourPixel IT. Texto completo no arquivo local `LICENSE` e na [licenca do pacote](https://unpkg.com/browse/@omnizapi/connect@1.0.4/LICENSE) apos a publicacao correspondente.
|
package/dist/cjs/index.js
CHANGED
|
@@ -387,6 +387,15 @@ function encodeChannelId(channelId) {
|
|
|
387
387
|
throw new OmnizapiError("INVALID_OPTIONS", "The channelId cannot be encoded as a URL path.");
|
|
388
388
|
}
|
|
389
389
|
}
|
|
390
|
+
function isFacebookOrigin(origin) {
|
|
391
|
+
let url;
|
|
392
|
+
try {
|
|
393
|
+
url = new URL(origin);
|
|
394
|
+
} catch (e) {
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
397
|
+
return url.protocol === "https:" && (url.hostname === "facebook.com" || url.hostname.endsWith(".facebook.com"));
|
|
398
|
+
}
|
|
390
399
|
function isChannelType(value) {
|
|
391
400
|
return [
|
|
392
401
|
"META_MESSENGER",
|
|
@@ -747,10 +756,7 @@ var OmnizapiClientImpl = class {
|
|
|
747
756
|
succeed({ code, wabaId, phoneId, coexistence });
|
|
748
757
|
};
|
|
749
758
|
messageListener = (event) => {
|
|
750
|
-
if (!isLive() || !
|
|
751
|
-
"https://www.facebook.com",
|
|
752
|
-
"https://web.facebook.com"
|
|
753
|
-
].includes(event.origin)) return;
|
|
759
|
+
if (!isLive() || !isFacebookOrigin(event.origin)) return;
|
|
754
760
|
let data = event.data;
|
|
755
761
|
if (typeof data === "string") {
|
|
756
762
|
try {
|
|
@@ -764,7 +770,7 @@ var OmnizapiClientImpl = class {
|
|
|
764
770
|
fail("cancelled");
|
|
765
771
|
} else if (data.event === "ERROR") {
|
|
766
772
|
finish(new OmnizapiError("PROVIDER_ERROR", "Meta could not complete the connection."));
|
|
767
|
-
} else if (data.event === "FINISH" || data.event === "FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING") {
|
|
773
|
+
} else if (data.event === "FINISH" || data.event === "FINISH_ONLY_WABA" || data.event === "FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING") {
|
|
768
774
|
if (!isRecord(data.data) || !stringOrNull(data.data.waba_id) || data.data.phone_number_id != null && typeof data.data.phone_number_id !== "string") return;
|
|
769
775
|
wabaId = stringOrNull(data.data.waba_id);
|
|
770
776
|
phoneId = stringOrNull(data.data.phone_number_id);
|
package/dist/esm/index.mjs
CHANGED
|
@@ -358,6 +358,15 @@ function encodeChannelId(channelId) {
|
|
|
358
358
|
throw new OmnizapiError("INVALID_OPTIONS", "The channelId cannot be encoded as a URL path.");
|
|
359
359
|
}
|
|
360
360
|
}
|
|
361
|
+
function isFacebookOrigin(origin) {
|
|
362
|
+
let url;
|
|
363
|
+
try {
|
|
364
|
+
url = new URL(origin);
|
|
365
|
+
} catch (e) {
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
return url.protocol === "https:" && (url.hostname === "facebook.com" || url.hostname.endsWith(".facebook.com"));
|
|
369
|
+
}
|
|
361
370
|
function isChannelType(value) {
|
|
362
371
|
return [
|
|
363
372
|
"META_MESSENGER",
|
|
@@ -718,10 +727,7 @@ var OmnizapiClientImpl = class {
|
|
|
718
727
|
succeed({ code, wabaId, phoneId, coexistence });
|
|
719
728
|
};
|
|
720
729
|
messageListener = (event) => {
|
|
721
|
-
if (!isLive() || !
|
|
722
|
-
"https://www.facebook.com",
|
|
723
|
-
"https://web.facebook.com"
|
|
724
|
-
].includes(event.origin)) return;
|
|
730
|
+
if (!isLive() || !isFacebookOrigin(event.origin)) return;
|
|
725
731
|
let data = event.data;
|
|
726
732
|
if (typeof data === "string") {
|
|
727
733
|
try {
|
|
@@ -735,7 +741,7 @@ var OmnizapiClientImpl = class {
|
|
|
735
741
|
fail("cancelled");
|
|
736
742
|
} else if (data.event === "ERROR") {
|
|
737
743
|
finish(new OmnizapiError("PROVIDER_ERROR", "Meta could not complete the connection."));
|
|
738
|
-
} else if (data.event === "FINISH" || data.event === "FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING") {
|
|
744
|
+
} else if (data.event === "FINISH" || data.event === "FINISH_ONLY_WABA" || data.event === "FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING") {
|
|
739
745
|
if (!isRecord(data.data) || !stringOrNull(data.data.waba_id) || data.data.phone_number_id != null && typeof data.data.phone_number_id !== "string") return;
|
|
740
746
|
wabaId = stringOrNull(data.data.waba_id);
|
|
741
747
|
phoneId = stringOrNull(data.data.phone_number_id);
|
package/dist/omnizapi.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";(()=>{var o=class extends Error{constructor(n,e){super(e);this.code=n;this.name="OmnizapiError"}};var ue={PRODUCTION:{api:"https://api.omni.z-api.io",front:"https://app.omni.z-api.io"},STAGING:{api:"https://api.staging.omni.z-api.io",front:"https://app.staging.omni.z-api.io"},SANDBOX:{api:"",front:""}},fe=({environment:r="PRODUCTION",apiUrl:t,frontUrl:n}={})=>{if(!Object.prototype.hasOwnProperty.call(ue,r))throw new o("INVALID_CONFIGURATION","Unknown environment.");let e=ue[r],a={api:t!=null?t:e.api,front:n!=null?n:e.front};for(let s of["api","front"]){let c;try{c=new URL(a[s])}catch(f){throw new o("INVALID_CONFIGURATION",`A valid ${s}Url is required for this environment.`)}if(!["http:","https:"].includes(c.protocol)||c.username||c.password||c.href.includes("?")||c.href.includes("#"))throw new o("INVALID_CONFIGURATION",`${s}Url must be an HTTP(S) base URL without credentials, query or fragment.`);a[s]=c.href.replace(/\/+$/,"")}return a};var pe=Symbol.for("omnizapi.connect.runtime.v1");function j(r){var e,a,s;let t=r,n=t[pe];return n||(n={nativeLoginPending:!1,failedFacebookScripts:new WeakSet,erroredFacebookScripts:new WeakSet,facebookAppIds:new WeakMap,facebookInitObservers:new WeakMap},Object.defineProperty(t,pe,{configurable:!0,value:n})),(e=n.facebookAppIds)!=null||(n.facebookAppIds=new WeakMap),(a=n.facebookInitObservers)!=null||(n.facebookInitObservers=new WeakMap),(s=n.erroredFacebookScripts)!=null||(n.erroredFacebookScripts=new WeakSet),n}function he(r){return!!r&&!("__buffer"in r)&&typeof r.init=="function"&&typeof r.login=="function"}function be(r,t){var n;try{let e=Object.getOwnPropertyDescriptor(t,"init"),a=r.facebookInitObservers.get(t);if(a){if((e==null?void 0:e.value)!==a.init)throw new Error("FB.init was replaced.");return a}if(!e||typeof e.value!="function"||!e.writable&&!e.configurable)throw new Error("FB.init cannot be observed.");let s=e.value,c={calls:0,init:function(...f){return c.calls++,r.facebookAppIds.delete(t),Reflect.apply(s,this,f)}};if(Object.defineProperty(t,"init",{...e,value:c.init}),((n=Object.getOwnPropertyDescriptor(t,"init"))==null?void 0:n.value)!==c.init)throw new Error("FB.init was not replaced.");return r.facebookInitObservers.set(t,c),c}catch(e){throw r.facebookAppIds.delete(t),new o("INVALID_CONFIGURATION","The Meta SDK initialization cannot be observed safely. Use the popup flow or reload a fresh page.")}}function Ie(r,t,n){var f;if(r.FB!==t||!t||"__buffer"in t||typeof t.login!="function")throw new o("INVALID_CONFIGURATION","The Meta SDK is not ready or was replaced before initialization.");if(typeof n!="string"||!/^[0-9]+$/.test(n))throw new o("INVALID_CONFIGURATION","A numeric Meta appId is required for native login.");let e=j(r);e.facebookAppIds.get(t)===null&&(e.facebookLoadUncertain||e.facebookLoading||typeof r.fbAsyncInit=="function")&&e.facebookAppIds.delete(t);let a=e.facebookAppIds.get(t);if(a===void 0||a!==null&&!e.facebookInitObservers.has(t))throw e.facebookAppIds.delete(t),new o("INVALID_CONFIGURATION","The host Meta SDK configuration is unknown. Use the popup flow or a fresh page without a host-initialized SDK for native login.");let s=be(e,t);if(a!==null){if(a!==n)throw new o("INVALID_CONFIGURATION","The Meta SDK is already initialized for another app. Use the popup flow or reload a fresh page before changing apps.");return}let c=s.calls;e.facebookAppIds.delete(t);try{t.init({appId:n,version:"v25.0",autoLogAppEvents:!0,xfbml:!0})}catch(p){throw new o("PROVIDER_ERROR","The Meta SDK could not be initialized.")}if(s.calls!==c+1||r.FB!==t||((f=Object.getOwnPropertyDescriptor(t,"init"))==null?void 0:f.value)!==s.init)throw new o("INVALID_CONFIGURATION","The Meta SDK changed during initialization. Use the popup flow or reload a fresh page.");e.facebookAppIds.set(t,n)}function me(r,t){if(t.aborted)return Promise.reject(new o("SDK_LOAD_FAILED","The Meta SDK load was cancelled."));let n=j(r),e=n.facebookLoadObserver;if(!e&&he(r.FB)&&(e={promise:Promise.resolve(r.FB),consumers:0}),!e){let s={consumers:0,promise:Promise.resolve().then(()=>new Promise((c,f)=>{var h;let p=!1,i,_=!1,g=!1,b,D,M,z=(u,l,y=!1)=>{if(!p){p=!0,clearTimeout(F),i==null||i.removeEventListener("load",P),i==null||i.removeEventListener("error",V);try{r.fbAsyncInit===K&&(D?Object.defineProperty(r,"fbAsyncInit",D):Reflect.deleteProperty(r,"fbAsyncInit"))}catch(L){}if(l&&i&&(n.failedFacebookScripts.add(i),y?n.erroredFacebookScripts.add(i):_||(n.facebookLoadUncertain=!0),_))try{i.remove()}catch(L){}n.facebookLoadObserver===s&&delete n.facebookLoadObserver,u?c(u):f(l)}},P=()=>{var y;if(p)return;let u=r.FB;if(!u)return;"__buffer"in u&&(b=u),(((y=b==null?void 0:b.__buffer)==null?void 0:y.opts)!=null||r.fbAsyncInit!==K||i!=null&&i.onload||n.facebookLoading||n.facebookLoadUncertain)&&(g=!1,n.facebookAppIds.get(u)===null&&n.facebookAppIds.delete(u),b&&n.facebookAppIds.get(b)===null&&n.facebookAppIds.delete(b));let l=he(u);if(g&&n.facebookAppIds.get(u)==null){if(!l)n.facebookAppIds.set(u,null);else if(!n.facebookInitObservers.has(u))try{be(n,u),n.facebookAppIds.set(u,null)}catch(L){}}l&&z(u)},V=()=>z(void 0,new o("SDK_LOAD_FAILED","The Meta SDK could not be loaded."),!0),K=()=>{if(!p){try{M==null||M.call(r)}catch(u){}P()}},F=setTimeout(()=>z(void 0,new o("SDK_LOAD_FAILED","The Meta SDK load timed out.")),30*1e3);s.cancelIfUnused=()=>{_&&s.consumers===0&&z(void 0,new o("SDK_LOAD_FAILED","The Meta SDK load was cancelled."))};try{D=Object.getOwnPropertyDescriptor(r,"fbAsyncInit"),M=typeof r.fbAsyncInit=="function"?r.fbAsyncInit:void 0;let u=r.document,l=u.getElementById("facebook-jssdk");if(i=Array.from(u.scripts).find(y=>{try{let L=new URL(y.src);return L.origin!=="https://connect.facebook.net"||!/^\/[^/]+\/sdk\.js$/.test(L.pathname)?!1:n.failedFacebookScripts.has(y)?(n.erroredFacebookScripts.has(y)||(n.facebookLoadUncertain=!0),!1):!0}catch(L){return!1}}),!i){i=u.createElement("script"),_=!0;let y=r.FB;y&&"__buffer"in y&&(b=y),g=!n.facebookLoadUncertain&&!n.facebookLoading&&!M&&(!y||!!b&&n.facebookAppIds.get(y)===null&&((h=b.__buffer)==null?void 0:h.opts)==null),l||(i.id="facebook-jssdk"),i.src="https://connect.facebook.net/en_US/sdk.js",i.crossOrigin="anonymous",i.async=!0,i.defer=!0}if(s.cancelIfUnused(),p)return;Object.defineProperty(r,"fbAsyncInit",D&&!D.configurable?{value:K}:{configurable:!0,enumerable:!0,writable:!0,value:K}),i.addEventListener("load",P),i.addEventListener("error",V),P(),!p&&_&&u.head.appendChild(i)}catch(u){z(void 0,new o("SDK_LOAD_FAILED","The Meta SDK could not be loaded."))}}))};n.facebookLoadObserver=e=s}let a=e;return new Promise((s,c)=>{let f=!1;a.consumers++;let p=(_,g)=>{var b;f||(f=!0,t.removeEventListener("abort",i),a.consumers--,_?s(_):c(g),(b=a.cancelIfUnused)==null||b.call(a))},i=()=>p(void 0,new o("SDK_LOAD_FAILED","The Meta SDK load was cancelled."));a.promise.then(_=>t.aborted?i():p(_),_=>p(void 0,new o("SDK_LOAD_FAILED",_.message))),t.addEventListener("abort",i,{once:!0}),t.aborted&&i()})}var we=(r,t,n=600,e=700)=>{let a=window,s=a.document,c=a.screenLeft!==void 0?a.screenLeft:a.screenX,f=a.screenTop!==void 0?a.screenTop:a.screenY,p=a.innerWidth?a.innerWidth:s.documentElement.clientWidth?s.documentElement.clientWidth:a.screen.width,i=a.innerHeight?a.innerHeight:s.documentElement.clientHeight?s.documentElement.clientHeight:a.screen.height,_=p/2-n/2+c,g=i/2-e/2+f;return a.open(r,t,`scrollbars=yes, width=${n}, height=${e}, top=${g}, left=${_}`)};var Se=600*1e3,ve=30*1e3;function v(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function O(r){return typeof r=="string"&&r.trim()?r:null}function Oe(r){if(r==="."||r==="..")throw new o("INVALID_OPTIONS","The channelId cannot be a URL path navigation segment.");try{return encodeURIComponent(r)}catch(t){throw new o("INVALID_OPTIONS","The channelId cannot be encoded as a URL path.")}}function Pe(r){return["META_MESSENGER","META_INSTAGRAM","META_WHATSAPP","BOT_TELEGRAM","Z_API_WHATSAPP"].includes(r)}function ge(r){return typeof r=="string"&&["cancelled","popup_closed","not_completed","invalid_channel","origin_not_allowed","unsupported_channel"].includes(r)}function Y(r,t,n){return{success:!1,reason:n,channelId:r,type:t,code:null,wabaId:null,phoneId:null}}function Ae(r,t,n){return typeof fetch!="function"||typeof AbortController!="function"?Promise.reject(new o("INVALID_CONFIGURATION","Fetch and AbortController are required.")):new Promise((e,a)=>{let s=new AbortController,c=!1,f=(g,b)=>{c||(c=!0,clearTimeout(i),n==null||n.removeEventListener("abort",p),s.abort(),b?a(b):e(g))},p=()=>f(void 0,new o("ABORTED","The API request was aborted.")),i=setTimeout(()=>f(void 0,new o("TIMEOUT","The API request timed out.")),ve);if(n==null||n.addEventListener("abort",p,{once:!0}),n!=null&&n.aborted){p();return}(async()=>{let g;try{g=await fetch(r.href,{...t,signal:s.signal})}catch(b){f(void 0,new o("NETWORK_ERROR","The API request failed."));return}if(!c){if(!g||typeof g.ok!="boolean"){f(void 0,new o("INVALID_RESPONSE","The API response is invalid."));return}if(!g.ok){f(void 0,new o("HTTP_ERROR","The API returned an unsuccessful status."));return}try{let b=await g.json();c||f(b)}catch(b){f(void 0,new o("INVALID_RESPONSE","The API did not return valid JSON."))}}})().catch(()=>f(void 0,new o("NETWORK_ERROR","The API request failed.")))})}var ee=class{constructor(t){if(!v(t)||!O(t.publicKey)||Array.from(t.publicKey).some(n=>{let e=n.charCodeAt(0);return e<32||e===127})||t.logo!==void 0&&typeof t.logo!="string"||t.apiUrl!==void 0&&!O(t.apiUrl)||t.frontUrl!==void 0&&!O(t.frontUrl))throw new o("INVALID_CONFIGURATION","Valid client properties and a publicKey are required.");this.publicKey=t.publicKey,this.logo=t.logo,this.constants=fe({environment:t.environment,apiUrl:t.apiUrl,frontUrl:t.frontUrl})}async getListMessengerPages(t,n,e){if(!O(t)||!O(n))throw new o("INVALID_OPTIONS","A channelId and authorization code are required.");if(e!==void 0&&(!v(e)||typeof e.aborted!="boolean"||typeof e.addEventListener!="function"||typeof e.removeEventListener!="function"))throw new o("INVALID_OPTIONS","The abort signal is invalid.");if(e!=null&&e.aborted)throw new o("ABORTED","The API request was aborted.");return Ae(new URL(`${this.constants.api}/v1/channels/${Oe(t)}/list-messenger-pages`),{method:"POST",body:JSON.stringify({redirectUri:new URL(`${this.constants.front}/oauth/proxy-messenger`).href,code:n}),headers:{"Content-Type":"application/json",Authorization:this.publicKey}},e)}async connect(t){var n;try{if(typeof window=="undefined"||!window.document||!window.location)throw new o("BROWSER_REQUIRED","Connecting requires a browser window.");let e=window,a=j(e);if(a.activeConnection)throw new o("CONNECTION_IN_PROGRESS","A connection is already in progress in this window.");if(!v(t))throw new o("INVALID_OPTIONS","Connection options are required.");let{channelId:s,direct:c,getQRCode:f,timeoutMs:p=Se,signal:i}=t;if(typeof s!="string"||c!==void 0&&typeof c!="boolean"||f!==void 0&&typeof f!="function"||typeof p!="number"||!Number.isFinite(p)||p<=0||p>2147483647||i!==void 0&&(!v(i)||typeof i.aborted!="boolean"||typeof i.addEventListener!="function"||typeof i.removeEventListener!="function"))throw new o("INVALID_OPTIONS","Invalid channelId, direct, getQRCode, timeoutMs or signal option.");if(i!=null&&i.aborted)throw new o("ABORTED","The connection was aborted.");if(!s.trim())return Y(s,null,"invalid_channel");let _=Oe(s);if(typeof e.open!="function"||typeof e.addEventListener!="function"||typeof e.removeEventListener!="function"||typeof e.location.origin!="string"||typeof e.location.href!="string"||typeof((n=e.crypto)==null?void 0:n.getRandomValues)!="function"||typeof AbortController!="function"||typeof fetch!="function")throw new o("INVALID_CONFIGURATION","Required browser APIs are unavailable.");let g=e.location.origin;if(g==="null")return Y(s,null,"origin_not_allowed");let b=e.location.href,D=new URL(this.constants.front).origin;return await new Promise((M,z)=>{let P=Symbol("omnizapi-connection"),V=new AbortController,K=Date.now()+p,F=!1,h=null,u=null,l=null,y,L,x,W,q=!1,Q=!1,J=()=>{a.nativeLoginOwner===P&&(a.nativeLoginPending=!1,delete a.nativeLoginOwner)},te=[],E=d=>{if(F)return;F=!0,clearTimeout(L),clearInterval(x);try{i==null||i.removeEventListener("abort",X)}catch(U){}if(W)try{e.removeEventListener("message",W)}catch(U){}try{V.abort()}catch(U){}let G=l;l=null;try{G==null||G.close()}catch(U){}for(let{name:U,previous:I,value:C}of te)try{let k=Object.getOwnPropertyDescriptor(e,U);if(!k||!("value"in k)||k.value!==C)continue;I?Object.defineProperty(e,U,I):Reflect.deleteProperty(e,U)}catch(k){}a.activeConnection===P&&delete a.activeConnection,q&&(Q||!(d instanceof o)&&d.success)&&J(),d instanceof o?z(d):M(d)},X=()=>E(new o("ABORTED","The connection was aborted.")),T=()=>(!F&&(i!=null&&i.aborted)&&X(),!F&&Date.now()>=K&&E(new o("TIMEOUT","The connection timed out.")),!F),N=d=>E(Y(s,h,d)),oe=()=>{try{let d=we("about:blank","_blank",600,740);if(!d||d===e)throw new Error("Popup unavailable");if(!T()){d.close();return}l=d}catch(d){throw new o("POPUP_BLOCKED","The connection popup could not be opened.")}},Re=()=>{x||(x=setInterval(()=>{if(T())try{l!=null&&l.closed&&N("popup_closed")}catch(d){E(new o("PROVIDER_ERROR","The connection popup could not be monitored."))}},500))},Te=()=>{clearInterval(x),x=void 0},re=d=>{!T()||!h||E({success:!0,channelId:s,type:h,code:O(d.code),wabaId:O(d.wabaId),phoneId:O(d.phoneId),coexistence:d.coexistence===!0,redirectUri:u,botToken:O(d.botToken),pageId:O(d.pageId),accessToken:O(d.accessToken)})};try{if(a.activeConnection=P,i==null||i.addEventListener("abort",X,{once:!0}),!T())return;let d=e.crypto.getRandomValues(new Uint8Array(16)),G=Array.from(d,I=>I.toString(16).padStart(2,"0")).join("");for(let[I,C]of[["__omnizapiPublicKey",this.publicKey],["__omnizapiCurrentChannel",s],["__omnizapiGetQrCode",f]]){let k=Object.getOwnPropertyDescriptor(e,I);Object.defineProperty(e,I,k&&!k.configurable?{value:C}:{configurable:!0,enumerable:!0,writable:!0,value:C}),te.push({name:I,previous:k,value:C})}if(L=setTimeout(()=>E(new o("TIMEOUT","The connection timed out.")),p),!c)try{oe()}catch(I){y=I instanceof o?I:new o("POPUP_BLOCKED","The connection popup could not be opened.")}if(!T())return;(async()=>{var ae,se,ce;let I=await Ae(new URL(`${this.constants.api}/instances/${_}/sdk-info`),{headers:{Authorization:this.publicKey,"Content-Type":"application/json"}},V.signal);if(!T())return;if(!v(I)||!O(I.middleware))throw new o("INVALID_RESPONSE","The channel configuration is invalid.");let C=(ae=I.allowOrigins)!=null?ae:[];if(!Array.isArray(C)||!C.every(w=>typeof w=="string"))throw new o("INVALID_RESPONSE","The channel origins are invalid.");let k=I.middleware;if(h=Pe(k)?k:null,g!==D&&!C.some(w=>{try{return g===new URL(w).origin}catch(m){return!1}})){N("origin_not_allowed");return}if(!h){N("unsupported_channel");return}let H=(se=O(h==="META_INSTAGRAM"?I.appInstagramId:I.appId))!=null?se:"",Z=(ce=O(I.appConfig))!=null?ce:"";if(h.startsWith("META_")&&!H||h==="META_WHATSAPP"&&!Z)throw new o("INVALID_RESPONSE","The channel provider configuration is invalid.");let ke=h==="META_WHATSAPP"&&c===!0,ie=!1,$;if(ke){if(Te(),a.nativeLoginPending)throw new o("CONNECTION_IN_PROGRESS","A previous Meta login is incomplete. Reload this window before retrying a native login.");if($=await me(e,V.signal),!T())return;try{Ie(e,$,H),ie=!0}catch(w){if(!(w instanceof o&&w.code==="INVALID_CONFIGURATION"))throw w}if(!T())return}if(ie&&$){l==null||l.close(),l=null;let w=null,m=null,B=null,le=!1,de=()=>{!T()||!w||!m||re({code:w,wabaId:m,phoneId:B,coexistence:le})};W=S=>{if(!T()||!["https://www.facebook.com","https://web.facebook.com"].includes(S.origin))return;let R=S.data;if(typeof R=="string")try{R=JSON.parse(R)}catch(Le){return}if(!(!v(R)||R.type!=="WA_EMBEDDED_SIGNUP")){if(R.event==="CANCEL")N("cancelled");else if(R.event==="ERROR")E(new o("PROVIDER_ERROR","Meta could not complete the connection."));else if(R.event==="FINISH"||R.event==="FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING"){if(!v(R.data)||!O(R.data.waba_id)||R.data.phone_number_id!=null&&typeof R.data.phone_number_id!="string")return;m=O(R.data.waba_id),B=O(R.data.phone_number_id),le=R.event==="FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING",de()}}},e.addEventListener("message",W),a.nativeLoginPending=!0,a.nativeLoginOwner=P,q=!0;try{$.login(S=>{if(!Q){if(Q=!0,F){J();return}if(T()){if(!v(S)||S.error){E(new o("PROVIDER_ERROR","Meta returned an invalid login response."));return}if(S.authResponse==null){N("not_completed");return}if(!v(S.authResponse)||!O(S.authResponse.code)){N("not_completed");return}w=O(S.authResponse.code),de()}}},{config_id:Z,response_type:"code",override_default_response_type:!0,extras:{setup:{},featureType:"whatsapp_business_app_onboarding",sessionInfoVersion:"3"}})}catch(S){throw J(),q=!1,new o("PROVIDER_ERROR","The Meta login could not be started.")}return}let A;if(h==="META_MESSENGER"||h==="META_INSTAGRAM"){let w=h==="META_MESSENGER";u=new URL(`${this.constants.front}/oauth/proxy-${w?"messenger":"instagram"}`).href,A=new URL(w?"https://www.facebook.com/dialog/oauth":"https://www.instagram.com/oauth/authorize"),A.searchParams.set("client_id",H),w&&A.searchParams.set("display","popup"),A.searchParams.set("redirect_uri",u),A.searchParams.set("response_type","code"),A.searchParams.set("scope",w?"public_profile,business_management,pages_messaging,pages_show_list,pages_manage_metadata,pages_read_engagement":"instagram_business_basic,instagram_business_manage_messages"),A.searchParams.set("state",JSON.stringify({currentUrl:b,attemptId:G,channelId:s}))}else h==="META_WHATSAPP"?(A=new URL(`${this.constants.front}/oauth/proxy-cloud-api`),A.searchParams.set("configId",Z),A.searchParams.set("appId",H),A.searchParams.set("channelId",s),A.searchParams.set("channelType",h),A.searchParams.set("logo",this.logo||new URL(`${this.constants.front}/logos/SVG/Ativo%2016.svg`).href),A.searchParams.set("pk",this.publicKey)):(A=new URL(`${this.constants.front}/connect/${h==="BOT_TELEGRAM"?"telegram":"whatsapp-web"}`),A.searchParams.set("channelId",s),A.searchParams.set("pk",this.publicKey));if(h!=="META_MESSENGER"&&h!=="META_INSTAGRAM"&&A.searchParams.set("attemptId",G),W=w=>{if(!T()||!l||w.origin!==D||w.source!==l)return;let m=w.data;!v(m)||m.type!=="after-connect"||m.attemptId!==G||m.channelId!==s||typeof m.success!="boolean"||m.reason!==void 0&&!ge(m.reason)||m.coexistence!==void 0&&typeof m.coexistence!="boolean"||["code","wabaId","phoneId","botToken","pageId","accessToken","redirectUri"].some(B=>m[B]!=null&&typeof m[B]!="string")||(m.success?h!=null&&h.startsWith("META_")&&!O(m.code)||h==="BOT_TELEGRAM"&&!O(m.botToken)?N("not_completed"):re(m):N(ge(m.reason)?m.reason:"not_completed"))},e.addEventListener("message",W),!!T()){if(y)throw y;if(l||oe(),l!=null&&l.closed){N("popup_closed");return}Re();try{l==null||l.location.replace(A.href)}catch(w){throw new o("PROVIDER_ERROR","The connection popup could not be navigated.")}}})().catch(I=>{T()&&E(I instanceof o?I:new o("PROVIDER_ERROR","The connection could not be completed."))})}catch(d){E(d instanceof o?d:new o("INVALID_CONFIGURATION","The connection could not be initialized."))}})}catch(e){throw e instanceof o?e:new o("INVALID_OPTIONS","The connection could not be started with these options.")}}},ye=ee;var ne=class{static newClient(t){return new ye(t)}};var _e=ne;Object.assign(window,{Omnizapi:_e});})();
|
|
1
|
+
"use strict";(()=>{var o=class extends Error{constructor(n,e){super(e);this.code=n;this.name="OmnizapiError"}};var ue={PRODUCTION:{api:"https://api.omni.z-api.io",front:"https://app.omni.z-api.io"},STAGING:{api:"https://api.staging.omni.z-api.io",front:"https://app.staging.omni.z-api.io"},SANDBOX:{api:"",front:""}},fe=({environment:r="PRODUCTION",apiUrl:t,frontUrl:n}={})=>{if(!Object.prototype.hasOwnProperty.call(ue,r))throw new o("INVALID_CONFIGURATION","Unknown environment.");let e=ue[r],a={api:t!=null?t:e.api,front:n!=null?n:e.front};for(let s of["api","front"]){let c;try{c=new URL(a[s])}catch(f){throw new o("INVALID_CONFIGURATION",`A valid ${s}Url is required for this environment.`)}if(!["http:","https:"].includes(c.protocol)||c.username||c.password||c.href.includes("?")||c.href.includes("#"))throw new o("INVALID_CONFIGURATION",`${s}Url must be an HTTP(S) base URL without credentials, query or fragment.`);a[s]=c.href.replace(/\/+$/,"")}return a};var pe=Symbol.for("omnizapi.connect.runtime.v1");function j(r){var e,a,s;let t=r,n=t[pe];return n||(n={nativeLoginPending:!1,failedFacebookScripts:new WeakSet,erroredFacebookScripts:new WeakSet,facebookAppIds:new WeakMap,facebookInitObservers:new WeakMap},Object.defineProperty(t,pe,{configurable:!0,value:n})),(e=n.facebookAppIds)!=null||(n.facebookAppIds=new WeakMap),(a=n.facebookInitObservers)!=null||(n.facebookInitObservers=new WeakMap),(s=n.erroredFacebookScripts)!=null||(n.erroredFacebookScripts=new WeakSet),n}function he(r){return!!r&&!("__buffer"in r)&&typeof r.init=="function"&&typeof r.login=="function"}function be(r,t){var n;try{let e=Object.getOwnPropertyDescriptor(t,"init"),a=r.facebookInitObservers.get(t);if(a){if((e==null?void 0:e.value)!==a.init)throw new Error("FB.init was replaced.");return a}if(!e||typeof e.value!="function"||!e.writable&&!e.configurable)throw new Error("FB.init cannot be observed.");let s=e.value,c={calls:0,init:function(...f){return c.calls++,r.facebookAppIds.delete(t),Reflect.apply(s,this,f)}};if(Object.defineProperty(t,"init",{...e,value:c.init}),((n=Object.getOwnPropertyDescriptor(t,"init"))==null?void 0:n.value)!==c.init)throw new Error("FB.init was not replaced.");return r.facebookInitObservers.set(t,c),c}catch(e){throw r.facebookAppIds.delete(t),new o("INVALID_CONFIGURATION","The Meta SDK initialization cannot be observed safely. Use the popup flow or reload a fresh page.")}}function Ie(r,t,n){var f;if(r.FB!==t||!t||"__buffer"in t||typeof t.login!="function")throw new o("INVALID_CONFIGURATION","The Meta SDK is not ready or was replaced before initialization.");if(typeof n!="string"||!/^[0-9]+$/.test(n))throw new o("INVALID_CONFIGURATION","A numeric Meta appId is required for native login.");let e=j(r);e.facebookAppIds.get(t)===null&&(e.facebookLoadUncertain||e.facebookLoading||typeof r.fbAsyncInit=="function")&&e.facebookAppIds.delete(t);let a=e.facebookAppIds.get(t);if(a===void 0||a!==null&&!e.facebookInitObservers.has(t))throw e.facebookAppIds.delete(t),new o("INVALID_CONFIGURATION","The host Meta SDK configuration is unknown. Use the popup flow or a fresh page without a host-initialized SDK for native login.");let s=be(e,t);if(a!==null){if(a!==n)throw new o("INVALID_CONFIGURATION","The Meta SDK is already initialized for another app. Use the popup flow or reload a fresh page before changing apps.");return}let c=s.calls;e.facebookAppIds.delete(t);try{t.init({appId:n,version:"v25.0",autoLogAppEvents:!0,xfbml:!0})}catch(p){throw new o("PROVIDER_ERROR","The Meta SDK could not be initialized.")}if(s.calls!==c+1||r.FB!==t||((f=Object.getOwnPropertyDescriptor(t,"init"))==null?void 0:f.value)!==s.init)throw new o("INVALID_CONFIGURATION","The Meta SDK changed during initialization. Use the popup flow or reload a fresh page.");e.facebookAppIds.set(t,n)}function me(r,t){if(t.aborted)return Promise.reject(new o("SDK_LOAD_FAILED","The Meta SDK load was cancelled."));let n=j(r),e=n.facebookLoadObserver;if(!e&&he(r.FB)&&(e={promise:Promise.resolve(r.FB),consumers:0}),!e){let s={consumers:0,promise:Promise.resolve().then(()=>new Promise((c,f)=>{var h;let p=!1,i,_=!1,g=!1,b,D,M,z=(u,l,y=!1)=>{if(!p){p=!0,clearTimeout(F),i==null||i.removeEventListener("load",P),i==null||i.removeEventListener("error",G);try{r.fbAsyncInit===V&&(D?Object.defineProperty(r,"fbAsyncInit",D):Reflect.deleteProperty(r,"fbAsyncInit"))}catch(L){}if(l&&i&&(n.failedFacebookScripts.add(i),y?n.erroredFacebookScripts.add(i):_||(n.facebookLoadUncertain=!0),_))try{i.remove()}catch(L){}n.facebookLoadObserver===s&&delete n.facebookLoadObserver,u?c(u):f(l)}},P=()=>{var y;if(p)return;let u=r.FB;if(!u)return;"__buffer"in u&&(b=u),(((y=b==null?void 0:b.__buffer)==null?void 0:y.opts)!=null||r.fbAsyncInit!==V||i!=null&&i.onload||n.facebookLoading||n.facebookLoadUncertain)&&(g=!1,n.facebookAppIds.get(u)===null&&n.facebookAppIds.delete(u),b&&n.facebookAppIds.get(b)===null&&n.facebookAppIds.delete(b));let l=he(u);if(g&&n.facebookAppIds.get(u)==null){if(!l)n.facebookAppIds.set(u,null);else if(!n.facebookInitObservers.has(u))try{be(n,u),n.facebookAppIds.set(u,null)}catch(L){}}l&&z(u)},G=()=>z(void 0,new o("SDK_LOAD_FAILED","The Meta SDK could not be loaded."),!0),V=()=>{if(!p){try{M==null||M.call(r)}catch(u){}P()}},F=setTimeout(()=>z(void 0,new o("SDK_LOAD_FAILED","The Meta SDK load timed out.")),30*1e3);s.cancelIfUnused=()=>{_&&s.consumers===0&&z(void 0,new o("SDK_LOAD_FAILED","The Meta SDK load was cancelled."))};try{D=Object.getOwnPropertyDescriptor(r,"fbAsyncInit"),M=typeof r.fbAsyncInit=="function"?r.fbAsyncInit:void 0;let u=r.document,l=u.getElementById("facebook-jssdk");if(i=Array.from(u.scripts).find(y=>{try{let L=new URL(y.src);return L.origin!=="https://connect.facebook.net"||!/^\/[^/]+\/sdk\.js$/.test(L.pathname)?!1:n.failedFacebookScripts.has(y)?(n.erroredFacebookScripts.has(y)||(n.facebookLoadUncertain=!0),!1):!0}catch(L){return!1}}),!i){i=u.createElement("script"),_=!0;let y=r.FB;y&&"__buffer"in y&&(b=y),g=!n.facebookLoadUncertain&&!n.facebookLoading&&!M&&(!y||!!b&&n.facebookAppIds.get(y)===null&&((h=b.__buffer)==null?void 0:h.opts)==null),l||(i.id="facebook-jssdk"),i.src="https://connect.facebook.net/en_US/sdk.js",i.crossOrigin="anonymous",i.async=!0,i.defer=!0}if(s.cancelIfUnused(),p)return;Object.defineProperty(r,"fbAsyncInit",D&&!D.configurable?{value:V}:{configurable:!0,enumerable:!0,writable:!0,value:V}),i.addEventListener("load",P),i.addEventListener("error",G),P(),!p&&_&&u.head.appendChild(i)}catch(u){z(void 0,new o("SDK_LOAD_FAILED","The Meta SDK could not be loaded."))}}))};n.facebookLoadObserver=e=s}let a=e;return new Promise((s,c)=>{let f=!1;a.consumers++;let p=(_,g)=>{var b;f||(f=!0,t.removeEventListener("abort",i),a.consumers--,_?s(_):c(g),(b=a.cancelIfUnused)==null||b.call(a))},i=()=>p(void 0,new o("SDK_LOAD_FAILED","The Meta SDK load was cancelled."));a.promise.then(_=>t.aborted?i():p(_),_=>p(void 0,new o("SDK_LOAD_FAILED",_.message))),t.addEventListener("abort",i,{once:!0}),t.aborted&&i()})}var we=(r,t,n=600,e=700)=>{let a=window,s=a.document,c=a.screenLeft!==void 0?a.screenLeft:a.screenX,f=a.screenTop!==void 0?a.screenTop:a.screenY,p=a.innerWidth?a.innerWidth:s.documentElement.clientWidth?s.documentElement.clientWidth:a.screen.width,i=a.innerHeight?a.innerHeight:s.documentElement.clientHeight?s.documentElement.clientHeight:a.screen.height,_=p/2-n/2+c,g=i/2-e/2+f;return a.open(r,t,`scrollbars=yes, width=${n}, height=${e}, top=${g}, left=${_}`)};var Se=600*1e3,ve=30*1e3;function v(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function O(r){return typeof r=="string"&&r.trim()?r:null}function Oe(r){if(r==="."||r==="..")throw new o("INVALID_OPTIONS","The channelId cannot be a URL path navigation segment.");try{return encodeURIComponent(r)}catch(t){throw new o("INVALID_OPTIONS","The channelId cannot be encoded as a URL path.")}}function Pe(r){let t;try{t=new URL(r)}catch(n){return!1}return t.protocol==="https:"&&(t.hostname==="facebook.com"||t.hostname.endsWith(".facebook.com"))}function Le(r){return["META_MESSENGER","META_INSTAGRAM","META_WHATSAPP","BOT_TELEGRAM","Z_API_WHATSAPP"].includes(r)}function ge(r){return typeof r=="string"&&["cancelled","popup_closed","not_completed","invalid_channel","origin_not_allowed","unsupported_channel"].includes(r)}function Y(r,t,n){return{success:!1,reason:n,channelId:r,type:t,code:null,wabaId:null,phoneId:null}}function Ae(r,t,n){return typeof fetch!="function"||typeof AbortController!="function"?Promise.reject(new o("INVALID_CONFIGURATION","Fetch and AbortController are required.")):new Promise((e,a)=>{let s=new AbortController,c=!1,f=(g,b)=>{c||(c=!0,clearTimeout(i),n==null||n.removeEventListener("abort",p),s.abort(),b?a(b):e(g))},p=()=>f(void 0,new o("ABORTED","The API request was aborted.")),i=setTimeout(()=>f(void 0,new o("TIMEOUT","The API request timed out.")),ve);if(n==null||n.addEventListener("abort",p,{once:!0}),n!=null&&n.aborted){p();return}(async()=>{let g;try{g=await fetch(r.href,{...t,signal:s.signal})}catch(b){f(void 0,new o("NETWORK_ERROR","The API request failed."));return}if(!c){if(!g||typeof g.ok!="boolean"){f(void 0,new o("INVALID_RESPONSE","The API response is invalid."));return}if(!g.ok){f(void 0,new o("HTTP_ERROR","The API returned an unsuccessful status."));return}try{let b=await g.json();c||f(b)}catch(b){f(void 0,new o("INVALID_RESPONSE","The API did not return valid JSON."))}}})().catch(()=>f(void 0,new o("NETWORK_ERROR","The API request failed.")))})}var ee=class{constructor(t){if(!v(t)||!O(t.publicKey)||Array.from(t.publicKey).some(n=>{let e=n.charCodeAt(0);return e<32||e===127})||t.logo!==void 0&&typeof t.logo!="string"||t.apiUrl!==void 0&&!O(t.apiUrl)||t.frontUrl!==void 0&&!O(t.frontUrl))throw new o("INVALID_CONFIGURATION","Valid client properties and a publicKey are required.");this.publicKey=t.publicKey,this.logo=t.logo,this.constants=fe({environment:t.environment,apiUrl:t.apiUrl,frontUrl:t.frontUrl})}async getListMessengerPages(t,n,e){if(!O(t)||!O(n))throw new o("INVALID_OPTIONS","A channelId and authorization code are required.");if(e!==void 0&&(!v(e)||typeof e.aborted!="boolean"||typeof e.addEventListener!="function"||typeof e.removeEventListener!="function"))throw new o("INVALID_OPTIONS","The abort signal is invalid.");if(e!=null&&e.aborted)throw new o("ABORTED","The API request was aborted.");return Ae(new URL(`${this.constants.api}/v1/channels/${Oe(t)}/list-messenger-pages`),{method:"POST",body:JSON.stringify({redirectUri:new URL(`${this.constants.front}/oauth/proxy-messenger`).href,code:n}),headers:{"Content-Type":"application/json",Authorization:this.publicKey}},e)}async connect(t){var n;try{if(typeof window=="undefined"||!window.document||!window.location)throw new o("BROWSER_REQUIRED","Connecting requires a browser window.");let e=window,a=j(e);if(a.activeConnection)throw new o("CONNECTION_IN_PROGRESS","A connection is already in progress in this window.");if(!v(t))throw new o("INVALID_OPTIONS","Connection options are required.");let{channelId:s,direct:c,getQRCode:f,timeoutMs:p=Se,signal:i}=t;if(typeof s!="string"||c!==void 0&&typeof c!="boolean"||f!==void 0&&typeof f!="function"||typeof p!="number"||!Number.isFinite(p)||p<=0||p>2147483647||i!==void 0&&(!v(i)||typeof i.aborted!="boolean"||typeof i.addEventListener!="function"||typeof i.removeEventListener!="function"))throw new o("INVALID_OPTIONS","Invalid channelId, direct, getQRCode, timeoutMs or signal option.");if(i!=null&&i.aborted)throw new o("ABORTED","The connection was aborted.");if(!s.trim())return Y(s,null,"invalid_channel");let _=Oe(s);if(typeof e.open!="function"||typeof e.addEventListener!="function"||typeof e.removeEventListener!="function"||typeof e.location.origin!="string"||typeof e.location.href!="string"||typeof((n=e.crypto)==null?void 0:n.getRandomValues)!="function"||typeof AbortController!="function"||typeof fetch!="function")throw new o("INVALID_CONFIGURATION","Required browser APIs are unavailable.");let g=e.location.origin;if(g==="null")return Y(s,null,"origin_not_allowed");let b=e.location.href,D=new URL(this.constants.front).origin;return await new Promise((M,z)=>{let P=Symbol("omnizapi-connection"),G=new AbortController,V=Date.now()+p,F=!1,h=null,u=null,l=null,y,L,x,K,q=!1,Q=!1,J=()=>{a.nativeLoginOwner===P&&(a.nativeLoginPending=!1,delete a.nativeLoginOwner)},te=[],E=d=>{if(F)return;F=!0,clearTimeout(L),clearInterval(x);try{i==null||i.removeEventListener("abort",X)}catch(U){}if(K)try{e.removeEventListener("message",K)}catch(U){}try{G.abort()}catch(U){}let W=l;l=null;try{W==null||W.close()}catch(U){}for(let{name:U,previous:I,value:C}of te)try{let k=Object.getOwnPropertyDescriptor(e,U);if(!k||!("value"in k)||k.value!==C)continue;I?Object.defineProperty(e,U,I):Reflect.deleteProperty(e,U)}catch(k){}a.activeConnection===P&&delete a.activeConnection,q&&(Q||!(d instanceof o)&&d.success)&&J(),d instanceof o?z(d):M(d)},X=()=>E(new o("ABORTED","The connection was aborted.")),T=()=>(!F&&(i!=null&&i.aborted)&&X(),!F&&Date.now()>=V&&E(new o("TIMEOUT","The connection timed out.")),!F),N=d=>E(Y(s,h,d)),oe=()=>{try{let d=we("about:blank","_blank",600,740);if(!d||d===e)throw new Error("Popup unavailable");if(!T()){d.close();return}l=d}catch(d){throw new o("POPUP_BLOCKED","The connection popup could not be opened.")}},Re=()=>{x||(x=setInterval(()=>{if(T())try{l!=null&&l.closed&&N("popup_closed")}catch(d){E(new o("PROVIDER_ERROR","The connection popup could not be monitored."))}},500))},Te=()=>{clearInterval(x),x=void 0},re=d=>{!T()||!h||E({success:!0,channelId:s,type:h,code:O(d.code),wabaId:O(d.wabaId),phoneId:O(d.phoneId),coexistence:d.coexistence===!0,redirectUri:u,botToken:O(d.botToken),pageId:O(d.pageId),accessToken:O(d.accessToken)})};try{if(a.activeConnection=P,i==null||i.addEventListener("abort",X,{once:!0}),!T())return;let d=e.crypto.getRandomValues(new Uint8Array(16)),W=Array.from(d,I=>I.toString(16).padStart(2,"0")).join("");for(let[I,C]of[["__omnizapiPublicKey",this.publicKey],["__omnizapiCurrentChannel",s],["__omnizapiGetQrCode",f]]){let k=Object.getOwnPropertyDescriptor(e,I);Object.defineProperty(e,I,k&&!k.configurable?{value:C}:{configurable:!0,enumerable:!0,writable:!0,value:C}),te.push({name:I,previous:k,value:C})}if(L=setTimeout(()=>E(new o("TIMEOUT","The connection timed out.")),p),!c)try{oe()}catch(I){y=I instanceof o?I:new o("POPUP_BLOCKED","The connection popup could not be opened.")}if(!T())return;(async()=>{var ae,se,ce;let I=await Ae(new URL(`${this.constants.api}/instances/${_}/sdk-info`),{headers:{Authorization:this.publicKey,"Content-Type":"application/json"}},G.signal);if(!T())return;if(!v(I)||!O(I.middleware))throw new o("INVALID_RESPONSE","The channel configuration is invalid.");let C=(ae=I.allowOrigins)!=null?ae:[];if(!Array.isArray(C)||!C.every(w=>typeof w=="string"))throw new o("INVALID_RESPONSE","The channel origins are invalid.");let k=I.middleware;if(h=Le(k)?k:null,g!==D&&!C.some(w=>{try{return g===new URL(w).origin}catch(m){return!1}})){N("origin_not_allowed");return}if(!h){N("unsupported_channel");return}let H=(se=O(h==="META_INSTAGRAM"?I.appInstagramId:I.appId))!=null?se:"",Z=(ce=O(I.appConfig))!=null?ce:"";if(h.startsWith("META_")&&!H||h==="META_WHATSAPP"&&!Z)throw new o("INVALID_RESPONSE","The channel provider configuration is invalid.");let ke=h==="META_WHATSAPP"&&c===!0,ie=!1,$;if(ke){if(Te(),a.nativeLoginPending)throw new o("CONNECTION_IN_PROGRESS","A previous Meta login is incomplete. Reload this window before retrying a native login.");if($=await me(e,G.signal),!T())return;try{Ie(e,$,H),ie=!0}catch(w){if(!(w instanceof o&&w.code==="INVALID_CONFIGURATION"))throw w}if(!T())return}if(ie&&$){l==null||l.close(),l=null;let w=null,m=null,B=null,le=!1,de=()=>{!T()||!w||!m||re({code:w,wabaId:m,phoneId:B,coexistence:le})};K=S=>{if(!T()||!Pe(S.origin))return;let R=S.data;if(typeof R=="string")try{R=JSON.parse(R)}catch(Ne){return}if(!(!v(R)||R.type!=="WA_EMBEDDED_SIGNUP")){if(R.event==="CANCEL")N("cancelled");else if(R.event==="ERROR")E(new o("PROVIDER_ERROR","Meta could not complete the connection."));else if(R.event==="FINISH"||R.event==="FINISH_ONLY_WABA"||R.event==="FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING"){if(!v(R.data)||!O(R.data.waba_id)||R.data.phone_number_id!=null&&typeof R.data.phone_number_id!="string")return;m=O(R.data.waba_id),B=O(R.data.phone_number_id),le=R.event==="FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING",de()}}},e.addEventListener("message",K),a.nativeLoginPending=!0,a.nativeLoginOwner=P,q=!0;try{$.login(S=>{if(!Q){if(Q=!0,F){J();return}if(T()){if(!v(S)||S.error){E(new o("PROVIDER_ERROR","Meta returned an invalid login response."));return}if(S.authResponse==null){N("not_completed");return}if(!v(S.authResponse)||!O(S.authResponse.code)){N("not_completed");return}w=O(S.authResponse.code),de()}}},{config_id:Z,response_type:"code",override_default_response_type:!0,extras:{setup:{},featureType:"whatsapp_business_app_onboarding",sessionInfoVersion:"3"}})}catch(S){throw J(),q=!1,new o("PROVIDER_ERROR","The Meta login could not be started.")}return}let A;if(h==="META_MESSENGER"||h==="META_INSTAGRAM"){let w=h==="META_MESSENGER";u=new URL(`${this.constants.front}/oauth/proxy-${w?"messenger":"instagram"}`).href,A=new URL(w?"https://www.facebook.com/dialog/oauth":"https://www.instagram.com/oauth/authorize"),A.searchParams.set("client_id",H),w&&A.searchParams.set("display","popup"),A.searchParams.set("redirect_uri",u),A.searchParams.set("response_type","code"),A.searchParams.set("scope",w?"public_profile,business_management,pages_messaging,pages_show_list,pages_manage_metadata,pages_read_engagement":"instagram_business_basic,instagram_business_manage_messages"),A.searchParams.set("state",JSON.stringify({currentUrl:b,attemptId:W,channelId:s}))}else h==="META_WHATSAPP"?(A=new URL(`${this.constants.front}/oauth/proxy-cloud-api`),A.searchParams.set("configId",Z),A.searchParams.set("appId",H),A.searchParams.set("channelId",s),A.searchParams.set("channelType",h),A.searchParams.set("logo",this.logo||new URL(`${this.constants.front}/logos/SVG/Ativo%2016.svg`).href),A.searchParams.set("pk",this.publicKey)):(A=new URL(`${this.constants.front}/connect/${h==="BOT_TELEGRAM"?"telegram":"whatsapp-web"}`),A.searchParams.set("channelId",s),A.searchParams.set("pk",this.publicKey));if(h!=="META_MESSENGER"&&h!=="META_INSTAGRAM"&&A.searchParams.set("attemptId",W),K=w=>{if(!T()||!l||w.origin!==D||w.source!==l)return;let m=w.data;!v(m)||m.type!=="after-connect"||m.attemptId!==W||m.channelId!==s||typeof m.success!="boolean"||m.reason!==void 0&&!ge(m.reason)||m.coexistence!==void 0&&typeof m.coexistence!="boolean"||["code","wabaId","phoneId","botToken","pageId","accessToken","redirectUri"].some(B=>m[B]!=null&&typeof m[B]!="string")||(m.success?h!=null&&h.startsWith("META_")&&!O(m.code)||h==="BOT_TELEGRAM"&&!O(m.botToken)?N("not_completed"):re(m):N(ge(m.reason)?m.reason:"not_completed"))},e.addEventListener("message",K),!!T()){if(y)throw y;if(l||oe(),l!=null&&l.closed){N("popup_closed");return}Re();try{l==null||l.location.replace(A.href)}catch(w){throw new o("PROVIDER_ERROR","The connection popup could not be navigated.")}}})().catch(I=>{T()&&E(I instanceof o?I:new o("PROVIDER_ERROR","The connection could not be completed."))})}catch(d){E(d instanceof o?d:new o("INVALID_CONFIGURATION","The connection could not be initialized."))}})}catch(e){throw e instanceof o?e:new o("INVALID_OPTIONS","The connection could not be started with these options.")}}},ye=ee;var ne=class{static newClient(t){return new ye(t)}};var _e=ne;Object.assign(window,{Omnizapi:_e});})();
|
package/examples/vanilla.html
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
<button id="connect-btn" type="button">Connect channel</button>
|
|
11
11
|
<p id="status" role="status"></p>
|
|
12
12
|
|
|
13
|
-
<!-- Version pinned to 1.0.
|
|
14
|
-
<script src="https://unpkg.com/@omnizapi/connect@1.0.
|
|
13
|
+
<!-- Version pinned to 1.0.4; test your integration and serve this page over HTTP(S). -->
|
|
14
|
+
<script src="https://unpkg.com/@omnizapi/connect@1.0.4/dist/omnizapi.min.js"></script>
|
|
15
15
|
<script>
|
|
16
16
|
const button = document.getElementById("connect-btn");
|
|
17
17
|
const statusElement = document.getElementById("status");
|