This guide covers deploying SignalWire AI Agents to Google Cloud Functions and Azure Functions from PHP.
SignalWire AI Agents support deployment to major cloud function platforms:
- Google Cloud Functions - Serverless compute platform on Google Cloud
- Azure Functions - Serverless compute service on Microsoft Azure
- AWS Lambda - Already supported (see existing documentation)
The agent automatically detects Google Cloud Functions environment using these variables:
FUNCTION_TARGET- The function entry pointK_SERVICE- Knative service name (Cloud Run/Functions)GOOGLE_CLOUD_PROJECT- Google Cloud project ID
- Create your agent file (
index.php):
<?php
require 'vendor/autoload.php';
use SignalWire\Agent\AgentBase;
use SignalWire\Serverless\Adapter;
// Create agent instance
$agent = new AgentBase(
name: 'my-agent',
route: '/',
);
$agent->promptAddSection('Role', 'You are a helpful assistant running in Google Cloud Functions.');
// Handle the request. Adapter::handleGcf() reads the request from the PHP
// superglobals, calls $agent->handleRequest(), and emits the response.
Adapter::handleGcf($agent);
Adapter::serve($agent)auto-detects the execution mode (gcf,azure,lambda,cgi, orserver) and dispatches to the right handler, so a single entry point can run unchanged across platforms.
- Create
composer.json:
{
"require": {
"signalwire/signalwire-agents": "*"
}
}- Deploy using gcloud:
gcloud functions deploy my-agent \
--runtime php82 \
--trigger-http \
--entry-point agent_handler \
--allow-unauthenticatedSet these environment variables for your function:
# SignalWire credentials
export SIGNALWIRE_PROJECT_ID="your-project-id"
export SIGNALWIRE_API_TOKEN="your-token"
# Agent HTTP Basic Auth
export SWML_BASIC_AUTH_USER="your-username"
export SWML_BASIC_AUTH_PASSWORD="your-password"
# Optional: Custom region/project settings
export FUNCTION_REGION="us-central1"
export GOOGLE_CLOUD_PROJECT="your-project-id"Google Cloud Functions URLs follow this pattern:
https://{region}-{project-id}.cloudfunctions.net/{function-name}
With authentication:
https://username:password@{region}-{project-id}.cloudfunctions.net/{function-name}
The agent automatically detects Azure Functions environment using these variables:
AZURE_FUNCTIONS_ENVIRONMENT- Azure Functions runtime environmentFUNCTIONS_WORKER_RUNTIME- Runtime language (custom for PHP)AzureWebJobsStorage- Azure storage connection string
- Create your function app structure:
my-agent-function/
├── agent/
│ ├── function.json
│ └── index.php
├── composer.json
└── host.json
- Create
agent/index.php:
<?php
require __DIR__ . '/../vendor/autoload.php';
use SignalWire\Agent\AgentBase;
use SignalWire\Serverless\Adapter;
$agent = new AgentBase(
name: 'my-agent',
);
// $request is the Azure Functions HTTP request array (method, url, headers, body).
// handleAzure() returns an Azure-compatible {status, headers, body} response.
return Adapter::handleAzure($agent, $request);- Create
agent/function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["get", "post"]
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}- Deploy using Azure CLI:
# Create function app
az functionapp create \
--resource-group myResourceGroup \
--consumption-plan-location westus \
--runtime custom \
--functions-version 4 \
--name my-agent-function \
--storage-account mystorageaccount
# Deploy code
func azure functionapp publish my-agent-functionSet these in your Azure Function App settings:
SIGNALWIRE_PROJECT_ID="your-project-id"
SIGNALWIRE_API_TOKEN="your-token"
SWML_BASIC_AUTH_USER="your-username"
SWML_BASIC_AUTH_PASSWORD="your-password"Azure Functions URLs follow this pattern:
https://{function-app-name}.azurewebsites.net/api/{function-name}
Both platforms support HTTP Basic Authentication:
use SignalWire\Agent\AgentBase;
$agent = new AgentBase(
name: 'my-agent',
basicAuthUser: 'your-username',
basicAuthPassword: 'your-password',
);- Client sends request with
Authorization: Basic <credentials>header - Agent validates credentials against configured username/password
- If invalid, returns 401 with
WWW-Authenticateheader - If valid, processes the request normally
# Install dependencies
composer install
# Run locally with PHP built-in server
php -S localhost:3000 index.php# Test without auth (should return 401)
curl https://your-function-url/
# Test with valid auth
curl -u username:password https://your-function-url/
# Test SWAIG function call
curl -u username:password \
-H "Content-Type: application/json" \
-d '{"call_id": "test", "argument": {"parsed": [{"param": "value"}]}}' \
https://your-function-url/your_function_name- Use connection pooling for database connections
- Implement proper caching strategies
- Minimise cold start times with smaller deployment packages
- Always use HTTPS endpoints
- Implement proper authentication
- Use environment variables for sensitive data
- Consider using cloud-native secret management
- Enable cloud platform logging
- Monitor function execution times
- Set up alerts for errors and timeouts
- Use distributed tracing for complex workflows
- Right-size memory allocation
- Implement proper timeout settings
- Use reserved capacity for predictable workloads
- Monitor and optimise function execution patterns
Environment Detection:
// Check detected mode
echo "Detected: " . getenv('K_SERVICE') . "\n";
echo "Project: " . getenv('GOOGLE_CLOUD_PROJECT') . "\n";Authentication Issues:
- Verify username/password are set correctly
- Check that the Authorization header is being sent
- Ensure credentials match exactly (case-sensitive)
Enable debug logging:
error_reporting(E_ALL);
ini_set('display_errors', '1');- Update environment variable names
- Modify request/response handling if needed
- Update deployment scripts
- Add cloud function entry point
- Configure environment variables
- Update URL generation logic
- Test authentication flow