Processes an event of the given details, returning a (success, message) tuple

def process_event(message_id, event_type, event_detail, timestamp):
    """
    Processes an event of the given details, returning a (success, message) tuple
    """
    # Load message
    try:
        message = Outbound.objects.select_related("channel").get(
            vumi_message_id=message_id
        )
    except ObjectDoesNotExist:
        return (False, "Cannot find message for ID {}".format(message_id))

    if event_type == "ack":
        message.delivered = True
        message.to_addr = ""
        message.metadata["ack_timestamp"] = timestamp
        message.metadata["ack_reason"] = event_detail
        message.save(update_fields=["delivered", "to_addr", "metadata"])
    elif event_type == "nack":
        message.metadata["nack_timestamp"] = timestamp
        message.metadata["nack_reason"] = event_detail
        message.save(update_fields=["metadata"])

        decr_message_count(message)

        send_message.delay(str(message.id))
    elif event_type == "delivery_succeeded":
        message.delivered = True
        message.to_addr = ""
        message.metadata["delivery_timestamp"] = timestamp
        message.metadata["delivery_reason"] = event_detail
        message.save(update_fields=["delivered", "metadata", "to_addr"])
    elif event_type == "delivery_failed":
        message.metadata["delivery_failed_reason"] = event_detail
        message.metadata["delivery_failed_timestamp"] = timestamp
        message.save(update_fields=["metadata"])

        decr_message_count(message)

        send_message.delay(str(message.id))
    elif event_type == "read":
        message.delivered = True
        message.to_addr = ""
        message.metadata["read_timestamp"] = timestamp
        message.save(update_fields=["delivered", "to_addr", "metadata"])

    outbound_event_total.labels(event_type, message.channel_id).inc()
    fire_delivery_hook(message)

    return (True, "Event processed")