Skip to content
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

Update to latest Carbon. Added support for attachments. #18

Merged
merged 1 commit into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion shard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ license: MIT
dependencies:
carbon:
github: luckyframework/carbon
version: ~> 0.4.0
version: ~> 0.5.1
habitat:
github: luckyframework/habitat
version: ~> 0.4.8
Expand Down
9 changes: 9 additions & 0 deletions spec/carbon_sendgrid_adapter_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,15 @@ describe Carbon::SendGridAdapter do

params["personalizations"].as(Array).first.has_key?("asm").should eq(false)
end

it "handles attachments" do
email = FakeEmail.new(text_body: "0")
params = Carbon::SendGridAdapter::Email.new(email, api_key: "fake_key").params
attachments = params["attachments"].as(Array)
attachments.size.should eq(1)
attachments.first["filename"].should eq("contract.pdf")
Base64.decode_string(attachments.first["content"].to_s).should eq("Sign here")
end
end
end

Expand Down
9 changes: 9 additions & 0 deletions spec/support/fake_email.cr
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,13 @@ class FakeEmail < Carbon::Email
cc @cc
bcc @bcc
subject @subject
attachment contract

def contract
{
io: IO::Memory.new("Sign here"),
file_name: "contract.pdf",
mime_type: "application/pdf",
}
end
end
16 changes: 15 additions & 1 deletion src/carbon_sendgrid_adapter.cr
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require "http"
require "json"
require "carbon"
require "base64"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Sendgrid API docs mention that attachments should be Base64.

require "./errors"
require "./carbon_sendgrid_extensions"

Expand Down Expand Up @@ -35,7 +36,6 @@ class Carbon::SendGridAdapter < Carbon::Adapter
end

# :nodoc:
# Used only for testing
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why this said used only for testing 🤔 This method is how we send the email lol

def params
data = {
"personalizations" => [personalizations],
Expand All @@ -45,6 +45,7 @@ class Carbon::SendGridAdapter < Carbon::Adapter
"reply_to" => reply_to_params,
"asm" => {"group_id" => 0, "groups_to_display" => [] of Int32},
"mail_settings" => {sandbox_mode: {enable: sandbox?}},
"attachments" => attachments,
}.compact

if asm_data = email.asm
Expand Down Expand Up @@ -138,6 +139,19 @@ class Carbon::SendGridAdapter < Carbon::Adapter
].compact
end

private def attachments : Array(Hash(String, String))
files = [] of Hash(String, String)
email.attachments.map do |attachment|
case attachment
in AttachFile, ResourceFile
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what the difference between AttachFile and ResourceFile are, but I'm guessing it's related to SMTP and doesn't really matter in this case.

files.push({"content" => Base64.encode(File.read(attachment[:file_path])), "type" => attachment[:mime_type].to_s, "filename" => attachment[:file_name].to_s, "disposition" => "attachment"})
in AttachIO, ResourceIO
files.push({"content" => Base64.encode(attachment[:io].to_s), "type" => attachment[:mime_type].to_s, "filename" => attachment[:file_name].to_s, "disposition" => "attachment"})
end
end
files
end

private def text_content : Hash(String, String)?
body = email.text_body
if body && !body.empty?
Expand Down
Loading