Usługa biuletynu w Laravel: jak połączyliśmy wysyłanie wiadomości e-mail i SMS dla wszystkich usług wewnętrznych

W dużym projekcie każda usługa wysyłała e-maile i SMS-y na swój sposób: powielanie kodu, brak Pulpitu nawigacyjnego statusu, długie poprawki. Zaprojektowaliśmy kompleksową usługę biuletynu w Laravel i RabbitMQ z trzech rozwiązań-dashboard, API i nadawcy. Dostawcy łączą się raz, statusy są widoczne za pośrednictwem webhooków agregatorów, a zespół nie marnuje już czasu na zduplikowane integracje.

Usługa biuletynu w Laravel: jak połączyliśmy wysyłanie wiadomości e-mail i SMS dla wszystkich usług wewnętrznych

Problem: wysyłka jako wąskie gardło

Zacznijmy od kontekstu. Uczestniczyliśmy w dużym projekcie obejmującym zestaw różnych paneli użytkownika na platformie 1C-Bitrix. Każde rozwiązanie pełniło określoną funkcję. Uwierzytelnianie w każdym z nich odbywało się przez OAuth 2.0 za pośrednictwem naszego modułu napisanego w Laravelu. Większość serwisów wysyłała klientom wiadomości e-mail, a część korzystała również z SMS-ów.

Na pierwszy rzut oka wszystko działało. Jednak po bliższym przyjrzeniu się zauważyliśmy narastający dług techniczny:

  • Każdy serwis miał własną integrację z dostawcami usług wysyłkowych. Ten sam kod odpowiedzialny za wysyłkę był powielany w każdym rozwiązaniu.
  • Zespół wsparcia był wspólny, ale kod wysyłki rozproszony po wszystkich serwisach — błędy trzeba było poprawiać w kilku miejscach.
  • Brakowało dashboardu. Nie można było sprawdzić, czy wiadomość została wysłana i jaki ma status.
  • Zmiany w mechanizmach wysyłki wdrażano osobno w każdym serwisie. Przy dużym obciążeniu zespołu biznes długo czekał na poprawki.

Każda kolejna zmiana stawała się małym projektem: trzeba było równolegle modyfikować kilka serwisów, testować każdą integrację i pamiętać, który dostawca jest podłączony w którym miejscu.

Pomysł: jeden serwis zamiast modułu

Początkowo zadanie brzmiało skromnie — opracować moduł wysyłki wiadomości dla serwisu uwierzytelniania. Zaproponowaliśmy jednak biznesowi szersze rozwiązanie: stworzenie wspólnego serwisu wysyłkowego dla wszystkich serwisów wewnętrznych. Pomysł został zaakceptowany.

Dlaczego było to korzystniejsze niż kolejny moduł?

  • Jedna integracja zamiast kilku. Dostawców podłącza się raz, a nie osobno w każdym serwisie.
  • Jednolity interfejs API dla wszystkich serwisów wewnętrznych. Wysyłanie wiadomości i pobieranie ich statusów odbywa się według tego samego protokołu.
  • Centralny dashboard ze statusami wysyłek i rejestrem błędów. Zespół wsparcia zyskał dostęp do informacji o wysyłanych wiadomościach.
  • Zmiany szablonów i logiki w jednym miejscu. Biznes szybciej otrzymuje potrzebne aktualizacje.

Dodatkowym impulsem było to, że wszystkie serwisy korzystały z Mailchimp. Ze względu na spodziewaną blokadę tej platformy konieczne było przejście na nowe rozwiązanie dla rynku rosyjskiego.

Architektura serwisu wysyłkowego

Podzieliliśmy system na trzy komponenty. Każdy pełni określoną funkcję i komunikuje się z pozostałymi na podstawie jasno zdefiniowanych kontraktów.

  1. Dashboard — interfejs webowy

Ten komponent jest dostępny z poziomu przeglądarki. Skupia wszystkie informacje operacyjne:

  • Dane dotyczące wysyłki wiadomości e-mail i SMS
  • Klientów API serwisu i operacje zarządzania nimi
  • Rejestr błędów
  • Szablony wiadomości e-mail i SMS

To właśnie tutaj frontend developer przygotowuje i edytuje szablony.

  1. Komponent API

Przyjmuje zlecenia dla poszczególnych kanałów: zgłoszenia incydentów w OMNITRACKER, wiadomości e-mail przez integracje z DashaMail, UniSender i własnym serwisem wysyłkowym oraz SMS-y przez integracje z MTS Marketolog i MTS Communicator. Po walidacji żądania inicjuje utworzenie zadań w RabbitMQ.

  1. Komponent wysyłkowy

