Skip to content

Commit 59a8674

Browse files
committed
Rework the logic for sending emails
1 parent 3eaa9d2 commit 59a8674

17 files changed

+135
-121
lines changed

config/dev.exs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,14 @@ config :code_corps, CodeCorps.Mailer, adapter: Bamboo.LocalAdapter
6060

6161
config :code_corps,
6262
postmark_forgot_password_template: "123",
63+
postmark_message_initiated_by_project_template: "123",
6364
postmark_organization_invite_email_template: "123",
6465
postmark_project_approval_request_template: "123",
6566
postmark_project_approved_template: "123",
6667
postmark_project_user_acceptance_template: "123",
6768
postmark_project_user_request_template: "123",
68-
postmark_receipt_template: "123"
69+
postmark_receipt_template: "123",
70+
postmark_reply_to_conversation_template: "123"
6971

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

config/prod.exs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,14 @@ config :code_corps, CodeCorps.Mailer,
6161

6262
config :code_corps,
6363
postmark_forgot_password_template: "1989483",
64+
postmark_message_initiated_by_project_template: "4324242",
6465
postmark_organization_invite_email_template: "3441863",
6566
postmark_project_approval_request_template: "4105824",
6667
postmark_project_approved_template: "4105822",
6768
postmark_project_user_acceptance_template: "1447041",
6869
postmark_project_user_request_template: "4017262",
69-
postmark_receipt_template: "1255222"
70+
postmark_receipt_template: "1255222",
71+
postmark_reply_to_conversation_template: "4324082"
7072

7173
# ## SSL Support
7274
#

config/remote-development.exs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,14 @@ config :code_corps, CodeCorps.Mailer,
4444

4545
config :code_corps,
4646
postmark_forgot_password_template: "123",
47+
postmark_message_initiated_by_project_template: "123",
4748
postmark_organization_invite_email_template: "123",
4849
postmark_project_approval_request_template: "123",
4950
postmark_project_approved_template: "123",
5051
postmark_project_user_acceptance_template: "123",
5152
postmark_project_user_request_template: "123",
52-
postmark_receipt_template: "123"
53+
postmark_receipt_template: "123",
54+
postmark_reply_to_conversation_template: "123"
5355

5456
# ## SSL Support
5557
#

config/staging.exs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,14 @@ config :code_corps, CodeCorps.Mailer,
6060

6161
config :code_corps,
6262
postmark_forgot_password_template: "1989481",
63+
postmark_message_initiated_by_project_template: "4324241",
6364
postmark_organization_invite_email_template: "3442401",
6465
postmark_project_approval_request_template: "4105823",
6566
postmark_project_approved_template: "4105744",
6667
postmark_project_user_acceptance_template: "1447022",
6768
postmark_project_user_request_template: "4017261",
68-
postmark_receipt_template: "1252361"
69+
postmark_receipt_template: "1252361",
70+
postmark_reply_to_conversation_template: "4324243"
6971

7072
# ## SSL Support
7173
#

config/test.exs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,14 @@ config :code_corps, CodeCorps.Mailer,
6666

6767
config :code_corps,
6868
postmark_forgot_password_template: "123",
69+
postmark_message_initiated_by_project_template: "123",
6970
postmark_organization_invite_email_template: "123",
7071
postmark_project_approval_request_template: "123",
7172
postmark_project_approved_template: "123",
7273
postmark_project_user_acceptance_template: "123",
7374
postmark_project_user_request_template: "123",
74-
postmark_receipt_template: "123"
75+
postmark_receipt_template: "123",
76+
postmark_reply_to_conversation_template: "123"
7577

7678
config :code_corps, :cloudex, CloudexTest
7779
config :cloudex, api_key: "test_key", secret: "test_secret", cloud_name: "test_cloud_name"
File renamed without changes.

emails/message_for_project.html renamed to emails/reply_to_conversation.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head>
44
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
55
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6-
<title>You have a new message from {{name}}.</title>
6+
<title>{{author_name}} replied to your conversation in {{project_title}}.</title>
77
<!--
88
Make sure you copy the styles from styles.css into the email template in Postmark before saving there.
99
@@ -13,7 +13,7 @@
1313
<link rel="stylesheet" type="text/css" href="styles.css" media="screen" />
1414
</head>
1515
<body>
16-
<span class="preheader">You have a new message from {{name}}.</span>
16+
<span class="preheader">{{author_name}} replied to your conversation in {{project_title}}.</span>
1717
<table class="email-wrapper" width="100%" cellpadding="0" cellspacing="0">
1818
<tr>
1919
<td align="center">
@@ -44,9 +44,9 @@
4444
<p class="center">
4545
<img src="https://d3pgew4wbk2vb1.cloudfront.net/emails/images/[email protected]" width="100" height="100" />
4646
</p>
47-
<p>Hi {{project_title}} team,</p>
48-
<p>You have a new message from {{name}}.</p>
49-
<p><a class="button" href="{{conversation_url}}">See your message</a></p>
47+
<p>Hi {{name}},</p>
48+
<p>{{author_name}} replied to your conversation in {{project_title}}.</p>
49+
<p><a class="button" href="{{conversation_url}}">See your conversation</a></p>
5050
</td>
5151
</tr>
5252
</table>

