Notifications
1. Bevezető
A különféle értesítések (notification) küldése a felhasználóknak már minden alkalmazásban alapvető követelmény. Az értesítés fajtája lehet SMS, Email, Push vagy InAPP notification.
Ezek közül a Semi Product az Email és Push értesítések küldéséhez ad beépített megoldást.
SMS esetében mivel szinte minden projekten más lesz a tényleges SMS provider, ezért a már kész keretrendszerben csak az SmsNotificationMediaTypeService.send metódust kell implementálni.
InAPP értesítéseket még a Semi nem implementálta, így ha adott projekten szükséges, akkor a keretrendszer segítségével azt is implementálni kell.
1.1 Értesítések küldése kódból
A keretrendszer lelke a NotificationService és a NotificationMediaTypeService osztályok, rajtuk keresztül történik meg általánosan az értesítések kezelése.
Fejlesztőként a NotificationService.send vagy NotificationService.schedule metódusát kell használnunk, kivéve ha Push esetén topicra akarunk (le/fel) iratkozni.
1.1.1 Email küldése
public void sajatMetodusunk() {
EmailNotificationMessage notificationMessage = EmailNotificationMessage.builder()
...
.build();
notificationService.send(notificationMessage);
}
1.1.2 Push küldése
public void sajatMetodusunk() {
PushNotificationMessage notificationMessage = PushNotificationMessage.builder()
...
.build();
notificationService.send(notificationMessage);
}
1.1.3 SMS küldése
public void sajatMetodusunk() {
SmsNotificationMessage notificationMessage = SmsNotificationMessage.builder()
...
.build();
notificationService.send(notificationMessage);
}
1.1.4 InAPP küldése
public void sajatMetodusunk() {
InAppNotificationMessage notificationMessage = InAppNotificationMessage.builder()
...
.build();
notificationService.send(notificationMessage);
}
2. Email notification
2.1 Az SMTP szerver
Ahhoz, hogy az email megérkezzen a címzettekhez egy kiszolgáló szerverre van szükség. Ehhez SMTP (Simple Mail Transfer Protocol) szervert használunk.
A használni kívánt SMTP szervert az application.yml fájlban konfigurálhatjuk a spring.mail szekcióban.
2.1.1 Konfiguráció automata teszteknél
Mivel a teszteknél GreenMail-t használunk így csak az alábbi konfiguráció szükséges az automata tesztek futtatásakor:
2.1.2 Konfiguráció lokális és fejlesztői tesztkörnyezeteknél
Az alkalmazás által kiküldött levelek a maildev szolgáltatásban találhatóak meg. Ez egy lokális smtp mock, amit docker komponensként futtatunk, mint pl az adatbázist is.
Fejlesztői gépen a localhost:1080 címen érhetőek el a levelek. A menüből a relay funkcióval tovább lehet küldeni igazi levelező fiókokba is, ha erre igény lenne.
2.1.3 Címzettek maximális száma
Az SMTP szervereknek különböző limitációi lehetnek arra vonatkozólag, hogy 1 email üzenetnek hány címzettje lehet.
Ennek okán a projekten konfigurálható az 1 email üzenetben megadható maximális címzettek száma. Ezt az application.yml fájl project.notification szekció max-recipients paraméterében adhatjuk meg:
A gyakorlatban ez a limit annyit jelent, hogy amennyiben a konfigurált értéknél nagyobb számú címzettnek szeretnénk kiküldeni 1 email üzenetet, akkor a rendszer annyi üzenetben küldi ki az emailt hogy egyik üzenet címzettjeinek száma se haladja meg a limitet, de minden címzett megkapja az üzenetet.
Pl.: Ha 2500 címzettnek szeretnénk kiküldeni egy emailt, akkor ha a konfigurált max-recipients limit 1000 akkor 3 üzenetben küldi ki a rendszer az emailt.
2.2 Email template
Manapság egy email üzenetnek nem csak tartalmilag, de formailag is meg kell felelnie az aktuális trendeknek.
Ez a gyakorlatban úgy valósul meg, hogy a mai modern email kliensek képesek a HTML template-et használó email üzeneteket is megjeleníteni. A HTML lehetőséget ad arra, hogy az email üzeneteket igény szerint formázzuk és különféle stíluselemekkel lássuk el.
Ebből következően a projekten is HTML formátumban tároljuk az emailek template-jeit.
A template-ek előállításának megkönnyítésére az MJML Responsive Email Framework-öt használjuk.
A template-ből a HTML-t ezután egy generátor script-tel állítjuk elő.
Az email template-eket az adatbázisban a noti_templates táblában tároljuk és onnan használja az alkalmazás is.
A template beszúrásához szükséges SQL scriptet nem kézzel, hanem generálva állítjuk elő.
2.2.1 Template létrehozása és SQL script generálása
Az email template-ek forrás MJML fájljai a backend-service/websrc/src/notifications/templates/email mappa alatt találhatóak.
Ebbe a mappába kell létrehozni az új MJML template-et. A dinamikus paramétereket az alábbi formátumban kell megadni: ${notification.parameterName}
notification.-el prefixelt paraméternevek
Fontos, hogy az email templatekben a dinamikusan feloldandó paraméterek neveit prefixelni kell a notification. kulcsszóval.
Ennek oka, hogy a template-eket SQL scriptekkel beszúrjuk a noti_templates táblába is. Azonban az SQL scripteket nem kézzel, hanem Liquibase-el futtatjuk, ami bizonyos kulcsszavakat automatikusan felold az SQL scriptek végrehajtásakor.
Azért, hogy a Liquibase kulcsszavakkal történő esetleges egyezéseket elkerüljük a saját paramétereinket notification.-el prefixeljük.
A Liquibase projekten történő használatáról részletesebben olvashatsz itt.
Ha feltesszük, hogy az általunk létrehozott template neve: template-name, a feature mappa neve: featureDir akkor az alábbi lépésekkel tudjuk legenerálni az email template adatbázisba történő beszúrásához szükséges scriptet:
-
Az
srckönyvtárban lévőnotifications/templates/emailmappába kell létrehozni az email template-et az emailhez kapcsolódó feature package alá.template-name.mjmlnéven. Pl.:src/notifications/templates/email/newfeature/template-name.mjml -
Miután a template elkészült az
srckönyvtárban találhatópackage.json-ba fel kell venni az új template-hez tartozóbuildscript-et:"build-mjml:template-name": "node ./generate-html.js --folder featureDir --filename template-name && node ./generate-sql.js template-name"Template generálása
Ezt a scriptet futtatva tudjuk majd legenerálni az új template-hez tartozó HTML-t és SQL scriptet. A scriptet az intelliJ felületét használva is lefuttathatjuk, ha a „play“ ikonra kattintunk:
Generált template elérési útvonala
A generált template-ek a következő elérési útvonalon lesznek elérhetőek:
-
Ezt követően a
package.jsonfájlban hozzá kell adni a főbuildscript-hez a előbbi pontban felvett script-et:"build-mjml": "npm run build-mjml:client_email_verification && npm run build-mjml:admin_email_verification && npm run build-mjml:auth_user_reset_password && npm run build-mjml:template-name"Template generálása
Ezt a scriptet futtatva tudjuk majd legenerálni az összes template-hez tartozó SQL scriptet.
-
Végül a
generate-sql.jsfájlba kell felvenni az új template adatait aresourcestömbbe:{ fileName: "template-name", featureDir: "newfeature", notification_key: "email.notification_key", title: "email title", }- A
fileNamemezőben kell megadni a template fájl nevét. - A
featureDirmezőben kell megadni a templatehez tartozó feature package nevét. - A
notification_keymezőben kell megadni, hogy milyen kulccsal kerüljön be a template az adatbázisba. - A
titlemezőben kell megadni, hogy mi legyen a kiküldött email tárgya. (Itt is használhatóak a dinamikus paraméterek az email törzséhez hasonlóan.)
Az email template-ek
valid_fromértéke mindig az aktuális dátum lesz. Ha a generálás során kézzel szeretnénk megadni egy specifikus, akár jövőbeli dátumot, akkor a generálás idejére kitölthetjük aresourcestömbben avalid_frommezőt is:{ fileName: "template-name", featureDir: "newfeature", notification_key: "email.notification_key", title: "email title", valid_from: "2020-02-02 12:00:00 +01:00", }Mikor kell specifikus
valid_fromértéket definiálni?A
valid_frommezőben egy olyan dátumot lehet megadni amely dátumtól kezdve szeretnénk, hogy a rendszer az általunk generált template-et használja.Ez egy új template esetén nyilván az aktuális dátum kell hogy legyen és ilyenkor a
valid_frommegadása nem szükséges.Azonban amennyiben egy létező template-et módosítunk előfordulhat, hogy az új template-et csak egy bizonyos dátumtól kezdve szeretnénk használni. Ez a dátum a
valid_frommezőben adható meg.Fontos
Ha specifikus
valid_fromértékkel generáljuk a template SQL script-jét, akkor se commitoljuk fel a kitöltöttvalid_frommezőt. Az alapértelmezetten mindig maradjon üresen agenerate-sql.jsfájlban. - A
-
Ezután lépjünk be a webscr mappába, és installáljuk a node package manager-t.
- Főkönyvtárból:
cd .\backend-service\websrc\ -
npm ci -
Az
npm run build-mjml:template-nameparancs futtatása után kapjuk meg a generált SQL scriptet mely az alábbi útvonalon lesz elérhető:
backend-service/src/main/resources/db/insert_template_name_generated.sql -
Az
insert_template_name_generated.sqlfájl egy ideiglenes fájl amit a repositoryba sem kommitolunk. Ebből következően a Liquibase changeSet-be nem ezt a fájlt kell bekötni. A tartalmát másoljuk át az aktuális feature-höz tartozó SQL fájlunkba.
2.3 Az email küldés tesztelése
Az automata tesztek futtatásakor az email küldés teszteléséhez GreenMail-t használunk.
Ha olyan funkciót fejlesztünk ami email kiküldéssel is jár, akkor azt, hogy a megfelelő címzetteknek kiküldjük-e a megfelelő
emaileket az assertThatEmailsWasDeliveredToCorrectTargetEmails metódussal tudjuk ellenőrizni.
Az assertThatEmailsWasDeliveredToCorrectTargetEmails metódus egy EmailCheckDTO-t vár paraméterül, melyben megadható:
notificationKey: Az elvárt email értesítés template-jének azonosítója.targetEmails: Az elvárt email címzettjének/címzettjeinek email címe.
2.4 A noti_history tábla
Amikor egy értesítést kiküld a rendszer a hozzá tartozó metaadatokat és magát az email üzenetet is letárolja a noti_history táblában.
Így visszakereshetővé válik az email üzenetek kiküldése.
Az hogy a konkrét notification mentésre kerüljön, az application.yml-ben konfigurálható, notification típusonként külön, pl SMS esetében
2.5 Időzített üzenetek kiküldése
A rendszer támogatja, hogy előre lehessen ütemezni időzített üzeneteket, ehhez a NotificationService.schedule metódusát kell meghívni, majd a rendszer automatán kiküldi adott időpontban az értesítéseket.
Ha a projekt nem szeretné menteni az értesítéseket, akkor az időzített üzenetek csak addig kerülnek tárolásra, ameddig a tényleges kiküldés nem történik meg.
2.6 Push notificationök konfigurálása
Android és iOS esetén Firebase alapon történik meg a push notificationok kiküldése.
Ha a projekten szükséges, akkor konfiguráljuk be a Firebase tutorialok alapján az alkalmazásokat, és az application.yml fájlban beállíthatjuk a firebase-ről letöltött json fájlt a push szekció alatt.