GithubHelp home page GithubHelp logo

luckyframework / carbon Goto Github PK

View Code? Open in Web Editor NEW
84.0 84.0 18.0 300 KB

Email library for Crystal. Testable, adapter-based, and catches bugs for you. Comes with an adapter for SendGrid.

License: MIT License

Crystal 93.19% HTML 3.80% Shell 3.01%
crystal email

carbon's People

Contributors

ajwann avatar akadusei avatar balakhorvathnorbert avatar bcardiff avatar brunto avatar camuthig avatar igor-alexandrov avatar jackturnbull avatar jwoertink avatar keizo3 avatar manveru avatar matthewmcgarvey avatar mdwagner avatar paulcsmith avatar stephendolan avatar xaviablaza avatar y2k2mt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

carbon's Issues

DevAdapter print_email option should highlight links

It would be cool if all of the URLs in your email were like green or something when you use the dev adapter to print emails. A well designed email is LOADED with markup, and printing them to find your "confirm email" link is pretty difficult. Since the rest of the text comes out in the basic color, if we had a way to colorize the URLs, then it'd be easier to scan your terminal to find it.

To do this though, I get we'd have to re-parse the HTML which means we'd have to include an HTML parser, and things get messy. So this is more of a wishful thinking, but I'm posting anyway just in case someone gets an idea of how we can do this without it getting too crazy and requiring 3rd party shards.

Add inline docs

Now that we publish API docs, we need to start filling in all of the actual inline documentation. Once that's done, the docs in the README can point to the official API docs.

Support Postmark

This is a feature request for a first-party adapter for Postmark (the better SendGrid ๐Ÿ˜‰)

Instance variables not working in templates

I created a text and HTML template, I have a couple of instance variables but when the email is sent the variables aren't replaced by their value they stay like that #{@name_of_the_variable}.

My class is like that:

class ConfirmationEmail < BaseEmail
    @title : String
    @sub_title : String
    @body : String

    def initialize(@email_address : String, @language : String, @confirmation_code : String)
      @title = translate("email_confirmation_title", @language, Nil)
      @sub_title = translate("email_confirmation_sub_title", @language, Nil)
      @body = translate("email_confirmation_body", @language, Nil)
    end

    to @email_address
    subject translate("email_confirmation_subject", @language, Nil)
    reply_to "[email protected]"
    templates text, html
  end

Here is my text template, couldn't be simpler:

#{@title}
#{@sub_title}

#{@body}


#{@confirmation_code}

I won't show my HTML template it's way too big. And I don't think it matters as the issue also involve the text template.

So when the email is sent, I receive the email like that:

#{@title}
#{@sub_title}

#{@body}


#{@confirmation_code}

Not, with the actual values.

Am I doing something wrong here?

Consider changing how the layout is defined

Per @paulcsmith

I would have expected this to be the name of the file and not the folder. May be worth changing this so the default is always src/emails/templates/layouts/{file} and the layout is the name of the file, not the folder. I think that is more common in most languages and that way you have one folder with all your layouts rather than a folder for each kind of layout

In reference to specifying a layout like layout my_email_layout

Add markdown mailable and methods for embedding pre-made HTML components

I'm not exactly sure how this will work but this is roughly what I want to be able to do:

## Welcome to MyApp

