Mahira
Mahira

Reputation: 113

How to make send_mail function send bcc emails - Django REST API

I want to send notifications to everybody (except a message author) in the chat if there is a new message in the chat. I want to send one email to all, so that nobody can see the others' email addresses (bcc-blind carbon copy). How can I do so?

Here is my view:

class WriteMessageCreateAPIView(generics.CreateAPIView):
    permission_classes = [IsAuthenticated, IsParticipant]
    serializer_class = MessageSerializer

def perform_create(self, serializer):
    ...
    chat = serializer.validated_data['chat']
    chat_recipients = chat.participants.exclude(id=self.request.user.id)

    for participant in chat_recipients:
        MessageRecipient.objects.create(message_id=new_message.id, recipient_id=participant.id)

    send_new_message_notification(chat.id, new_message.author, chat_recipients)

Here an email is sent to all recipients at once, but in cc form (everybody can see each others' email addresses).

Here is send_mail function:

def send_new_message_notification(chat_id, sender: User, recipients):
    link = BASE_URL + '/messaging/chat/%s/messages' % chat_id
    send_email(
        subject='You have a new message',
        message='Click the link below to view the message:', link),
        from_email='[email protected]',
        recipient_list=recipients
)

Yes, I could do like this in a view part:

for participant in chat_recipients:
        MessageRecipient.objects.create(message_id=new_message.id, recipient_id=participant.id)
        send_new_message_notification(chat.id, new_message.author, participant)

And send one by one, but it is not efficient.

So the question is: is there any method to send an email with to all recipients at once so that they are not able to see each others' email addresses?

Upvotes: 0

Views: 653

Answers (1)

tim-mccurrach
tim-mccurrach

Reputation: 6815

Yes. Django has a send_mass_mail function for exactly this purpose. You can check out the docs here.

# This is more efficient, because it hits the database only
# once instead of once for each new MessageRecipient
message_recipients = [MessageRecipient(message_id=new_message.id, recipient_id=participant.id) for participant in chat_recipients]
MessageRecipient.objects.bulk_create(message_recipients)

# This will send separate emails, but will only make
# one connection with the email server so it will be
# more efficient
link = BASE_URL + '/messaging/chat/%s/messages' % chat.id
emails = (('You have a new message',
           f'Click the link below to view the message: {link}', 
           '[email protected]',
           [recepient]
           ) for recepient in chat_recepients)
send_mass_mail(emails, fail_silently=False)

Upvotes: 1

Related Questions