Návrh integrace O2 SMS Connector do Dynamics 365 (Dataverse)
Odesílání SMS z Dynamics 365 / Dataverse přes službu O2 SMS Connector pomocí Power Automate (varianta bez Azure a bez vlastního kódu pro mTLS).
Obsah
- 1. Cíl a kontext
- 2. Jak funguje O2 SMS Connector
- 3. Jádro problému — klientský certifikát v sandboxu
- 4. Doporučená architektura — Outbox pattern
- 5. Datový model — tabulka o2_smsmessage
- 6. Plugin (sandbox-safe)
- 7. Power Automate Flow
- 8. Security a správa secrets
- 9. Na co dát pozor
- 10. Otevřené otázky pro zákazníka
- 11. Předpoklady a registrace u O2
- 12. Reference na manuály
1. Cíl a kontext
Potřebujeme z Dynamics 365 (Dataverse) odesílat textové SMS koncovým uživatelům přes službu O2 SMS Connector. Řešení musí být:
- Asynchronní — odeslání SMS nesmí blokovat transakci uživatele.
- Odolné — když je O2 dočasně nedostupné, zpráva se neztratí.
- Bez nutnosti Azure — využíváme Power Platform (Power Automate).
- Sandbox-safe — respektuje omezení pluginů v Dataverse.
2. Jak funguje O2 SMS Connector
Služba nabízí dvě rovnocenná rozhraní ke stejné platformě (O2 Messaging Platform, „MP"):
| Rozhraní | Vlastnosti | Použití |
|---|---|---|
| HTTP GET/POST | Jednoduché, jen textové SMS | ✅ Doporučeno pro náš případ |
| Web Services (SOAP) | Plná funkcionalita (binární SMS, MMS, push) | Jen pokud bude potřeba více |
Pro odesílání textové SMS použijeme HTTP POST na endpoint:
https://smsconnector.cz.o2.com/smsconnector/getpost/GP
Klíčové pojmy
- baID — ID business aplikace, přidělí O2 (7 číslic, MSISDN z rozsahu
199…, např.1991123). - AO/MT — Application-Originated / Mobile-Terminated = SMS od nás k uživateli (akce
send). - Certifikát — klientský X.509 (
.p12s privátním klíčem) pro mutual TLS. Identita aplikace = certifikát spárovaný sbaID(žádný login/heslo).
Parametry akce send
| Parametr | Povinný | Popis |
|---|---|---|
action |
✔ | send |
baID |
✔ | ID aplikace, např. 1991123 |
toNumber |
✔ | příjemce v mezinár. formátu +420602... (CZ = přesně 12 číslic vč. +420) |
text |
✔ | text; max 160 znaků, nebo 900 při multipart=TRUE. Jen 7bit GSM 03.38 — bez diakritiky |
msgID |
– | naše unikátní ID zprávy (doporučeno, kvůli párování delivery reportů; bez ;) |
deliveryReport |
– | TRUE/FALSE (default FALSE) |
multipart |
– | TRUE umožní text > 160 znaků (O2 účtuje každou část) |
fromNumber |
– | odesílatel — baID, MSISDN nebo NICKNAME (musí být provisioned u O2) |
validityPeriod |
– | platnost v sekundách, max 388800 (4,5 dne) |
priority |
– | 1 VIP / 2 high / 3 normal (default) |
Odpověď (HTTP 200, text/plain, UTF-8) je sada řádků KLÍČ=HODNOTA.
Úspěch = responseType=SUCCESS, responseCode=ISUC_001. Synchronní chyby vrací HTTP 400.
Naše msgID se vrací v poli refMsgID.
3. Jádro problému — klientský certifikát v sandboxu
O2 vyžaduje mutual TLS s klientským certifikátem. Plugin v Dataverse ale běží v sandboxu (isolation mode), který je pro práci s certifikátem prakticky nepoužitelný:
| Co je potřeba k mTLS | Stav v sandboxu |
|---|---|
Načíst .pfx/.p12 ze souboru |
❌ žádný přístup k file systému |
Načíst cert z Windows cert store (X509Store) |
❌ blokováno SecurityException |
X509Certificate2 s privátním klíčem z byte[] |
⚠️ potřebuje persistovat klíč na disk → selže; EphemeralKeySet je až .NET 4.7.2, plugin cílí na 4.6.2 |
| Odchozí síť | ✅ jen HTTP/HTTPS na portech 80/443 |
Další omezení: 2minutový timeout, žádná vlákna/registry/event log, synchronní volání externí služby blokuje transakci platformy.
Závěr: mTLS s klientským certifikátem přímo z pluginu Microsoft nepodporuje a v praxi to spolehlivě nezprovozníte. Certifikát musí žít mimo sandbox.
Řešení: Power Automate to umí nativně
Premium akce HTTP v Power Automate má v nastavení Authentication přímo typ
Client Certificate, kde zadáte:
- Pfx — obsah
.p12/.pfxsouboru v Base64 - Password — password k privátnímu klíči
Connector provede mTLS handshake za vás. Žádný sandbox, žádný kód, žádné Azure.
4. Doporučená architektura — Outbox pattern
Plugin pouze vytvoří řádek v „outbox" tabulce (rychlé, sandbox-safe) a skončí. Power Automate Flow se spustí na vytvoření řádku, zavolá O2 přes mTLS a zapíše zpět stav.
(plugin / workflow)"] OB[("Tabulka
o2_smsmessage
(Outbox)")] BL -->|"1 - Create row
(Pending)"| OB end subgraph PP["Power Platform"] FLOW["Power Automate Flow"] end O2["O2 SMS Connector
HTTP POST /GP"] OB -.->|"2 - Trigger:
When a row is added"| FLOW FLOW -->|"3 - HTTP POST + mTLS
(Client Certificate)"| O2 O2 -->|"4 - responseCode
refMsgID"| FLOW FLOW -->|"5 - Update row
(Sent / Failed)"| OB
Proč outbox tabulka a ne trigger přímo na business entitě
- Asynchronní — flow běží mimo transakci Dataverse.
- Odolnost — při výpadku O2 zůstane řádek
Pending, lze opakovat. - Audit/logging — historie každé SMS (text, příjemce,
responseCode,refMsgID, čas). - Decoupling — plugin jen vytvoří řádek a hned skončí, neblokuje uživatele.
Sekvenční pohled
5. Datový model — tabulka o2_smsmessage
Custom tabulka jako outbox a zároveň audit log.
| Sloupec (logický) | Typ | Popis |
|---|---|---|
o2_tonumber |
Text | Příjemce +420... |
o2_text |
Multiline text | Text zprávy |
o2_status |
Choice | Pending (1), Sent (2), Failed (3) |
o2_msgid |
Text | Naše unikátní msgID (GUID) |
o2_responsecode |
Text | Návratový kód O2 (ISUC_001, EFMT_007, …) |
o2_refmsgid |
Text | refMsgID z odpovědi O2 |
o2_rawresponse |
Multiline text | Surová odpověď O2 (pro diagnostiku) |
o2_senton |
DateTime | Čas odeslání |
6. Plugin (sandbox-safe)
Plugin nedělá nic náročného — jen zapíše řádek do outboxu. Veškerá síťová a certifikátová logika je mimo sandbox.
var sms = new Entity("o2_smsmessage");
sms["o2_tonumber"] = "+420602123456";
sms["o2_text"] = "Vas kod je 1234";
sms["o2_status"] = new OptionSetValue(1); // Pending
service.Create(sms);
Plugin step registrujte tak, aby zápis odpovídal vaší business logice (typicky synchronně na hlavní entitě — samotný
Createřádku je levný; vlastní odeslání SMS je už asynchronní díky flow).
7. Power Automate Flow
Kroky
-
Trigger: Dataverse → When a row is added na tabulce
o2_smsmessage. -
(Volitelně) Get Secret: Azure Key Vault → načtení Pfx Base64 a hesla, nebo čtení z Environment Variables.
-
Compose – body (form-urlencoded;
textmusí být URL-enkódovaný):
text
action=send
&baID=@{variables('baID')}
&toNumber=@{uriComponent(triggerOutputs()?['body/o2_tonumber'])}
&text=@{uriComponent(triggerOutputs()?['body/o2_text'])}
&msgID=@{guid()}
&deliveryReport=FALSE
&multipart=@{if(greater(length(triggerOutputs()?['body/o2_text']),160),'TRUE','FALSE')}
&priority=3
(v praxi jako jeden concat() / Compose bez odřádkování)
- HTTP akce:
- Method:
POST - URI:
https://smsconnector.cz.o2.com/smsconnector/getpost/GP - Header:
Content-Type: application/x-www-form-urlencoded - Body: výstup z Compose
-
Authentication:
Client Certificate→ Pfx (Base64), Password -
Vyhodnocení odpovědi — O2 vrací
text/plainřádkyKLÍČ=HODNOTA. Úspěch:
text
contains(body('HTTP'), 'responseType=SUCCESS')
nebo přesněji vytáhnout responseCode (ISUC_001) a refMsgID.
- Update row v
o2_smsmessage→ statusSent/Failed, uložitresponseCode,refMsgIDa surovou odpověď.
Tok flow
(o2_smsmessage)"] --> S["Get Secret
(Pfx Base64 + password)"] S --> C["Compose: form-urlencoded body
(uriComponent na text)"] C --> H["HTTP POST → O2
Auth: Client Certificate"] H --> Q{"responseType=SUCCESS?"} Q -->|Ano| OK["Update row:
status=Sent
responseCode, refMsgID"] Q -->|Ne| ERR["Update row:
status=Failed
rawResponse"]
8. Security a správa secrets
| Secret | Doporučené uložení |
|---|---|
| Pfx (Base64) + password | Ne natvrdo do akce (viditelné v exportu flow). Použít Environment Variables typu Secret (ideálně s referencí na Azure Key Vault), nebo connector Azure Key Vault → Get Secret na začátku flow. |
| baID, endpoint | Environment Variables (mohou referencovat Key Vault). Žádný hardcode. |
Konverze certifikátu .p12 → Base64 (PowerShell):
[Convert]::ToBase64String([IO.File]::ReadAllBytes("cert.p12"))
9. Na co dát pozor
| Téma | Doporučení |
|---|---|
| Licence | HTTP je premium connector → potřeba Power Automate per-flow/per-user plán. Ověřit licencování. |
| Retry na HTTP 403 | Dle manuálu: opakovat po 5 s, max 5×. Nastavit na HTTP akci Settings → Retry Policy, nebo obalit do Do until. |
| Diakritika | Jen 7bit GSM 03.38 — háčky/čárky O2 v AO směru nepodporuje. Před odesláním text transliterovat (odstranit diakritiku). |
| Delivery reporty | Chodí asynchronně přes receive (jiný endpoint). Pokud je budete chtít, je to samostatný flow s plánovaným pollingem — k odeslání není potřeba. |
| Formát čísla | CZ příjemce přesně 12 číslic vč. +420 (EFMT_007 při chybě). |
| Throttling | Standardní kapacita 1 SMS/s; při překročení se send zpomalí. Vyšší kapacita (5/20 SMS/s) za příplatek. |
10. Otevřené otázky pro zákazníka
Než finalizujeme implementaci, potřebujeme od zákazníka (a částečně od O2) zodpovědět
níže uvedené otázky. Jejich odpovědi rozhodnou o volbě rozhraní a konkrétní metody
(HTTP GET/POST vs Web Services, a v rámci WS SimpleSmsGw.sendSms vs PPGw.send,
pull vs push). Náš návrh počítá s HTTP GET/POST přes Power Automate — to je správně
jen pokud odpovědi nevynutí SOAP (viz rozhodovací matice).
Slouží zároveň jako checklist na schůzku — pole na odpovědi jsou prázdná.
A. Funkční rozsah (rozhoduje o rozhraní)
| # | Otázka | Odpověď |
|---|---|---|
| A1 | Směr komunikace — jen odchozí SMS (AO/MT), nebo i příchozí (MO/AT, odpovědi uživatelů, two-way)? | |
| A2 | Pokud i příchozí — pull, nebo push mode? (push = zákazník provozuje veřejný endpoint na portu 443/8443) | |
| A3 | Potřeba delivery reportů (potvrzení o doručení)? Co s nimi — logovat / reagovat? | |
| A4 | Posílat binární SMS / MMS / flash (intruder) SMS / premium (zpoplatněné) zprávy? (binary/MMS/premium = jen Web Services) | |
| A5 | Diakritika — stačí transliterace (odstranění háčků/čárek), nebo musí projít Unicode/UCS-2? (Unicode v AO jen přes Web Services) |
B. Objem a kapacita (rozhoduje o tarifu)
| # | Otázka | Odpověď |
|---|---|---|
| B1 | Kolik SMS denně / měsíčně, jaké jsou špičky? | |
| B2 | Požadovaná propustnost — 1 / 5 / 20 SMS/s? (vyšší = příplatek, ovlivňuje throttling) | |
| B3 | Jsou potřeba paralelní vlákna (vyšší objem najednou)? |
C. Identita a registrace u O2
| # | Otázka | Odpověď |
|---|---|---|
| C1 | Je už uzavřená smlouva / aktivovaná služba SMS Connector, nebo začínáme od nuly? | |
| C2 | Máte přidělené baID, nebo si chcete zvolit vlastní číslo? | |
| C3 | Na jaké hlasové číslo bude služba navázaná? (jeho deaktivace = deaktivace SMS Connectoru) | |
| C4 | SMS Connector vs SMS Connector Plus (rozšířená varianta) — co máte/chcete? |
D. Certifikát
| # | Otázka | Odpověď |
|---|---|---|
| D1 | Veřejná CA (1.CA, Verisign…), nebo O2-generovaný certifikát? | |
| D2 | Kdo certifikát vygeneruje, kde bude uložený (Key Vault?) a kdo hlídá expiraci/obnovu? |
E. Odesílatel a obsah
| # | Otázka | Odpověď |
|---|---|---|
| E1 | Jak se má SMS zobrazit příjemci — z baID, z konkrétního MSISDN, nebo jako alfanumerický NICKNAME? (NICKNAME vyžaduje zvlášť provisioning u O2) | |
| E2 | Délka zpráv — do 160 znaků, nebo multipart do 900? (multipart = O2 účtuje každou část) | |
| E3 | validityPeriod a priorita — jak dlouho se má O2 pokoušet doručit, VIP/high/normal? |
F. Provoz
| # | Otázka | Odpověď |
|---|---|---|
| F1 | Existuje testovací baID / sandbox u O2 pro vývoj a testy? | |
| F2 | Vyžaduje O2 IP whitelisting vašeho prostředí? | |
| F3 | Kdo bude kontaktní osoba pro SMS Connector (vyřizuje dotazy příjemců)? |
Rozhodovací matice
Mapování odpovědí na správnou metodu:
| Odpovědi zákazníka | Doporučená metoda |
|---|---|
| Jen odchozí textové SMS, bez Unicode diakritiky, bez delivery reportů | HTTP GET/POST send ← náš návrh (Power Automate) |
| Odchozí + potřeba delivery reportů přes pull | HTTP GET/POST send + samostatný receive flow |
| Potřeba Unicode diakritiky, binary SMS, MMS nebo premium | Web Services PPGw.send(MessageContainer) |
| Maximálně jednoduché odeslání přes SOAP, vše ostatní default | Web Services SimpleSmsGw.sendSms |
| Vysoký objem příchozích zpráv, nízká latence | Web Services push (PushPPGw) — zákazník provozuje endpoint |
Klíčové „rozbíječe" HTTP GET/POST řešení (kvůli kterým bychom museli na Web Services): potřeba Unicode diakritiky, binary/MMS/premium zpráv, nebo push příjmu. Pokud žádný nenastane, zůstává HTTP GET/POST + Power Automate jako nejjednodušší volba.
11. Předpoklady a registrace u O2
- Registrace aplikace u O2 — aktivační formulář, navázání na hlasové číslo,
volba tarifu a kapacity, přidělení
baIDa denních/měsíčních limitů. - Certifikát — vygenerovat (O2 aplikace nebo veřejná CA: 1.CA, Verisign…),
veřejnou část (
.PEM) zaslat O2 ke spárování sbaID, privátní (.P12) si ponechat. - Limity a kapacitu potvrdit s O2.
12. Reference na manuály
Stažené v adresáři docs/:
| Soubor | Obsah |
|---|---|
01_WebServices_rozhrani_ENG.pdf |
SOAP/Web Services rozhraní (plná funkcionalita) |
02_HTTP_GET_rozhrani_ENG.pdf |
HTTP GET/POST rozhraní (použito pro tento návrh) |
03_Deployment_Specific_Parameters.pdf |
Konkrétní hodnoty timeoutů, limitů, URL |
04_SMS_Connector_Plus_EMP_UserManWS.pdf |
SMS Connector Plus (rozšířená varianta) |
05_Certifikaty_Manual.pdf |
Generování certifikátů |
Zdroj dokumentace: https://www.o2.cz/podnikatele-a-firmy/volani/sms-connector