Skip to content

Commit f1fdef9

Browse files
committed
Send an email when an organiation invite is created
1 parent c7d0527 commit f1fdef9

9 files changed

Lines changed: 184 additions & 8 deletions

File tree

blueprint/api.apib

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,8 @@ This endpoint is for Creating, Updating, returning Organization Invites on Code
515515

516516
Admin creates new organization invites which contains `email` and `title`. A `code` is automatically generated on creation and `fulfilled` is set to false.
517517

518+
On successful creation an email is sent to the given `email` address.
519+
518520
+ Request
519521

520522
+ Headers

config/dev.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ config :code_corps, CodeCorps.Mailer,
6262
config :code_corps,
6363
postmark_forgot_password_template: "123",
6464
postmark_project_acceptance_template: "123",
65-
postmark_receipt_template: "123"
65+
postmark_receipt_template: "123",
66+
postmark_organization_invite_email_template: "123"
6667

6768
# If the dev environment has no CLOUDEX_API_KEY set, we want the app
6869
# to still run, with cloudex in test API mode

config/prod.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ config :code_corps, CodeCorps.Mailer,
6363
config :code_corps,
6464
postmark_forgot_password_template: "1989483",
6565
postmark_project_acceptance_template: "1447041",
66-
postmark_receipt_template: "1255222"
66+
postmark_receipt_template: "1255222",
67+
postmark_organization_invite_email_template: "3441863"
6768

6869
# ## SSL Support
6970
#

config/staging.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ config :code_corps, CodeCorps.Mailer,
6161
config :code_corps,
6262
postmark_forgot_password_template: "1989481",
6363
postmark_project_acceptance_template: "1447022",
64-
postmark_receipt_template: "1252361"
64+
postmark_receipt_template: "1252361",
65+
postmark_organization_invite_email_template: "3442401"
6566

6667
# ## SSL Support
6768
#

emails/organization_invite.html

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2+
<html xmlns="http://www.w3.org/1999/xhtml">
3+
<head>
4+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
5+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6+
<title>Create your first project on Code Corps.</title>
7+
<!--
8+
Make sure you copy the styles from styles.css into the email template in Postmark before saving there.
9+
10+
<style type="text/css" rel="stylesheet" media="all">
11+
</style>
12+
-->
13+
<link rel="stylesheet" type="text/css" href="styles.css" media="screen" />
14+
</head>
15+
<body>
16+
<span class="preheader">Create your first project on Code Corps.</span>
17+
<table class="email-wrapper" width="100%" cellpadding="0" cellspacing="0">
18+
<tr>
19+
<td align="center">
20+
<table class="email-content" width="100%" cellpadding="0" cellspacing="0">
21+
<tr>
22+
<td class="email-masthead" width="100%" cellpadding="0" cellspacing="0">
23+
<table class="email-masthead_inner" align="center" width="570" cellpadding="0" cellspacing="0">
24+
<tr>
25+
<td>
26+
<a href="https://www.codecorps.org">
27+
<img src="https://d3pgew4wbk2vb1.cloudfront.net/emails/images/logo-small@2x.png" class="email-masthead_logo" />
28+
</a>
29+
</td>
30+
</tr>
31+
</table>
32+
</td>
33+
</tr>
34+
<!-- Email Body -->
35+
<tr>
36+
<td class="email-body" width="100%" cellpadding="0" cellspacing="0">
37+
<table class="email-body_inner" align="center" width="570" cellpadding="0" cellspacing="0">
38+
<!-- Body content -->
39+
<tr>
40+
<td class="content-cell">
41+
<table width="100%" cellpadding="0" cellspacing="0">
42+
<tr>
43+
<td>
44+
<p>Hi {{title}},</p>
45+
<p>You've just been invited to add your first project on Code Corps.</p>
46+
<p>To create your project, please <a href="{{url}}">click here</a> or paste this link into your browser:</p>
47+
<p><a href="{{url}}">{{url}}</a></p>
48+
<p>If you have any issues, don't hesitate to <a href="https://help.codecorps.org">contact us</a>.</p>
49+
</td>
50+
</tr>
51+
</table>
52+
<table class="body-signature">
53+
<tr>
54+
<td>
55+
<p>
56+
Thanks!
57+
<br><strong>The Code Corps Team</strong>
58+
</p>
59+
<p class="center small">
60+
Questions? Feedback?
61+
<br>Visit our <strong><a href="https://help.codecorps.org">Help Center</a></strong> or just reply to this email.</p>
62+
</td>
63+
</tr>
64+
</table>
65+
</td>
66+
</tr>
67+
</table>
68+
</td>
69+
</tr>
70+
<tr>
71+
<td>
72+
<table class="email-footer" align="center" width="570" cellpadding="0" cellspacing="0">
73+
<tr>
74+
<td class="content-cell" align="center">
75+
<p class="sub align-center">
76+
Code Corps PBC
77+
<br>4166 Wilson Ave #1
78+
<br>San Diego, CA 92104
79+
</p>
80+
</td>
81+
</tr>
82+
</table>
83+
</td>
84+
</tr>
85+
</table>
86+
</td>
87+
</tr>
88+
</table>
89+
</body>
90+
</html>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
defmodule CodeCorps.Emails.OrganizationInviteEmail do
2+
import Bamboo.Email
3+
import Bamboo.PostmarkHelper
4+
5+
alias CodeCorps.{OrganizationInvite}
6+
alias CodeCorps.Emails.BaseEmail
7+
8+
def create(%OrganizationInvite{} = organization_invite) do
9+
BaseEmail.create
10+
|> to(organization_invite.email)
11+
|> template(template_id(), build_model(organization_invite))
12+
end
13+
14+
defp build_model(%OrganizationInvite{} = organization_invite) do
15+
%{
16+
title: organization_invite.title,
17+
url: url(organization_invite.title, organization_invite.code),
18+
subject: "Create your first project on Code Corps"
19+
}
20+
end
21+
22+
defp url(title, code) do
23+
Application.get_env(:code_corps, :site_url)
24+
|> URI.merge("/invites/organization" <> "?" <> set_params(code, title))
25+
|> URI.to_string
26+
end
27+
28+
defp set_params(code, title) do
29+
%{code: code, organization_title: title }
30+
|> URI.encode_query
31+
end
32+
33+
defp template_id, do: Application.get_env(:code_corps, :organization_invite_email_template)
34+
end