lib/code_corps/emails/message_for_user_email.ex renamed to lib/code_corps/emails/message_initiated_by_project_email.ex

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
defmodule CodeCorps.Emails.MessageForUserEmail do
1+
defmodule CodeCorps.Emails.MessageInitiatedByProjectEmail do
22
import Bamboo.Email, only: [to: 2]
33
import Bamboo.PostmarkHelper
44

@@ -19,15 +19,15 @@ defmodule CodeCorps.Emails.MessageForUserEmail do
1919
BaseEmail.create
2020
|> to(user.email)
2121
|> template(template_id(), %{
22-
conversation_url: conversation |> conversation_url,
23-
project_title: project.title,
22+
conversation_url: conversation |> conversation_url(),
2423
name: user.first_name,
24+
project_title: project.title,
2525
subject: "You have a new message from #{project.title}"
2626
})
2727
end
2828

2929
@spec template_id :: String.t
30-
defp template_id, do: Application.get_env(:code_corps, :postmark_message_for_user_template)
30+
defp template_id, do: Application.get_env(:code_corps, :postmark_message_initiated_by_project_template)
3131

3232
@spec conversation_url(Conversation.t) :: String.t
3333
defp conversation_url(%Conversation{id: id}) do

lib/code_corps/emails/message_for_project_email.ex renamed to lib/code_corps/emails/reply_to_conversation_email.ex

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
defmodule CodeCorps.Emails.MessageForProjectEmail do
1+
defmodule CodeCorps.Emails.ReplyToConversationEmail do
22
import Bamboo.Email, only: [to: 2]
33
import Bamboo.PostmarkHelper
44

55
alias CodeCorps.{
66
Conversation,
7+
ConversationPart,
78
Emails.BaseEmail,
89
Message,
910
Organization,
@@ -12,24 +13,31 @@ defmodule CodeCorps.Emails.MessageForProjectEmail do
1213
WebClient
1314
}
1415

15-
@spec create(Message.t, Conversation.t, User.t) :: Bamboo.Email.t
16+
@spec create(ConversationPart.t, User.t) :: Bamboo.Email.t
1617
def create(
17-
%Message{project: %Project{} = project},
18-
%Conversation{} = conversation,
18+
%ConversationPart{
19+
author: %User{} = author,
20+
conversation: %Conversation{
21+
message: %Message{
22+
project: %Project{} = project
23+
}
24+
} = conversation
25+
},
1926
%User{} = user) do
2027

2128
BaseEmail.create
2229
|> to(user.email)
2330
|> template(template_id(), %{
31+
author_name: author.first_name,
2432
conversation_url: project |> conversation_url(conversation),
2533
name: user.first_name,
2634
project_title: project.title,
27-
subject: "#{user.first_name} has posted a reply on #{project.title}"
35+
subject: "#{author.first_name} replied to your conversation in #{project.title}"
2836
})
2937
end
3038

3139
@spec template_id :: String.t
32-
defp template_id, do: Application.get_env(:code_corps, :postmark_message_for_project_template)
40+
defp template_id, do: Application.get_env(:code_corps, :postmark_reply_to_conversation_template)
3341

