initial message processing
This commit is contained in:
parent
82d752c677
commit
61e543b1b0
4 changed files with 110 additions and 7 deletions
96
rc_hip/repapp/mail_interface.py
Normal file
96
rc_hip/repapp/mail_interface.py
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import os
|
||||
import re
|
||||
import logging
|
||||
from imap_tools import MailBox, AND, MailMessage
|
||||
from django.core.mail import send_mail
|
||||
from .models import Guest, Message, Question, Organisator
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def send_message_notification(message: Message, guest: Guest):
|
||||
"""
|
||||
Send new message notification.
|
||||
"""
|
||||
organizers = []
|
||||
for organizer in Organisator.objects.all():
|
||||
organizers.append(organizer.mail)
|
||||
|
||||
subject = f'Neue Nachricht von Gast {guest.name} ({guest.mail})'
|
||||
text = f'Hallo,\n'
|
||||
f'der Gast {guest.name} ({guest.mail}) hat folgende Nachricht gesendet:\n\n'
|
||||
f'{message.message}'
|
||||
# TODO: add attachments
|
||||
# TODO: add link to message
|
||||
|
||||
send_mail(
|
||||
subject=subject,
|
||||
message=text,
|
||||
from_email=os.getenv("DJANGO_SENDER_ADDRESS", ""),
|
||||
recipient_list=organizers,
|
||||
fail_silently=True
|
||||
)
|
||||
|
||||
|
||||
def process_message(message: MailMessage, guest: Guest):
|
||||
"""
|
||||
Process a valid message from a guest.
|
||||
"""
|
||||
content = message.text
|
||||
if message.html:
|
||||
content = message.html
|
||||
|
||||
result = re.search('Q#([0-9]+):', message.subject)
|
||||
if result:
|
||||
question_pk = result.group(1)
|
||||
question = Question.objects.filter(pk=question_pk).first()
|
||||
if question:
|
||||
if question.device.guest.mail == message.from_:
|
||||
question.answer = content
|
||||
question.save()
|
||||
# TODO: save attachments and add to message
|
||||
logger.info(
|
||||
f'Valid answer for Question {question_pk} from {message.from_} received.')
|
||||
# TODO: send notifications
|
||||
else:
|
||||
logger.warning(
|
||||
f'Answer for Question {question_pk} from {message.from_} received,'
|
||||
' but the question was not for this guest. Message was ignored.')
|
||||
# TODO: send reply that mail address was wrong
|
||||
else:
|
||||
logger.warning(
|
||||
f'Answer for Question {question_pk} from {message.from_} received,'
|
||||
' but there is no such question. Message was ignored.')
|
||||
else:
|
||||
db_message = Message(
|
||||
message=content,
|
||||
guest=guest,
|
||||
)
|
||||
db_message.save()
|
||||
send_message_notification(message, guest)
|
||||
|
||||
|
||||
def process_mails():
|
||||
"""
|
||||
Check for new messages and handle valid messages.
|
||||
"""
|
||||
host = os.getenv("DJANGO_EMAIL_HOST", "")
|
||||
user = os.getenv("DJANGO_EMAIL_HOST_USER", None)
|
||||
password = os.getenv("DJANGO_EMAIL_HOST_PASSWORD", None)
|
||||
mailbox = MailBox(host).login(user, password)
|
||||
messages = mailbox.fetch(criteria=AND(seen=False),
|
||||
mark_seen=True, bulk=True)
|
||||
|
||||
message_count = 0
|
||||
for message in messages:
|
||||
message_count += 1
|
||||
sender = message.from_
|
||||
guest = Guest.objects.filter(mail=sender).first()
|
||||
if guest:
|
||||
process_message(message, guest)
|
||||
else:
|
||||
logger.warning(
|
||||
'Mail form unknown sender %s with subject %s ignored.'
|
||||
% (sender, message.subject))
|
||||
|
||||
return message_count
|
||||
|
|
@ -14,15 +14,15 @@ from django.contrib import messages
|
|||
from django.views import generic
|
||||
from django.urls import reverse_lazy
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.http import HttpResponseRedirect, HttpResponse
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth import authenticate, login
|
||||
from django.utils.timezone import now
|
||||
from repapp.models import CustomUser, Organisator, Reparateur
|
||||
from .models import Cafe, Device, Guest, OneTimeLogin
|
||||
from .forms import RegisterDevice, RegisterGuest
|
||||
from .models import (Cafe, Device, Guest, OneTimeLogin,
|
||||
CustomUser, Organisator, Reparateur)
|
||||
from . import mail_interface
|
||||
|
||||
|
||||
def send_one_time_login_mail(secret, mail, request):
|
||||
|
|
@ -216,11 +216,15 @@ class RegisterDeviceFormView(generic.edit.FormView):
|
|||
device.save()
|
||||
|
||||
guest = Guest.objects.filter(mail=mail).first()
|
||||
user = CustomUser.objects.filter(email=mail).first()
|
||||
|
||||
if guest:
|
||||
if guest and user:
|
||||
device.guest = guest
|
||||
device.save()
|
||||
|
||||
guest.user = user
|
||||
guest.save()
|
||||
|
||||
send_confirmation_mails(device, guest, cafe, self.request)
|
||||
|
||||
resp = HttpResponseRedirect(
|
||||
|
|
@ -407,14 +411,15 @@ def cron(request):
|
|||
"""
|
||||
View to trigger automated regular tasks.
|
||||
"""
|
||||
pass
|
||||
return HttpResponse('done.')
|
||||
|
||||
|
||||
def process_mails(request):
|
||||
"""
|
||||
View to trigger processing of email in inbox.
|
||||
"""
|
||||
pass
|
||||
count = mail_interface.process_mails()
|
||||
return HttpResponse(f'Done. Processed {count} messages.')
|
||||
|
||||
|
||||
def one_time_login(request, secret: str):
|
||||
|
|
|
|||
|
|
@ -11,3 +11,4 @@ mozilla-django-oidc==3.0.0
|
|||
djlint==1.23.3
|
||||
django-import-export==3.2.0
|
||||
selenium==4.9.0
|
||||
imap-tools==1.0.0
|
||||
|
|
|
|||
|
|
@ -5,3 +5,4 @@ crispy-bootstrap4==2022.1
|
|||
crispy-bootstrap5==0.7
|
||||
mozilla-django-oidc==3.0.0
|
||||
django-import-export==3.2.0
|
||||
imap-tools==1.0.0
|
||||
|
|
|
|||
Reference in a new issue