lib/code_corps_web/controllers/organization_invite_controller.ex

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ defmodule CodeCorpsWeb.OrganizationInviteController do
33
use JaResource
44

55
import CodeCorps.Helpers.Query, only: [id_filter: 2]
6-
7-
alias CodeCorps.OrganizationInvite
6+
alias CodeCorps.{Emails, Mailer, OrganizationInvite}
87

98
plug :load_and_authorize_resource, model: OrganizationInvite, only: [:create, :update]
109
plug JaResource
@@ -19,4 +18,17 @@ defmodule CodeCorpsWeb.OrganizationInviteController do
1918
def handle_create(_conn, attributes) do
2019
OrganizationInvite.create_changeset(%OrganizationInvite{}, attributes)
2120
end
22-
end
21+
22+
def render_create(conn, model) do
23+
send_email(model)
24+
conn
25+
|> put_status(:created)
26+
|> Phoenix.Controller.render(:show, data: model)
27+
end
28+
29+
defp send_email(organization_invite) do
30+
organization_invite
31+
|> Emails.OrganizationInviteEmail.create()
32+
|> Mailer.deliver_later()
33+
end
34+
end
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
defmodule CodeCorps.Emails.OrganizationInviteEmailTest do
2+
use CodeCorps.ModelCase
3+
use Bamboo.Test
4+
5+
alias CodeCorps.Emails.OrganizationInviteEmail
6+
7+
test "organization email invite works" do
8+
organization_invite = insert(:organization_invite)
9+
email = OrganizationInviteEmail.create(organization_invite)
10+
11+
assert email.from == "Code Corps<team@codecorps.org>"
12+
assert email.to == organization_invite.email
13+
14+
template_model = email.private.template_model
15+
params =
16+
%{code: organization_invite.code, organization_title: organization_invite.title}
17+
|> URI.encode_query
18+
19+
assert template_model == %{
20+
title: organization_invite.title,
21+
url: "#{Application.get_env(:code_corps, :site_url)}/invites/organization?#{params}",
22+
subject: "Create your first project on Code Corps"
23+
}
24+
end
25+
end
26+

test/lib/code_corps_web/controllers/organization_invite_controller_test.exs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
defmodule CodeCorpsWeb.OrganizationInviteControllerTest do
22
use CodeCorpsWeb.ApiCase, resource_name: :organization_invite
3+
use Bamboo.Test
34

45
@valid_attrs %{email: "code@corps.com", title: "Code Corps"}
56
@invalid_attrs %{email: "code", title: ""}
@@ -32,8 +33,16 @@ defmodule CodeCorpsWeb.OrganizationInviteControllerTest do
3233

3334
describe "create" do
3435
@tag authenticated: :admin
35-
test "creates and renders resource when data is valid", %{conn: conn} do
36+
test "creates and renders resource when data is valid, sends valid email", %{conn: conn} do
3637
assert conn |> request_create(@valid_attrs) |> json_response(201)
38+
39+
organization_invite_email =
40+
CodeCorps.OrganizationInvite
41+
|> first()
42+
|> Repo.one()
43+
|> CodeCorps.Emails.OrganizationInviteEmail.create()
44+
45+
assert_delivered_email organization_invite_email
3746
end
3847

3948
@tag authenticated: :admin
@@ -61,4 +70,4 @@ defmodule CodeCorpsWeb.OrganizationInviteControllerTest do
6170
assert conn |> request_update(:not_found) |> json_response(404)
6271
end
6372
end
64-
end
73+
end

0 commit comments

Comments
 (0)