---
url: "https://vueda.dev/v3/reference/api/py/vueda.vdq.handlers.md"
title: "vdq.handlers"
---

# vdq.handlers

## Overview

Email and SMS send handlers and Twilio webhook processing for the VDQ.

## Classes

- [TwilioQueueItemHandler](/v3/reference/api/py/vueda.vdq.handlers/TwilioQueueItemHandler.md)

## `handle_bounce` {#handle_bounce}

Anymail tracking signal receiver. Processes ESP delivery events (delivered, bounced,
rejected, failed, deferred) and transitions the matching ``QueueItem`` accordingly.
An event finds its item by ``message_id`` first, then through the configured
``EmailTrackingStrategy``, which also stores the ``message_id`` on an item that has none.
Logs a warning for an event that finds no item and an error for unhandled exceptions.

### Signature {#handle_bounce-signature}

`handle_bounce(sender, event, esp_name, kwargs)`

#### Parameters {#handle_bounce-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="handle_bounce-param-sender">sender</span> |  | yes |  |  |
| <span id="handle_bounce-param-event">event</span> |  | yes |  |  |
| <span id="handle_bounce-param-esp_name">esp_name</span> |  | yes |  |  |
| <span id="handle_bounce-param-kwargs">kwargs</span> |  | no |  |  |

### Source {#handle_bounce-source}

`server/vueda/vdq/handlers.py:391`

## `send_email` {#send_email}

Send the email for a ``QueueItem``. Validates sender and receiver email addresses, attaches inline
images and regular attachments, adds the tracking data from the configured ``EmailTrackingStrategy``,
then sends via Anymail. Anymail raises ``AnymailUnsupportedFeature`` while it builds the request when
the ESP accepts no such data, so the email is then sent once more without it.
Transitions the queue item to ``await`` on success, or ``error`` on permanent failure. A status update
that reached the item first keeps the state and ``result`` it set.
Transient ESP errors (5xx, 408, 423, 429) raise ``AnymailTransientError`` for retry.

### Signature {#send_email-signature}

`send_email(qi)`

#### Parameters {#send_email-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="send_email-param-qi">qi</span> |  | yes |  |  |

### Source {#send_email-source}

`server/vueda/vdq/handlers.py:128`

## `timeout_queue_item` {#timeout_queue_item}

Mark a ``QueueItem`` as timed out and transition it to the ``timeout`` state.

### Signature {#timeout_queue_item-signature}

`timeout_queue_item(queue_item, timeout_hours)`

#### Parameters {#timeout_queue_item-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="timeout_queue_item-param-queue_item">queue_item</span> |  | yes |  |  |
| <span id="timeout_queue_item-param-timeout_hours">timeout_hours</span> |  | yes |  |  |

### Source {#timeout_queue_item-source}

`server/vueda/vdq/handlers.py:352`

## `twilio_status_callback_url` {#twilio_status_callback_url}

Return ``base_url`` with the queue item's primary key added as the ``queue_item`` query parameter.

### Signature {#twilio_status_callback_url-signature}

`twilio_status_callback_url(base_url, queue_item)`

#### Parameters {#twilio_status_callback_url-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="twilio_status_callback_url-param-base_url">base_url</span> |  | yes |  |  |
| <span id="twilio_status_callback_url-param-queue_item">queue_item</span> |  | yes |  |  |

#### Returns {#twilio_status_callback_url-returns}

`str`

### Source {#twilio_status_callback_url-source}

`server/vueda/vdq/handlers.py:344`

## `validate_email_role` {#validate_email_role}

Raise ``ValueError`` if ``role`` has no email address.

### Signature {#validate_email_role-signature}

`validate_email_role(role)`

#### Parameters {#validate_email_role-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="validate_email_role-param-role">role</span> |  | yes |  |  |

### Source {#validate_email_role-source}

`server/vueda/vdq/handlers.py:71`

## `validate_sms_role` {#validate_sms_role}

Raise ``ValueError`` if ``role`` has no cell phone number.

### Signature {#validate_sms_role-signature}

`validate_sms_role(role)`

#### Parameters {#validate_sms_role-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="validate_sms_role-param-role">role</span> |  | yes |  |  |

### Source {#validate_sms_role-source}

`server/vueda/vdq/handlers.py:76`

## Source

`server/vueda/vdq/handlers.py`
