Skip to content

Commit b2ce1d9

Browse files
committed
Merge branch 'main' into p2p_ios_demo
2 parents 5871486 + 03b3635 commit b2ce1d9

File tree

19 files changed

+6332
-14
lines changed

19 files changed

+6332
-14
lines changed

CHANGELOG.md

+10-7
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12-
- Added new processors `ProducerProcessor` and `ConsumerProcessor`. The producer
13-
processor processes frames from the pipeline and decides whether the consumers
14-
should consume it or not. If so, the same frame that is received by the
15-
producer is sent to the consumer. There can be multiple consumers per
12+
- Added new processors `ProducerProcessor` and `ConsumerProcessor`. The
13+
producer processor processes frames from the pipeline and decides whether the
14+
consumers should consume it or not. If so, the same frame that is received by
15+
the producer is sent to the consumer. There can be multiple consumers per
1616
producer. These processors can be useful to push frames from one part of a
1717
pipeline to a different one (e.g. when using `ParallelPipeline`).
1818

1919
- Improvements for the `SmallWebRTCTransport`:
2020
- Wait until the pipeline is ready before triggering the `connected` event.
2121
- Queue messages if the data channel is not ready.
22-
- Update the aiortc dependency to fix an issue where the 'video/rtx' MIME type
23-
was incorrectly handled as a codec retransmission.
22+
- Update the aiortc dependency to fix an issue where the 'video/rtx' MIME
23+
type was incorrectly handled as a codec retransmission.
2424
- Avoid initial video delays.
2525

2626
### Fixed
2727

28+
- Fixed an issue in the Azure TTS services where the language was being set
29+
incorrectly.
30+
2831
- Fixed `SmallWebRTCTransport` to support dynamic values for
29-
`TransportParams.audio_out_10ms_chunks`. Previously, it only worked with 20ms
32+
`TransportParams.audio_out_10ms_chunks`. Previously, it only worked with 20ms
3033
chunks.
3134