You can always [visit your account](#{UserProfiles::Show.with(@user.id})

#{mail_button("Log In", LogIns::New)}

It will send the markdown as-is for plain-text and will render it to HTML will ready made responsive styles. Would also allow having a mail layout that is responsive and customizable

Adding before/after hooks for emails

I just had a case come up where we need to send emails when a user is active on our site, but there may be technical issues where their system is flopping. Currently we would be sending an email on each call which just ends up being spam. Instead, we need to throttle sending the emails so we only send once on some parameter.

For this, it would be cool if there was a before/after hook on the deliver. This would allow us to do something like before we send, make sure we're allowed to send the email. Then after sending, we would update some table with the throttling info.

Add AwsSES adapter

#18
I want to use carbon adapter AWS SES.
But It is difficult to manage adapters within this repository.
So I will create separete repo for AWS SES adaptor.

Why is colorize undefined?

In lib/carbon/src/carbon/adapters/dev_adapter.cr:25:16

 25 | "#{"To:".colorize(:green)} #{email.to}",
               ^-------
Error: undefined method 'colorize' for String

Difference with lucky views

@paulcsmith
Hello,

In Lucky, tags are generated with regular Crystal methods, and Carbon, on the other side, uses ECR.

Why is that ? Isn't it better to have both generated with crystal methods for typesafe templates ?

Thanks.

be_delivered expectation fails when it shouldn't

I have a spec that looks like this:

NewPostEmail.new(friend, me, post).should be_delivered
NewPostEmail.new(friend, me, later_post).should_not be_delivered

because I'm sending bulk emails. In this case, I want to make sure the first one is sent because post is valid for sending at this time, but later_post is not, and should not be sent out. When the spec runs, it says both should be delivered, but I think it's a false positive because it sees the same to and same subject lines and probably whatever else to determine that these are the same email even though they're not.

`Carbon::Email` is no longer serializable

I include JSON::Serializable in my emails to have them sent in the background with Mel. Since Carbon v0.5, I get a compile error:

Showing last frame. Use --error-trace for full trace.

There was a problem expanding macro 'macro_139862332317072'

Code in /path/to/.crenv/versions/1.11.2/share/crystal/src/json/from_json.cr:271:3

 271 | {% begin %}
       ^
Called macro defined in /path/to/.crenv/versions/1.11.2/share/crystal/src/json/from_json.cr:271:3

 271 | {% begin %}

Which expanded to:

 > 27 |         
 > 28 |           when "io"
 > 29 |             __temp_4884 = self[:io].new(pull)
                                            ^--
Error: wrong number of arguments for 'IO::ARGF#initialize' (given 1, expected 2)

#88 introduced @attachment instance variable in Carbon::Email, a named tuple with one of its members being an IO, which is not serializable.

Is it possible to get rid of the @attachment instance variable? Maybe redefine .attachment macro thus:

macro attachment(value)
    def attachments : Array(Carbon::Attachment)
      {% if @type.methods.map(&.name).includes?("attachments".id) %}
        previous_def | [value]
      {% else %}
        [value]
      {% end %}
    end
  end

Code above is not tested, so I'm not sure if it works. But I'm thinking along the same lines as the callbacks:

macro before_send
def before_send
{% if @type.methods.map(&.name).includes?(:before_send.id) %}
previous_def
{% else %}
super
{% end %}
{{ yield }}
end
end

Or is there a better way to handle emails with Mel that I'm missing?

Generating a new email should detect if the word "Email" is included

"#{filename}_email.cr"
end
private def email_class_template_path
"src/emails/#{email_class_template_filename}"
end
private def email_class_template_file(file)
"src/emails/templates/#{filename}_email/#{file}.ecr"

It assumes you're generating an email like WelcomeUser which it will name WelcomeUserEmail. But if you generate WelcomeUserEmail, it'll name it WelcomeUserEmailEmail... we should not do that ๐Ÿ˜‚

Short circuit email sending

I have a case where I'm setting up users in a staging environment. I still want to be able to send email because I need to test on staging that emails are getting sent and that they look correct. However, the "fake" users I setup will have bad emails. This causes my bounce rates to skyrocket. For now, I can do some additional checks and avoid sending if their email matches something..

What would be cool is if we had a way to quick short-circuit the sending so it temporarily flips over to DevStrategy, or maybe just logs the email like it was sending, but doesn't actually send...

# sends real email
WelcomeUser.new(user_one).deliver_later

Cabron.temp_config(disable_sending: true) do
  # doesn't actually send
  WelcomeUser.new(user_two).deliver_later
end

# sends again
WelcomeUser.new(user_three).deliver_later

This interface might be ok, but the issue here is that there could be email sending all over the place in your app. Maybe there could be a method on your emailable object that handles it?

class User < BaseModel
  def emailable : Carbon::Address
    if email_is_phony?
      Carob::PhonyAddress.new(email)
    else
      Carbon::Address.new(email)
    end
  end
end

Then internally if it sees you have a PhonyAddress it doesn't actually send..

Add layouts

If you have a ton of emails, you'll probably want a single layout template so you don't have to keep digging through HTML to update header/footer stuff..

Extract SendGrid adapter into separate shard

Our README already has a great list of community Carbon adapters, and I believe that SendGrid should just be a Lucky-maintained third party adapter.

It struck me as a bit odd that we have default support for a single vendor in the Carbon library itself, and while it's nice to have an out-of-the-box solution that works in production, we can get around that by including the extracted shard in applications generated with the Lucky CLI.

Resolution of this issue should occur in these steps:

  • Extract SendGrid support to a separate adapter in the luckyframework org
  • Remove SendGrid support from this repository
  • Submit a PR to the Lucky CLI to include the new adapter in default Lucky generated apps
  • Ensure that release notes are loud and clear that this is a breaking change for anyone currently relying on SendGrid, and that they'll need to add the shard to their apps.

File attachment

Hello,

Any way to attach files on email? I cannot find it in the documentation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.