All Projects → luckyframework → carbon

luckyframework / carbon

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

Programming Languages

crystal
512 projects
HTML
75241 projects
shell
77523 projects

Labels

Projects that are alternatives of or similar to carbon

nuxt-mail
Adds email sending capability to a Nuxt.js app. Adds a server route, an injected variable, and uses nodemailer to send emails.
Stars: ✭ 62 (-12.68%)
Mutual labels:  email
email-framework
A simple, gulp powered framework to develop and test responsive emails.
Stars: ✭ 19 (-73.24%)
Mutual labels:  email
is-email-disposable
A REST API for checking if an e-mail address is disposable (a.k.a. throwaway). https://isemaildisposable.webgazer.io
Stars: ✭ 33 (-53.52%)
Mutual labels:  email
camunda-bpm-mail
Mail connectors for Camunda Platform 7
Stars: ✭ 64 (-9.86%)
Mutual labels:  email
smtp-translator
An SMTP server that converts emails into Pushover notifications.
Stars: ✭ 23 (-67.61%)
Mutual labels:  email
dispatch
A self-hosted mail forwarding API microservice
Stars: ✭ 24 (-66.2%)
Mutual labels:  email
email-reply-parser
🔎 Node library for parsing plain text email content.
Stars: ✭ 31 (-56.34%)
Mutual labels:  email
strapi-plugin-email-designer
Design your own email templates w/ visual composer directly inside the Strapi admin panel and send composed emails programmatically from your controllers / services.
Stars: ✭ 201 (+183.1%)
Mutual labels:  email
mailx
A lightweight SMTP mail library
Stars: ✭ 17 (-76.06%)
Mutual labels:  email
MAQS
Magenic's automation quick start
Stars: ✭ 46 (-35.21%)
Mutual labels:  email
rss2email
Convert RSS feeds to emails
Stars: ✭ 72 (+1.41%)
Mutual labels:  email
mailauth
Command line utility and a Node.js library for email authentication
Stars: ✭ 57 (-19.72%)
Mutual labels:  email
wp-mail-catcher
A fast, lightweight plugin that saves emails sent by your WordPress website.
Stars: ✭ 16 (-77.46%)
Mutual labels:  email
gmail-gitlab-filtering
Google Apps Script for Gmail to filter and sort email from GitLab
Stars: ✭ 84 (+18.31%)
Mutual labels:  email
yggmail
End-to-end encrypted email for the mesh networking age
Stars: ✭ 72 (+1.41%)
Mutual labels:  email
maildog
🐶 Hosting your own email forwarding service on AWS and managing it with Github Actions
Stars: ✭ 381 (+436.62%)
Mutual labels:  email
mailmask
Mailmask - easy stop unwanted email. Unlimited, free temporary email addresses, all forwarding to your real email address. Beat spam, protect your privacy.
Stars: ✭ 31 (-56.34%)
Mutual labels:  email
mjml-syntax
Sublime package for the MJML
Stars: ✭ 44 (-38.03%)
Mutual labels:  email
checkdmarc
A parser for SPF and DMARC DNS records
Stars: ✭ 124 (+74.65%)
Mutual labels:  email
go-html-email
Sending HTML email using Go 💌
Stars: ✭ 31 (-56.34%)
Mutual labels:  email

Carbon

API Documentation Website

Email library written in Crystal.

code preview

Installation

Add this to your application's shard.yml:

dependencies:
  carbon:
    github: luckyframework/carbon

Adapters

Usage

First, create a base class for your emails

require "carbon"

# You can setup defaults in this class
abstract class BaseEmail < Carbon::Email
  # For example, set up a default 'from' address
  from Carbon::Address.new("My App Name", "[email protected]")
  # Use a string if you just need the email address
  from "[email protected]"
end

Configure the mailer class

BaseEmail.configure do |settings|
  settings.adapter = Carbon::DevAdapter.new(print_emails: true)
end

Create a class for your email