3235
- Fixed an issue where `LLMAssistantContextAggregator` would prevent a
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# Handling PSTN/SIP Dial-in on Pipecat Cloud
2+
3+
This repository contains two server implementations for handling
4+
the pinless dial-in workflow in Pipecat Cloud. This is the companion to the
5+
Pipecat Cloud [pstn_sip starter image](https://github.com/daily-co/pipecat-cloud-images/tree/main/pipecat-starters/pstn_sip).
6+
In addition you can use `/api/dial` to trigger dial-out, and
7+
eventually, call-transfers.
8+
9+
1. [FastAPI Server](fastapi-webhook-server/README.md) -
10+
A FastAPI implementation that handles PSTN (Public Switched Telephone
11+
Network) and SIP (Session Initiation Protocol) calls using the Daily API.
12+
13+
2. [Next.js Serverless](nextjs-webhook-server/README.md) -
14+
A Next.js API implementation designed for deployment on Vercel's
15+
serverless platform.
16+
17+
Both implementations provide:
18+
19+
- HMAC signature validation for pinless webhook
20+
- Structured logging
21+
- Support for dial-in and dial-out settings
22+
- Voicemail detection and call transfer functionality (coming soon)
23+
- Test request handling
24+
25+
## Choosing an Implementation
26+
27+
- Use the **FastAPI Server** if you:
28+
29+
- Need a standalone server
30+
- Prefer Python and FastAPI
31+
- Want to deploy to traditional hosting platforms
32+
33+
- Use the **Next.js Serverless** implementation if you:
34+
- Want serverless deployment
35+
- Prefer JavaScript/TypeScript
36+
- Already use Next.js and Vercel for other projects
37+
- Need quick scaling and zero maintenance
38+
39+
## Prerequisites
40+
41+
### Environment Variables
42+
43+
Both implementations require similar environment variables:
44+
45+
- `PIPECAT_CLOUD_API_KEY`: Pipecat Cloud API Key, begins with pk\_\*
46+
- `AGENT_NAME`: Your Daily agent name
47+
- `PINLESS_HMAC_SECRET`: Your HMAC secret for request verification
48+
- `LOG_LEVEL`: (Optional) Logging level (defaults to 'info')
49+
50+
See the individual README files in each implementation directory for
51+
specific setup instructions.
52+
53+
### Phone number setup
54+
55+
You can buy a phone number through the Pipecat Cloud Dashboard:
56+
57+
1. Go to `Settings` > `Telephony`
58+
2. Follow the UI to purchase a phone number
59+
3. Configure the webhook URL to receive incoming calls (e.g. `https://my-webhook-url.com/api/dial`)
60+
61+
Or purchase the number using Daily's
62+
[PhoneNumbers API](https://docs.daily.co/reference/rest-api/phone-numbers).
63+
64+
```bash
65+
curl --request POST \
66+
--url https://api.daily.co/v1/domain-dialin-config \
67+
--header 'Authorization: Bearer $TOKEN' \
68+
--header 'Content-Type: application/json' \
69+
--data-raw '{
70+
"type": "pinless_dialin",
71+
"name_prefix": "Customer1",
72+
"phone_number": "+1PURCHASED_NUM",
73+
"room_creation_api": "https://example.com/api/dial",
74+
"hold_music_url": "https://example.com/static/ringtone.mp3",
75+
"timeout_config": {
76+
"message": "No agent is available right now"
77+
}
78+
}'
79+
```
80+
81+
The API will return a static SIP URI (`sip_uri`) that can be called
82+
from other SIP services.
83+
84+
### `room_creation_api`
85+
86+
To make and receive calls currently you have to host a server that
87+
handles incoming calls. In the coming weeks, incoming calls will be
88+
directly handled within Daily and we will expose an endpoint similar
89+
to `{service}/start` that will manage this for you.
90+
91+
In the meantime, the server described below serves as the webhook
92+
handler for the `room_creation_api`. Configure your pinless phone
93+
number or SIP interconnect to the `ngrok` tunnel or
94+
the actual server URL, append `/api/dial` to the webhook URL.
95+
96+
## Example curl commands
97+
98+
Note: Replace `http://localhost:3000` with your actual server URL and
99+
phone numbers with valid values for your use case.
100+
101+
### Dialin Request
102+
103+
The server will receive a request when a call is received from Daily.
104+
105+
### Dialout Request
106+
107+
Dial a number, will use any purchased number
108+
109+
```bash
110+
curl -X POST http://localhost:3000/api/dial \
111+
-H "Content-Type: application/json" \
112+
-d '{
113+
"dialout_settings": [
114+
{
115+
"phoneNumber": "+1234567890",
116+
}
117+
]
118+
}'
119+
```
120+
121+
Dial a number with callerId, which is the UUID of a purchased number.
122+
123+
```bash
124+
curl -X POST http://localhost:3000/api/dial \
125+
-H "Content-Type: application/json" \
126+
-d '{
127+
"dialout_settings": [
128+
{
129+
"phoneNumber": "+1234567890",
130+
"callerId": "purchased_phone_uuid"
131+
}
132+
]
133+
}'
134+
```
135+
136+
Dial a number
137+
138+
```bash
139+
curl -X POST http://localhost:3000/api/dial \
140+
-H "Content-Type: application/json" \
141+
-d '{
142+
"dialout_settings": [
143+
{
144+
"phoneNumber": "+1234567890",
145+
"callerId": "purchased_phone_uuid"
146+
}
147+
]
148+
}'
149+
```
150+
151+
### Advanced Request with Voicemail Detection
152+
153+
```bash
154+
curl -X POST http://localhost:3000/api/dial \
155+
-H "Content-Type: application/json" \
156+
-d '{
157+
"To": "+1234567890",
158+
"From": "+1987654321",
159+
"callId": "call-uuid-123",
160+
"callDomain": "domain-uuid-456",
161+
"dialout_settings": [
162+
{
163+
"phoneNumber": "+1234567890",
164+
"callerId": "purchased_phone_uuid"
165+
}
166+
],
167+
"voicemail_detection": {
168+
"testInPrebuilt": true
169+
},
170+
"call_transfer": {
171+
"mode": "dialout",
172+
"speakSummary": true,
173+
"storeSummary": true,
174+
"operatorNumber": "+1234567890",
175+
"testInPrebuilt": true
176+
}
177+
}'
178+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# FastAPI server for handling Daily PSTN/SIP Webhook
2+
3+
A FastAPI server that handles PSTN (Public Switched Telephone Network) and SIP (Session Initiation Protocol) calls using the Daily API.
4+
5+
## Setup
6+
7+
1. Clone the repository
8+
9+
2. Navigate to the `fastapi-webhook-server` directory:
10+
11+
```bash
12+
cd fastapi-webhook-server
13+
```
14+
15+
3. Install dependencies:
16+
17+
```bash
18+
pip install -r requirements.txt
19+
```
20+
21+
4. Copy `env.example` to `.env`:
22+
23+
```bash
24+
cp env.example .env
25+
```
26+
27+
5. Update `.env` with your credentials:
28+
29+
- `AGENT_NAME`: Your Daily agent name
30+
- `PIPECAT_CLOUD_API_KEY`: Your Daily API key
31+
- `PINLESS_HMAC_SECRET`: Your HMAC secret for request verification
32+
33+
## Running the Server
34+
35+
Start the server:
36+
37+
```bash
38+
python server.py
39+
```
40+
41+
The server will run on `http://localhost:7860` and you can expose it via ngrok for testing:
42+
43+
```bash
44+
`ngrok http 7860`
45+
```
46+
47+
> Tip: Use a subdomain for a consistent URL (e.g. `ngrok http -subdomain=mydomain http://localhost:7860`)
48+
49+
## API Endpoints
50+
51+
### GET /
52+
53+
Health check endpoint that returns a "Hello, World!" message.
54+
55+
### POST /api/dial
56+
57+
Initiates a PSTN/SIP call with the following request body format:
58+
59+
```json
60+
{
61+
"To": "+14152251493",
62+
"From": "+14158483432",
63+
"callId": "string-contains-uuid",
64+
"callDomain": "string-contains-uuid",
65+
"dialout_settings": [
66+
{
67+
"phoneNumber": "+14158483432",
68+
"callerId": "+14152251493"
69+
}
70+
],
71+
"voicemail_detection": {
72+
"testInPrebuilt": true
73+
},
74+
"call_transfer": {
75+
"mode": "dialout",
76+
"speakSummary": true,
77+
"storeSummary": true,
78+
"operatorNumber": "+14152250006",
79+
"testInPrebuilt": true
80+
}
81+
}
82+
```
83+
84+
#### Response
85+
86+
Returns a JSON object containing:
87+
88+
- `status`: Success/failure status
89+
- `data`: Response from Daily API
90+
- `room_properties`: Properties of the created Daily room
91+
92+
## Error Handling
93+
94+
- 401: Invalid signature
95+
- 400: Invalid authorization header (e.g. missing Daily API key in bot.py)
96+
- 405: Method not allowed (e.g. incorrect route on the webhook URL)
97+
- 500: Server errors (missing API key, network issues)
98+
- Other status codes are passed through from the Daily API
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
AGENT_NAME="your-agent-name"
2+
PIPECAT_CLOUD_API_KEY="your-daily-api-key"
3+
PINLESS_HMAC_SECRET="hmac-secret-pinless-dialin"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fastapi
2+
uvicorn
3+
python-dotenv
4+
requests
5+
pydantic
6+
loguru

0 commit comments

Comments
 (0)