Sending emails with Ash

Does Ash have a wrapper for Sending emails or a recommended way to send transactional emails e.g. Confirm Account?
16 Replies
ZachDaniel
ZachDaniel3y ago
No wrapper for it, but generally speaking you will want to implement them by using notifiers.
# in the resource
use Ash.Resource,
notifiers: [MyApp.SendUserEmails]

create :register do
...
end

# in the notifier
defmodule MyApp.SendUserEmails do
use Ash.Notifier

def notify(%{action: :register, data: user}) do
...send an email
end
end
# in the resource
use Ash.Resource,
notifiers: [MyApp.SendUserEmails]

create :register do
...
end

# in the notifier
defmodule MyApp.SendUserEmails do
use Ash.Notifier

def notify(%{action: :register, data: user}) do
...send an email
end
end
Ash takes care of ensuring that notifications are only sent after the transaction completes, so there are no timing issues. https://ash-hq.org/docs/guides/ash/latest/topics/notifiers
harry
harryOP3y ago
Cool, lets say I have an email that should happen without changes to the database e.g. a reminder from an Oban job can you programatically do that with notifiers?
ZachDaniel
ZachDaniel3y ago
You can, if you do something like this:
update :send_whatever_email do
manual fn changeset, _ ->
{:ok, changeset.data}
end
end
update :send_whatever_email do
manual fn changeset, _ ->
{:ok, changeset.data}
end
end
and then you can hook into it from a notifier.
harry
harryOP3y ago
ah ok, make a changeset that dosen't make any changes
ZachDaniel
ZachDaniel3y ago
Yep. In that case its a manual action, but if the changeset has no changes it won't update the record also the manual action doesn't hit the database unless you do something in the manual action to do so.
harry
harryOP3y ago
Thanks Zach
frankdugan3
frankdugan33y ago
Perfect timing, I just needed to do this too.
defmodule Decentralize.Help.ContactRequest do
use Decentralize.Resource,
notifiers: [Decentralize.Help.StaffNotifier]

attributes do
uuid_primary_key :id

attribute :email, :ci_string,
allow_nil?: false,
sensitive?: true,
constraints: @email_constraints

attribute :name, :ci_string, allow_nil?: false, sensitive?: true
attribute :type, :ci_string, allow_nil?: false
attribute :message, :ci_string, allow_nil?: false
end

actions do
create :create do
manual fn changeset, _ ->
Ash.Changeset.apply_attributes(changeset)
end
end
end
end
defmodule Decentralize.Help.ContactRequest do
use Decentralize.Resource,
notifiers: [Decentralize.Help.StaffNotifier]

attributes do
uuid_primary_key :id

attribute :email, :ci_string,
allow_nil?: false,
sensitive?: true,
constraints: @email_constraints

attribute :name, :ci_string, allow_nil?: false, sensitive?: true
attribute :type, :ci_string, allow_nil?: false
attribute :message, :ci_string, allow_nil?: false
end

actions do
create :create do
manual fn changeset, _ ->
Ash.Changeset.apply_attributes(changeset)
end
end
end
end
Greenfielding w/ Ash is such a better experience than all the boilerplate. 😄
harry
harryOP3y ago
How are you actually sending the emails? I wanted to try render Phoenix views
minib
minib3y ago
GitHub
GitHub - swoosh/swoosh: Compose, deliver and test your emails easil...
Compose, deliver and test your emails easily in Elixir - GitHub - swoosh/swoosh: Compose, deliver and test your emails easily in Elixir
GitHub
GitHub - swoosh/phoenix_swoosh: Swoosh <3 Phoenix
Swoosh <3 Phoenix. Contribute to swoosh/phoenix_swoosh development by creating an account on GitHub.
harry
harryOP3y ago
Does that work with CSS e.g. tailwindcss or does it still need premailing?
frankdugan3
frankdugan33y ago
I use Swoosh Phoenix + premail for one app. I don't use Tailwind in that one. Email is actually pretty tricky as far as what CSS is supported in the various clients. In another app, I use MJML, a special framework for ultimate CSS compatibility in Emails, got the idea from these posts. https://akoutmos.com/post/mjml-template-compliation/ https://medium.com/swlh/using-mjml-in-elixir-phoenix-ca27050ff26f
My.Thoughts v1
Crafting Beautiful Emails in Elixir Using MJML
Compile MJML->HTML->EEx using a Rust NIF and send your Phx.Gen.Auth notifications via Swoosh
Medium
Using MJML in Elixir & Phoenix
How to create responsive HTML emails for your Phoenix app with ease
frankdugan3
frankdugan33y ago
W/ emphasis on the first on, I went w/ the pre-rendered on the server way of doing it.
harry
harryOP3y ago
Awesome, thanks 🙌🏼 I tried premailx with tailwind but never got it to work unless I manually coppied the CSS into an inline style tag
frankdugan3
frankdugan33y ago
One suggestion: Make an effort to do an equally nice text Email body. Always good to have a fallback, and an option for odd ducks like me that use a terminal Email client. TableRex is a good lib for generating nice ASCII tables.
harry
harryOP3y ago
Yeah, I don't plan to send many emails but I would like the text ones to be nice and at the least functional although the client base for this app I presume it will mostly be GUI clients
frankdugan3
frankdugan33y ago
Yeah, safe assumption.

Did you find this page helpful?