Jedynym sposobem przekazywania mu zadań jest kolejka RabbitMQ. Komponent pobiera zadania, gdy pojawią się w kolejce. Szablony pobiera z pierwszego komponentu, czyli dashboardu, za pośrednictwem API.

Taki podział zapewnił elastyczność systemu: komponent wysyłkowy nie musi znać wewnętrznej logiki API ani dashboardu. Obsługuje zadania z kolejki, a szablony pobiera przez API dashboardu. Ułatwia to skalowanie i izolowanie awarii.

Przebieg działania i RabbitMQ

Prześledźmy cały proces — od zmiany szablonu do uzyskania statusu wysyłki.

  1. Biznes zgłasza potrzebę zmiany szablonu wiadomości e-mail lub przygotowania nowego.
  2. Frontend developer tworzy albo modyfikuje szablon w komponencie odpowiedzialnym za zarządzanie szablonami. Następnie wdrażamy zmiany.
  3. Zespoły odpowiedzialne za serwisy wewnętrzne otrzymują instrukcję korzystania z nowego lub zmodyfikowanego szablonu przez API: jak wysłać wiadomość i pobrać jej status.
  4. Serwis kliencki wywołuje API, inicjując wysyłkę. Serwis wysyłkowy waliduje żądanie, umieszcza zadanie w kolejce, a następnie je przetwarza.
  5. Serwis oczekuje na aktualizacje statusu wysyłki przekazywane przez webhooki dostawców.

Do serwisu podłączono trzech dostawców usług e-mail i dwóch dostawców SMS. Taki układ zapewnia redundancję: jeśli jeden dostawca jest niedostępny, wysyłka odbywa się przez innego.

Dlaczego RabbitMQ?

Kolejka wiadomości stała się ogniwem łączącym komponent API z komponentem wysyłkowym. Dało to kilka istotnych korzyści:

  • Asynchroniczność. Serwis kliencki nie czeka na faktyczne wysłanie wiadomości — otrzymuje potwierdzenie przyjęcia zadania.
  • Niezawodność. Zadania nie giną podczas awarii, ponieważ kolejka przechowuje je do momentu przetworzenia.
  • Rozdzielenie odpowiedzialności. Komponent wysyłkowy można skalować niezależnie od pozostałych części systemu.

Co ważne, skonfigurowaliśmy obsługę RabbitMQ tak, aby wiadomość była potwierdzana i usuwana z kolejki dopiero po pomyślnym wykonaniu zadania. Dzięki temu nie tracimy zadań, które zostały pobrane do przetworzenia, ale nie zostały ukończone.

Rezultaty i wnioski

Po wdrożeniu serwisu wysyłkowego serwisy wewnętrzne nie muszą już przebudowywać swoich integracji. Korzystają po prostu ze wspólnego, ustandaryzowanego interfejsu wysyłki.

Najważniejsze rezultaty:

  • Skrócił się czas poświęcany na rozwój i utrzymanie wysyłki w serwisach wewnętrznych.
  • Uwolniony czas zespołu przeznaczono na funkcje ważniejsze dla biznesu.
  • Pojawiła się przejrzystość. Dashboard pokazuje statusy wysyłek, które wcześniej nie były widoczne.
  • Aktualizacje szablonów stały się szybsze. Biznes nie musi już długo czekać — zmiany wprowadza się w jednym miejscu.

Najważniejsze wnioski z tego projektu:

  • Centralizacja wysyłki opłaca się, gdy istnieje kilka serwisów, a integracje są powielane. Jeden wspólny serwis oznacza mniej kodu, mniej błędów i szybsze wdrażanie zmian.
  • Podział na dashboard, API i komponent wysyłkowy, z kolejką łączącą API z komponentem wysyłkowym, zapewnia elastyczność i skalowalność. Każdy komponent można zmieniać i rozwijać niezależnie.
  • Webhooki dostawców zapewniają wcześniej niedostępną widoczność statusów. Biznes może sprawdzić, czy wiadomość została wysłana.
  • Warto proponować biznesowi szersze rozwiązania. Zadanie „zbudować moduł” przerodziło się w usprawnienie architektury, które zaoszczędziło czas całego zespołu.

Jeśli macie kilka serwisów, z których każdy na własny sposób wysyła wiadomości e-mail i SMS, warto rozważyć wspólny serwis wysyłkowy. To jeden z tych przypadków, w których inwestycja w architekturę szybko się zwraca.

Porozmawiajmy o projekcie

Opowiedz o zadaniu — wycenimy w kilka dni

Kontakt