# Create an email class
class WelcomeEmail < BaseEmail
  def initialize(@name : String, @email_address : String)
  end

  to @email_address
  subject "Welcome, #{@name}!"
  header "My-Custom-Header", "header-value"
  reply_to "[email protected]"
  # You can also do just `text` or `html` if you don't want both
  templates text, html
end

Create templates

Templates go in the same folder the email is in:

  • Text email: <folder_email_class_is_in>/templates/<underscored_class_name>/text.ecr
  • HTML email: <folder_email_class_is_in>/templates/<underscored_class_name>/html.ecr

So if your email class is in src/my_app/emails/welcome_email.cr, then your templates would go in src/my_app/emails/welcome_email/text|html.ecr.

# in <folder_of_email_class>/templates/welcome_email/text.ecr
# Templates have access to instance variables and methods in the email.
Welcome, <%= @name %>!
# in <folder_of_email_class>/templates/welcome_email/html.ecr
<h1>Welcome, <%= @name %>!</h1>

For more information on what you can do with Embedded Crystal (ECR), see the official Crystal documentation.

Deliver the email

# Send the email right away!
WelcomeEmail.new("Kate", "[email protected]").deliver

# Send the email in the background using `spawn`
WelcomeEmail.new("Kate", "[email protected]").deliver_later

Delay email delivery

The built-in delay uses the deliver_later_strategy setting set to Carbon::SpawnStrategy. You can create your own custom delayed strategy that inherits from Carbon::DeliverLaterStrategy and defines a run method that takes a Carbon::Email and a block.

One example might be a job processor:

# Define your new delayed strategy
class SendEmailInJobStrategy < Carbon::DeliverLaterStrategy

  # `block.call` will run `deliver`, but you can call
  # `deliver` yourself on the `email` when you need.
  def run(email : Carbon::Email, &block)
    EmailJob.perform_later(email)
  end
end

class EmailJob < JobProcessor
  def perform(email : Carbon::Email)
    email.deliver
  end
end

# configure to use your new delayed strategy
BaseEmail.configure do |settings|
  settings.deliver_later_strategy = SendEmailInJobStrategy.new
end

Testing

Change the adapter

# In spec/spec_helper.cr or wherever you configure your code
BaseEmail.configure do
  # This adapter will capture all emails in memory
  settings.adapter = Carbon::DevAdapter.new
end

Reset emails before each spec and include expectations

# In spec/spec_helper.cr

# This gives you the `be_delivered` expectation
include Carbon::Expectations

Spec.before_each do
  Carbon::DevAdapter.reset
end

Integration testing

# Let's say we have a class that signs the user up and sends the welcome email
# that was described at the beginning of the README
class SignUpUser
  def initialize(@name : String, @email_address : String)
  end

  def run
    sign_user_up
    WelcomeEmail.new(name: @name, email_address: @email_address).deliver_now
  end
end

it "sends an email after the user signs up" do
  SignUpUser.new(name: "Emily", email_address: "[email protected]").run

  # Test that this email was sent
  WelcomeEmail.new(name: "Emily", email_address: "[email protected]").should be_delivered
end

Unit testing

Unit testing is simple. Instantiate your email and test the fields you care about.

it "builds a nice welcome email" do
  email = WelcomeEmail.new(name: "David", email_address: "[email protected]")
  # Note that recipients are converted to an array of Carbon::Address
  # So if you use a string value for the `to` field, you'll get an array of
  # Carbon::Address instead.
  email.to.should eq [Carbon::Address.new("[email protected]")]
  email.text_body.should contain "Welcome"
  email.html_body.should contain "Welcome"
end

Note that unit testing can be superfluous in most cases. Instead, try unit testing just fields that have complex logic. The compiler will catch most other issues.

Development

  • shards install
  • Make changes
  • crystal spec

Contributing

  1. Fork it ( https://github.com/luckyframework/carbon/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Make your changes
  4. Run ./script/test to run the specs, build shards, and check formatting
  5. Commit your changes (git commit -am 'Add some feature')
  6. Push to the branch (git push origin my-new-feature)
  7. Create a new Pull Request

Contributors

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].