Event Grid Webhooks¶
This recipe demonstrates how to set up an Azure Event Grid subscription for Azure Communication Services (ACS) and handle events using a Python web framework like Flask or FastAPI.
This recipe walks these steps in order:
flowchart TD
START["Event Grid Webhooks"]
N1["Prerequisites"]
N2["1. Set Up Event Grid Subscription"]
N3["2. Flask Webhook Endpoint"]
N4["3. Validate CloudEvents"]
N5["4. Handle Common ACS Events"]
START --> N1
N1 --> N2
N2 --> N3
N3 --> N4
N4 --> N5 Prerequisites¶
- ACS Resource.
- Event Grid Subscription.
- Python Web Server (e.g., Flask, FastAPI).
1. Set Up Event Grid Subscription¶
Use the Azure Portal or CLI to create an Event Grid subscription for your ACS resource.
# Create an Event Grid subscription for ACS
az eventgrid event-subscription create \
--name "acs-sms-subscription" \
--source-resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Communication/CommunicationServices/<acs-resource-name>" \
--endpoint "https://<your-webhook-endpoint>/api/webhooks" \
--endpoint-type webhook \
--included-event-types "Microsoft.Communication.SMSReceived" "Microsoft.Communication.SMSDeliveryReportReceived"
| Command | Purpose |
|---|---|
az eventgrid event-subscription create | Creates an Event Grid subscription that forwards ACS events to an endpoint. |
--name "acs-sms-subscription" | Names the event subscription. |
--source-resource-id "/subscriptions/.../CommunicationServices/<acs-resource-name>" | Sets the ACS resource as the event source (full ARM resource ID). |
--endpoint "https://<your-webhook-endpoint>/api/webhooks" | Sets the webhook URL that receives events. |
--endpoint-type webhook | Declares the endpoint as an HTTP webhook. |
--included-event-types "Microsoft.Communication.SMSReceived" "..." | Filters delivery to the listed ACS SMS event types. |
2. Flask Webhook Endpoint¶
Implement an endpoint to receive and process events. You must handle the SubscriptionValidationEvent to successfully register the webhook.
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route("/api/webhooks", methods=["POST"])
def handle_event():
# Parse events from the request body
events = request.json
for event in events:
# Handle subscription validation event
if event["eventType"] == "Microsoft.EventGrid.SubscriptionValidationEvent":
validation_code = event["data"]["validationCode"]
return jsonify({"validationResponse": validation_code}), 200
# Handle SMS received event
elif event["eventType"] == "Microsoft.Communication.SMSReceived":
sender = event["data"]["from"]
message = event["data"]["message"]
print(f"Received SMS from {sender}: {message}")
# Handle Email delivered event
elif event["eventType"] == "Microsoft.Communication.EmailDeliveryReportReceived":
message_id = event["data"]["messageId"]
status = event["data"]["status"]
print(f"Email delivery status for {message_id}: {status}")
return "OK", 200
if __name__ == "__main__":
app.run(port=5000)
3. Validate CloudEvents¶
For improved interoperability, use the azure-eventgrid library to validate and parse CloudEvents.
from azure.eventgrid import EventGridConsumerClient
# Assuming the incoming request is in CloudEvent format
def process_cloud_event(raw_event):
consumer = EventGridConsumerClient()
event = consumer.deserialize(raw_event)
print(f"Processing event of type: {event.event_type}")
4. Handle Common ACS Events¶
ACS provides several event types you can subscribe to:
| Event Type | Description |
|---|---|
Microsoft.Communication.SMSReceived | Triggered when a message is received at a phone number. |
Microsoft.Communication.SMSDeliveryReportReceived | Triggered when a delivery report is received for an outbound SMS. |
Microsoft.Communication.EmailDeliveryReportReceived | Triggered when a delivery report is received for an email. |
Microsoft.Communication.ChatMessageReceived | Triggered when a new message is sent to a chat thread. |