feat(email): send booking reminders before event start.

Job process_reminders in subscription_worker; REMINDER_LEAD_HOURS window;
CalenTIQ email + in-app event_reminder; idempotent reminder_sent.
Refs EventHub/EventHubBack#70
This commit is contained in:
2026-08-14 20:59:38 +03:00
parent 347a645933
commit 15ae8d4426
9 changed files with 245 additions and 6 deletions
+23 -1
View File
@@ -1,5 +1,6 @@
-module(logic_email).
-export([send_verification_email/2, send_specialist_invite/2, send_password_reset/2]).
-export([send_verification_email/2, send_specialist_invite/2, send_password_reset/2,
send_booking_reminder/4]).
%% SMTP via env (variant A / Back#68):
%% SMTP_HOST empty → log-only (local/tests)
@@ -19,6 +20,15 @@ send_specialist_invite(Email, Token) ->
send_password_reset(Email, Token) ->
send_kind(reset, Email, abs_url(<<"/reset-password?token=">>, Token)).
%% Reminder before event start (Back#70).
-spec send_booking_reminder(binary(), binary(), calendar:datetime(), binary()) -> ok.
send_booking_reminder(Email, EventTitle, StartTime, EventPath) ->
Url = abs_path(EventPath),
WhenText = format_utc(StartTime),
{Subject, Plain, Html} =
logic_email_templates:render_reminder(Url, to_bin(EventTitle), WhenText),
send(to_bin(Email), Subject, Plain, Html).
send_kind(Kind, To0, Url) ->
{Subject, Plain, Html} = logic_email_templates:render(Kind, Url),
send(to_bin(To0), Subject, Plain, Html).
@@ -99,6 +109,18 @@ abs_url(PathPrefix, Token) ->
TokenB = to_bin(Token),
<<Base/binary, PathPrefix/binary, TokenB/binary>>.
abs_path(Path0) ->
Base = strip_slash(env_bin("PUBLIC_APP_URL", <<"https://stage.calentiq.com">>)),
Path = case to_bin(Path0) of
<<$/, Rest/binary>> -> <<$/, Rest/binary>>;
Rest -> <<$/, Rest/binary>>
end,
<<Base/binary, Path/binary>>.
format_utc({{Y, Mo, D}, {H, Mi, _S}}) ->
iolist_to_binary(io_lib:format("~4..0B-~2..0B-~2..0B ~2..0B:~2..0B",
[Y, Mo, D, H, Mi])).
strip_slash(Url) ->
case binary:last(Url) of
$/ -> binary:part(Url, 0, byte_size(Url) - 1);