-
Notifications
You must be signed in to change notification settings - Fork 345
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add ability to define interceptors #591
Conversation
@StephaneRob thanks so much for opening this PR. I'll review it as soon as I can. In the meantime, I was wondering if you could provide some more information as to the possible use cases for interceptors? I know I've used similar things in the past to prevent staging emails from going out, so I can see how this would be very useful. But I'd love to have more information so we can make sure to document all of that. Thanks! |
Hi @germsvel, use cases for interceptions:
use cases for modifications:
Certainly others use cases :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you so much for introducing this work. I'm really excited for this. I think this will be very useful! 🥳
I left several comments. If any of them are unclear, please let me know. I'd be happy to clarify them or help as much as I can.
I think the biggest change needed is for us to handle all deliver_x
functions. The PR currently handles deliver_now
.
Thanks again, and please reach out if you have comments or questions.
@germsvel thank you for your review :) |
Signed-off-by: Stéphane Robino <stephane@wttj.co>
Hi @germsvel, I reworked the feature. I also moved Let me know if it's more like you imagined it |
Nice work 👍 @StephaneRob what do you think about adding some headers with original addresses? That way it's possible to see which addresses should have received emails without interception.
|
Thx @davidlibrera :) |
Ok, I'm understand what's happening. This PR was notified to me as the same feature I was working by @maartenvanvliet but it seems that provides a different feature. |
@davidlibrera At first sight, your use case fits with interceptors feature. |
Ok, my fault. |
Yes exactly :) |
It sounds good! Many thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for all the improvements! 🥳
I left a few more comments, because I think we might not be handling two cases that we need to handle.
As I've read through the code, one thing that stood out to me is that we're using the term intercept for two different (but related) concepts. And that can make it confusing. One the one hand, we can define an interceptor module that modifies the email on its way out. A good example of that is the On the other hand, we can define interceptor modules that block an email from going out. That's when we use the So, I think the part that could cause confusion is that you can have an email that has been "intercepted" in the sense that it's gone through an interceptor but that hasn't been blocked — and thus has So, here's my question. What do you think about changing the term we use for one of those? I think the term interceptor implies blocking or obstructing, so it makes sense that an email is intercepted. So perhaps we can find a better name for the modules? But please feel free to disagree with this. It's possible that the term interceptor is good enough for both the modules and the boolean field. I'd love to hear your thoughts and see if we can find other terms. If we can't find other terms that better express that, I think I'm okay with using intercept for both. |
I understand what you mean. The term interceptor comes originally from Action Mailer (rails). They use Interceptor for the class but there is not Maybe we can change this term to something closer than a config :my_app, MyApp.Mailer,
adapter: MyAdapter,
before_send: [EnvHook, DenyListHook]
# with
defmodule Bamboo.Hook do
@callback call(email :: Bamboo.Email.t()) :: Bamboo.Email.t()
end
|
@StephaneRob thanks for mentioning that. I took a look at some of the interceptor libraries in Ruby, and I also tried to look for similar language used by other projects (for example, intercepting outgoing events in Phx Channels). It seems that the concept of intercept is used for modifying and blocking, like you have used it here. 👍 So, now I think we should keep the I think that also lines up with the language you used in the docs for the README:
I think that's a great description of interceptors: "Interceptors allow you to modify / block email on the fly. What do you think? |
@germsvel good idea! I update the pull request and let you know when ready for review. |
@germsvel I updated the PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great! Thank you so much for all the work and back and forth @StephaneRob! 🥳
Very excited for this feature.
assert %Bamboo.Email{blocked: true} = Mailer.deliver_later!(email) | ||
refute_receive {:deliver, %Bamboo.Email{to: [{nil, "blocked@blocked.com"}]}, _config} | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the change to these tests. They are far easier to read 🎉
@germsvel thank you for your help! |
This PR add ability to define interceptors for a given mailer. An interceptor can modify or intercept email before send.