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.views import generic
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.shortcuts import get_object_or_404, render
|
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.core.exceptions import PermissionDenied
|
||||||
from django.contrib import messages
|
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth import authenticate, login
|
from django.contrib.auth import authenticate, login
|
||||||
from django.utils.timezone import now
|
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 .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):
|
def send_one_time_login_mail(secret, mail, request):
|
||||||
|
|
@ -216,11 +216,15 @@ class RegisterDeviceFormView(generic.edit.FormView):
|
||||||
device.save()
|
device.save()
|
||||||
|
|
||||||
guest = Guest.objects.filter(mail=mail).first()
|
guest = Guest.objects.filter(mail=mail).first()
|
||||||
|
user = CustomUser.objects.filter(email=mail).first()
|
||||||
|
|
||||||
if guest:
|
if guest and user:
|
||||||
device.guest = guest
|
device.guest = guest
|
||||||
device.save()
|
device.save()
|
||||||
|
|
||||||
|
guest.user = user
|
||||||
|
guest.save()
|
||||||
|
|
||||||
send_confirmation_mails(device, guest, cafe, self.request)
|
send_confirmation_mails(device, guest, cafe, self.request)
|
||||||
|
|
||||||
resp = HttpResponseRedirect(
|
resp = HttpResponseRedirect(
|
||||||
|
|
@ -407,14 +411,15 @@ def cron(request):
|
||||||
"""
|
"""
|
||||||
View to trigger automated regular tasks.
|
View to trigger automated regular tasks.
|
||||||
"""
|
"""
|
||||||
pass
|
return HttpResponse('done.')
|
||||||
|
|
||||||
|
|
||||||
def process_mails(request):
|
def process_mails(request):
|
||||||
"""
|
"""
|
||||||
View to trigger processing of email in inbox.
|
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):
|
def one_time_login(request, secret: str):
|
||||||
|
|
|
||||||
|
|
@ -11,3 +11,4 @@ mozilla-django-oidc==3.0.0
|
||||||
djlint==1.23.3
|
djlint==1.23.3
|
||||||
django-import-export==3.2.0
|
django-import-export==3.2.0
|
||||||
selenium==4.9.0
|
selenium==4.9.0
|
||||||
|
imap-tools==1.0.0
|
||||||
|
|
|
||||||
|
|
@ -5,3 +5,4 @@ crispy-bootstrap4==2022.1
|
||||||
crispy-bootstrap5==0.7
|
crispy-bootstrap5==0.7
|
||||||
mozilla-django-oidc==3.0.0
|
mozilla-django-oidc==3.0.0
|
||||||
django-import-export==3.2.0
|
django-import-export==3.2.0
|
||||||
|
imap-tools==1.0.0
|
||||||
|
|
|
||||||
Reference in a new issue