mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 03:41:05 -05:00
AnymailInternalEvent had some properties that were actually implemented in AnymailInboundMessage. The event versions were never documented, and never contained useful data (they were always set to None).
90 lines
3.9 KiB
Python
90 lines
3.9 KiB
Python
from django.dispatch import Signal
|
|
|
|
|
|
# Outbound message, before sending
|
|
pre_send = Signal(providing_args=['message', 'esp_name'])
|
|
|
|
# Outbound message, after sending
|
|
post_send = Signal(providing_args=['message', 'status', 'esp_name'])
|
|
|
|
# Delivery and tracking events for sent messages
|
|
tracking = Signal(providing_args=['event', 'esp_name'])
|
|
|
|
# Event for receiving inbound messages
|
|
inbound = Signal(providing_args=['event', 'esp_name'])
|
|
|
|
|
|
class AnymailEvent(object):
|
|
"""Base class for normalized Anymail webhook events"""
|
|
|
|
def __init__(self, event_type, timestamp=None, event_id=None, esp_event=None, **kwargs):
|
|
self.event_type = event_type # normalized to an EventType str
|
|
self.timestamp = timestamp # normalized to an aware datetime
|
|
self.event_id = event_id # opaque str
|
|
self.esp_event = esp_event # raw event fields (e.g., parsed JSON dict or POST data QueryDict)
|
|
|
|
|
|
class AnymailTrackingEvent(AnymailEvent):
|
|
"""Normalized delivery and tracking event for sent messages"""
|
|
|
|
def __init__(self, **kwargs):
|
|
super(AnymailTrackingEvent, self).__init__(**kwargs)
|
|
self.click_url = kwargs.pop('click_url', None) # str
|
|
self.description = kwargs.pop('description', None) # str, usually human-readable, not normalized
|
|
self.message_id = kwargs.pop('message_id', None) # str, format may vary
|
|
self.metadata = kwargs.pop('metadata', {}) # dict
|
|
self.mta_response = kwargs.pop('mta_response', None) # str, may include SMTP codes, not normalized
|
|
self.recipient = kwargs.pop('recipient', None) # str email address (just the email portion; no name)
|
|
self.reject_reason = kwargs.pop('reject_reason', None) # normalized to a RejectReason str
|
|
self.tags = kwargs.pop('tags', []) # list of str
|
|
self.user_agent = kwargs.pop('user_agent', None) # str
|
|
|
|
|
|
class AnymailInboundEvent(AnymailEvent):
|
|
"""Normalized inbound message event"""
|
|
|
|
def __init__(self, **kwargs):
|
|
super(AnymailInboundEvent, self).__init__(**kwargs)
|
|
self.message = kwargs.pop('message', None) # anymail.inbound.AnymailInboundMessage
|
|
|
|
|
|
class EventType:
|
|
"""Constants for normalized Anymail event types"""
|
|
|
|
# Delivery (and non-delivery) event types:
|
|
# (these match message.ANYMAIL_STATUSES where appropriate)
|
|
QUEUED = 'queued' # the ESP has accepted the message and will try to send it (possibly later)
|
|
SENT = 'sent' # the ESP has sent the message (though it may or may not get delivered)
|
|
REJECTED = 'rejected' # the ESP refused to send the messsage (e.g., suppression list, policy, invalid email)
|
|
FAILED = 'failed' # the ESP was unable to send the message (e.g., template rendering error)
|
|
|
|
BOUNCED = 'bounced' # rejected or blocked by receiving MTA
|
|
DEFERRED = 'deferred' # delayed by receiving MTA; should be followed by a later BOUNCED or DELIVERED
|
|
DELIVERED = 'delivered' # accepted by receiving MTA
|
|
AUTORESPONDED = 'autoresponded' # a bot replied
|
|
|
|
# Tracking event types:
|
|
OPENED = 'opened' # open tracking
|
|
CLICKED = 'clicked' # click tracking
|
|
COMPLAINED = 'complained' # recipient reported as spam (e.g., through feedback loop)
|
|
UNSUBSCRIBED = 'unsubscribed' # recipient attempted to unsubscribe
|
|
SUBSCRIBED = 'subscribed' # signed up for mailing list through ESP-hosted form
|
|
|
|
# Inbound event types:
|
|
INBOUND = 'inbound' # received message
|
|
INBOUND_FAILED = 'inbound_failed'
|
|
|
|
# Other:
|
|
UNKNOWN = 'unknown' # anything else
|
|
|
|
|
|
class RejectReason:
|
|
"""Constants for normalized Anymail reject/drop reasons"""
|
|
INVALID = 'invalid' # bad address format
|
|
BOUNCED = 'bounced' # (previous) bounce from recipient
|
|
TIMED_OUT = 'timed_out' # (previous) repeated failed delivery attempts
|
|
BLOCKED = 'blocked' # ESP policy suppression
|
|
SPAM = 'spam' # (previous) spam complaint from recipient
|
|
UNSUBSCRIBED = 'unsubscribed' # (previous) unsubscribe request from recipient
|
|
OTHER = 'other'
|