Hello Django users,

I want to receive mails from mailgun in a Django web application. I have 
problem with parsing the data to the form. As you can see, in the froms.py 
there is a field_map, to convert the fields Mailgun sends to the model 
fields. This is not working. All fields that are not converted I receive, 
but for example the from field I cannot retrieve. I have installed Django 
1.8 and Python2.7. The code is from
https://github.com/hedberg/django-mailgun-incoming I think this would work 
for Django < 1.8, because in Django 1.8 is introduced the obligation to 
specify the fields. In older versions, omitting both fields and exclude 
resulted in a form with all the model’s fields. Doing this now raises an 
ImproperlyConfigured exception.Hope someone can help me. Thanks in advance

Here is the link to Mailgun for more information 
https://documentation.mailgun.com/user_manual.html#routes
forms.py

from django import forms
from models import EmailBaseModel

class EmailForm(forms.ModelForm):
    field_map = {'from_str':'from',
                 'body_plain':'body-plain',
                 'body_html':'body-html',
                 'stripped_text':'stripped-text',
                 'stripped_html':'stripped-html',
                 'message_headers':'message-headers',
                 'stripped_signature':'stripped-signature',
                 'content_id_map':'content-id-map'}

    class Meta:
    #    model = EmailBaseModel
        fields = '__all__'    

    def __init__(self, *args, **kwargs):
        super(EmailForm, self).__init__(*args, **kwargs)
        for (field_name, form_key) in self.field_map.items():
            self.fields[form_key] = self.fields[field_name]
            del self.fields[field_name]
        self.fields['attachment-count'] = forms.IntegerField(required=False)
        
    def clean(self):
        for (field_name, form_key) in self.field_map.items():
            if form_key in self.cleaned_data:
                self.cleaned_data[field_name] = self.cleaned_data[form_key]
        return self.cleaned_data

views.py

# -*- coding: utf-8 -*-import hashlib, hmacimport logging#import pdb
from django.conf import settings
from django.http import HttpResponse, HttpResponseBadRequest
from django.forms.models import modelform_factory
from django.views.generic.base import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from mailgun_incoming.models import Attachment, IncomingEmail
from mailgun_incoming.signals import email_received
from mailgun_incoming.forms import EmailForm

logger = logging.getLogger(__name__)

API_KEY = getattr(settings, "MAILGUN_ACCESS_KEY", "")
VERIFY_SIGNATURE = getattr(settings, "MAILGUN_VERIFY_INCOMING", API_KEY!="")
class Incoming(View):
    #pdb.set_trace()
    email_model = IncomingEmail
    attachment_model = Attachment
    form = EmailForm
    api_key = API_KEY
    verify = VERIFY_SIGNATURE
    
    def get_form(self):
        return modelform_factory(self.email_model, form=self.form)
    
    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(Incoming, self).dispatch(*args, **kwargs)
    
    def post(self, request, *args, **kwargs):
        if self.verify:
            verified = self.verify_signature(request.POST.get('token',''),
                              request.POST.get('timestamp',''),
                              request.POST.get('signature',''))
            if not verified:
                logger.debug("Signature verification failed. Email posted from 
%s. %s" % (
                              request.META.get('REMOTE_ADDR','<no remote 
addr>'),
                              request.POST.get('subject', '')))
                return HttpResponseBadRequest("Invalid signature")
                
        form = self.get_form()(request.POST)
        
        if form.is_valid():
            #save email
            
            email = form.save()
            #save attachments
            attachments = []
            if form.cleaned_data.get('attachment-count',0):
                attachments = []
                #reverse mapping in content_ids dict
                content_ids = dict((attnr,cid) for cid,attnr in 
(email.content_ids or {}).iteritems())
                i = 1
                for file in request.FILES.values():
                    attachment = self.attachment_model(email=email, file=file, 
content_id=content_ids.get('attachment-{0!s}'.format(i),'')).save()
                    attachments.append(attachment)
                    i += 1
            self.handle_email(email, attachments=attachments)
        else:
            logger.debug("Received email message contained errors. %s" % 
form.errors)
        
        return HttpResponse("OK")
    
    def handle_email(self, email, attachments=None):
        email_received.send(sender=self.email_model, instance=email, 
attachments=attachments or [])
    
    def verify_signature(self, token, timestamp, signature):
        return signature == hmac.new(key=self.api_key,
                                 msg='{0}{1}'.format(timestamp, token),
                                 digestmod=hashlib.sha256).hexdigest()

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/13e083da-7998-425d-839d-82d8fbfe0b4d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to