3442
@spec conversation_url(Project.t, Conversation.t) :: String.t
3543
defp conversation_url(

lib/code_corps/messages/emails.ex

Lines changed: 26 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ defmodule CodeCorps.Messages.Emails do
33
Handles email notifications used within the Messages context
44
"""
55
alias CodeCorps.{
6-
Conversation,
76
ConversationPart,
87
Emails,
98
Mailer,
@@ -14,23 +13,23 @@ defmodule CodeCorps.Messages.Emails do
1413
@message_preloads [:project, [conversations: :user]]
1514

1615
@doc ~S"""
17-
Notifies all relevant users of a new `CodeCorps.Message` being created.
16+
Notifies all the recipients of a new `CodeCorps.Message`.
1817
19-
We match against admin initiated messages only, because it's unclear who
20-
message.author is for user-initiated messages, or who the email recipient
21-
would be, assuming the message.author is the user who initiated the message.
18+
Target recipients are found in the `user` relationship of each
19+
`CodeCorps.Conversation`.
2220
"""
23-
@spec notify_of_new_message(Message.t) :: :ok
24-
def notify_of_new_message(%Message{initiated_by: "admin"} = message) do
21+
@spec notify_message_targets(Message.t) :: :ok
22+
def notify_message_targets(%Message{initiated_by: "admin"} = message) do
2523
message = message |> Repo.preload(@message_preloads)
2624

2725
message
2826
|> Map.get(:conversations)
29-
|> Enum.map(&Emails.MessageForUserEmail.create(message, &1))
27+
|> Enum.map(&Emails.MessageInitiatedByProjectEmail.create(message, &1))
3028
|> Enum.each(&Mailer.deliver_now/1)
3129
end
3230

33-
@part_preloads [
31+
@cpart_preloads [
32+
:author,
3433
conversation: [
3534
[conversation_parts: :author],
3635
[message: [:author, [project: :organization]]],
@@ -39,55 +38,36 @@ defmodule CodeCorps.Messages.Emails do
3938
]
4039

4140
@doc ~S"""
42-
Notifies via email all relevant users when a new `CodeCorps.ConvrsationPart`
43-
has been added to a `CodeCorps.Conversation`.
41+
Notifies users via email when a `CodeCorps.ConversationPart` has been added
42+
to a `CodeCorps.Conversation`.
43+
44+
Sends to users participating in the conversation, excluding the author of the
45+
conversation part.
4446
"""
45-
@spec notify_of_new_reply(ConvrsationPart.t) :: :ok
47+
@spec notify_of_new_reply(ConversationPart.t) :: :ok
4648
def notify_of_new_reply(%ConversationPart{} = part) do
47-
part = part |> Repo.preload(@part_preloads)
48-
49-
part |> maybe_send_message_for_user_email()
50-
part |> send_message_for_project_emails()
49+
part = part |> Repo.preload(@cpart_preloads)
50+
part |> send_reply_to_conversation_emails()
5151
end
5252

5353
# we match against admin initiated only, because it's unclear who
5454
# message.author is for user-initiated messages, or who the email recipient
5555
# would be, assuming the message.author is the user who initiated the message
56-
@spec send_message_for_project_emails(ConversationPart.t) :: :ok
57-
defp send_message_for_project_emails(%ConversationPart{
58-
conversation: %Conversation{
59-
message: %Message{initiated_by: "admin"} = message
60-
} = conversation
61-
} = part) do
62-
56+
@spec send_reply_to_conversation_emails(ConversationPart.t) :: :ok
57+
defp send_reply_to_conversation_emails(%ConversationPart{} = part) do
6358
part
64-
|> get_project_participants()
65-
|> Enum.map(&Emails.MessageForProjectEmail.create(message, conversation, &1))
59+
|> get_conversation_participants()
60+
|> Enum.map(&Emails.ReplyToConversationEmail.create(part, &1))
6661
|> Enum.each(&Mailer.deliver_now/1)
6762
end
6863

69-
# we match against admin initiated only, because it's unclear who
70-
# message.author is for user-initiated messages, or who the email recipient
71-
# would be, assuming the message.author is the user who initiated the message
72-
@spec maybe_send_message_for_user_email(ConversationPart.t) :: Bambo.Email.t | nil
73-
defp maybe_send_message_for_user_email(%ConversationPart{
74-
author_id: replier_id,
75-
conversation: %Conversation{
76-
user_id: conversation_target_id,
77-
message: %Message{initiated_by: "admin"} = message
78-
} = conversation
79-
}) when replier_id != conversation_target_id do
80-
81-
message
82-
|> Emails.MessageForUserEmail.create(conversation)
83-
|> Mailer.deliver_now
84-
end
85-
defp maybe_send_message_for_user_email(%ConversationPart{}), do: nil
86-
87-
@spec get_project_participants(ConversationPart.t) :: list(User.t)
88-
defp get_project_participants(%ConversationPart{author_id: author_id} = part) do
89-
part.conversation.conversation_parts |> Enum.map(&Map.get(&1, :author))
64+
@spec get_conversation_participants(ConversationPart.t) :: list(User.t)
65+
defp get_conversation_participants(%ConversationPart{author_id: author_id} = part) do
66+
part.conversation.conversation_parts
67+
|> Enum.map(&Map.get(&1, :author))
68+
|> Enum.concat([part.conversation.user])
9069
|> Enum.concat([part.conversation.message.author])
9170
|> Enum.reject(fn u -> u.id == author_id end)
71+
|> Enum.uniq()
9272
end
9373
end

0 commit comments

Comments
 (0)