
Perpustakaan Twilio Helper untuk ASP.NET (Twilio.aspnet), membantu Anda mengintegrasikan Twilio SDK resmi untuk C# dan .net ke dalam aplikasi ASP.NET Anda. Perpustakaan mendukung ASP.NET MVC di .NET Framework dan ASP.NET Core.
Perpustakaan ini membantu Anda menanggapi webhooks, menambahkan klien Twilio ke wadah injeksi ketergantungan, dan memvalidasi permintaan HTTP yang berasal dari Twilio.
Membutuhkan .NET 6.0 atau lebih baru.
Jalankan perintah berikut untuk menginstal paket menggunakan .net CLI:
dotnet add package Twilio.AspNet.CoreAtau, dari konsol manajer paket atau pengembang PowerShell, jalankan perintah berikut untuk menginstal versi terbaru:
Install-Package Twilio.AspNet.CoreAtau, gunakan Nuget Package Manager untuk Visual Studio atau Window Nuget untuk JetBrains Rider, lalu cari twilio.aspnet.core dan instal paket.
Membutuhkan .NET 4.6.2 atau lebih baru.
Dari Paket Manajer Konsol atau Pengembang PowerShell, jalankan perintah berikut untuk menginstal versi terbaru:
Install-Package Twilio.AspNet.MvcAtau, gunakan Nuget Package Manager untuk Visual Studio atau Window Nuget untuk JetBrains Rider, lalu cari twilio.aspnet.mvc dan instal paket.
using Twilio . AspNet . Common ;
using Twilio . AspNet . Core ; // or .Mvc for .NET Framework
using Twilio . TwiML ;
public class SmsController : TwilioController
{
// GET: Sms
public TwiMLResult Index ( SmsRequest request )
{
var response = new MessagingResponse ( ) ;
response . Message ( $ "Ahoy { request . From } !" ) ;
return TwiML ( response ) ;
}
} Pengontrol ini akan menangani webhook SMS. Rincian SMS yang masuk akan terikat pada parameter SmsRequest request . Dengan mewarisi dari TwilioController , Anda mendapatkan akses ke metode TwiML yang dapat Anda gunakan untuk merespons dengan TWIML.
using Twilio . AspNet . Common ;
using Twilio . AspNet . Core ; // or .Mvc for .NET Framework
using Twilio . TwiML ;
public class VoiceController : TwilioController
{
// GET: Voice
public TwiMLResult Index ( VoiceRequest request )
{
var response = new VoiceResponse ( ) ;
response . Say ( $ "Ahoy! Are you from { request . FromCity } ?" ) ;
return TwiML ( response ) ;
}
} Pengontrol ini akan menangani webhook suara. Rincian panggilan suara yang masuk akan terikat pada parameter VoiceRequest request . Dengan mewarisi dari TwilioController , Anda mendapatkan akses ke metode TwiML yang dapat Anda gunakan untuk merespons dengan TWIML.
TwiML alih -alih mewarisi dari TwilioController Jika Anda tidak dapat mewarisi dari kelas TwilioController , Anda dapat menggunakan metode ekstensi TwiML .
using Microsoft . AspNetCore . Mvc ; // or System.Web.Mvc for .NET Framework
using Twilio . AspNet . Common ;
using Twilio . AspNet . Core ; // or .Mvc for .NET Framework
using Twilio . TwiML ;
public class SmsController : Controller
{
// GET: Sms
public TwiMLResult Index ( SmsRequest request )
{
var response = new MessagingResponse ( ) ;
response . Message ( $ "Ahoy { request . From } !" ) ;
return this . TwiML ( response ) ;
}
} Sampel ini sama dengan sampel Webhook SMS sebelumnya, tetapi alih -alih mewarisi dari TwilioController , SmsController mewarisi dari asp.net MVC memberikan Controller , dan menggunakan this.TwiML untuk menggunakan metode ekstensi TwiML .
Twilio.aspnet.core juga memiliki dukungan untuk API minimal.
Sampel ini menunjukkan kepada Anda bagaimana Anda dapat memberikan webhook SMS menggunakan HTTP GET dan POST.
using Microsoft . AspNetCore . Mvc ;
using Twilio . AspNet . Core . MinimalApi ;
using Twilio . TwiML ;
var builder = WebApplication . CreateBuilder ( args ) ;
var app = builder . Build ( ) ;
app . MapGet ( "/sms" , ( [ FromQuery ] string from ) =>
{
var response = new MessagingResponse ( ) ;
response . Message ( $ "Ahoy { from } !" ) ;
return Results . Extensions . TwiML ( response ) ;
} ) ;
app . MapPost ( "/sms" , async ( HttpRequest request ) =>
{
var form = await request . ReadFormAsync ( ) ;
var from = form [ "from" ] ;
response . Message ( $ "Ahoy { from } !" ) ;
return Results . Extensions . TwiML ( response ) ;
} ) ;
app . Run ( ) ; Dalam pengontrol MVC tradisional, SmsRequest , VoiceRequest , dan objek permintaan yang diketik lainnya akan terikat, tetapi API minimal tidak mendukung ikatan model yang sama.
Sebagai gantinya, Anda dapat mengikat parameter individual untuk permintaan HTTP Get menggunakan atribut FromQuery . Ketika Anda tidak menentukan atribut FromQuery, banyak sumber akan dipertimbangkan untuk mengikat dari selain parameter string kueri. Untuk permintaan HTTP POST Anda dapat mengambil formulir dan kemudian mengambil parameter individual dengan indeks string.
Untuk merespons dengan TWIML, gunakan metode Results.Extensions.TwiML .
Twilio.aspnet dilengkapi dengan beberapa kelas untuk membantu Anda mengikat data dari webhook ke objek .net yang diketik. Inilah daftar kelas:
SmsRequest : Memegang data untuk permintaan Webhook SMS yang masukSmsStatusCallbackRequest : Menahan data untuk melacak status pengiriman SMS Twilio atau MMS keluarStatusCallbackRequest : Menahan data untuk melacak status panggilan suara Twilio keluarVoiceRequest : menyimpan data untuk panggilan suara yang masukPerhatikan hanya pengontrol MVC dan halaman pisau cukur yang mengikat model. NET objek yang diketik. Dalam API minimal dan skenario lainnya, Anda harus menulis kode untuk mengekstrak parameter sendiri.
Sampel berikut menunjukkan cara menerima SMS masuk, merespons, dan melacak status respons SMS.
using Twilio . AspNet . Common ;
using Twilio . AspNet . Core ; // or .Mvc for .NET Framework
using Twilio . TwiML ;
public class SmsController : TwilioController
{
private readonly ILogger < SmsController > logger ;
public SmsController ( ILogger < SmsController > logger )
{
this . logger = logger ;
}
public TwiMLResult Index ( SmsRequest request )
{
var messagingResponse = new MessagingResponse ( ) ;
messagingResponse . Message (
body : $ "Ahoy { request . From } !" ,
action : new Uri ( "/Sms/StatusCallback" ) ,
method : Twilio . Http . HttpMethod . Post
) ;
return TwiML ( messagingResponse ) ;
}
public void StatusCallback ( SmsStatusCallbackRequest request )
{
logger . LogInformation ( "SMS Status: {Status}" , request . MessageStatus ) ;
}
} Seperti yang ditunjukkan pada sampel di atas, Anda dapat menambahkan SmsRequest sebagai parameter, dan MVC akan mengikat objek untuk Anda. Kode kemudian merespons dengan SMS dengan parameter status dan method . Ketika status SMS berubah, Twilio akan mengirim permintaan HTTP POST ke StatusCallback Action. Anda dapat menambahkan SmsStatusCallbackRequest sebagai parameter, dan MVC akan mengikat objek untuk Anda.
Di ASP.NET Core, Anda dapat menambahkan klien Twilio Rest API ke layanan ASP.NET Core menggunakan metode .AddTwilioClient , seperti ini:
using Twilio . AspNet . Core ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services . AddTwilioClient ( ) Sekarang Anda dapat meminta ITwilioRestClient dan TwilioRestClient melalui injeksi ketergantungan.
Anda dapat mengonfigurasi klien Twilio menggunakan konfigurasi berikut:
{
"Twilio" : {
"AuthToken" : " [YOUR_AUTH_TOKEN] " ,
"Client" : {
"AccountSid" : " [YOUR_ACCOUNT_SID] " ,
"AuthToken" : " [YOUR_AUTH_TOKEN] " ,
"ApiKeySid" : " [YOUR_API_KEY_SID] " ,
"ApiKeySecret" : " [YOUR_API_KEY_SECRET] " ,
"CredentialType" : " [Unspecified|AuthToken|ApiKey] " ,
"Region" : null ,
"Edge" : null ,
"LogLevel" : null
}
}
}Beberapa catatan:
Twilio:Client:AuthToken jatuh pada Twilio:AuthToken . Anda hanya perlu mengkonfigurasi salah satunya.Twilio:Client:CredentialType memiliki nilai -nilai yang valid berikut: Unspecified , AuthToken , atau ApiKey .Twilio:Client:CredentialType adalah opsional dan default untuk Unspecified . Jika Unspecified , apakah Anda mengonfigurasi kunci API atau token auth akan terdeteksi.Jika Anda tidak ingin mengonfigurasi klien Twilio menggunakan konfigurasi .net, Anda dapat melakukannya secara manual:
using Twilio . AspNet . Core ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services
. AddTwilioClient ( ( serviceProvider , options ) =>
{
options . AccountSid = "[YOUR_ACCOUNT_SID]" ;
options . AuthToken = "[YOUR_AUTH_TOKEN]" ;
options . ApiKeySid = "[YOUR_API_KEY_SID]" ;
options . ApiKeySecret = "[YOUR_API_KEY_SECRET]" ;
options . Edge = null ;
options . Region = null ;
options . LogLevel = null ;
options . CredentialType = CredentialType . Unspecified ;
} ) ;PERINGATAN Jangan kode keras Token auth Anda atau rahasia kunci API ke dalam kode dan jangan memeriksanya ke kontrol sumber. Kami merekomendasikan menggunakan Secrets Manager untuk pengembangan lokal. Atau, Anda dapat menggunakan variabel lingkungan, layanan lemari besi, atau teknik lain yang lebih aman.
Secara default saat Anda menelepon .AddTwilioClient , pabrik klien HTTP dikonfigurasi yang digunakan untuk memberikan HttpClient ke klien Twilio REST. Jika Anda ingin menyesuaikan klien http ini, Anda dapat melakukannya dengan mengesampingkan pabrik klien http "twilio", setelah memohon .AddTwilioClient :
builder . Services . AddTwilioClient ( ) ;
builder . Services . AddHttpClient ( "Twilio" )
. ConfigureHttpClient ( client =>
{
client . BaseAddress = new Uri ( "YOUR_PROXY_ADDRESS" ) ;
} )
. ConfigurePrimaryHttpMessageHandler ( ( ) => new HttpClientHandler
{
// same options as the Twilio C# SDK
AllowAutoRedirect = false
} ) ;Webhooks mengharuskan titik akhir Anda tersedia untuk umum, tetapi ini juga memperkenalkan risiko bahwa aktor buruk dapat menemukan URL webhook Anda dan mencoba menyalahgunakannya.
Untungnya, Anda dapat memverifikasi bahwa permintaan HTTP berasal dari Twilio. Perpustakaan Twilio.AspNet menyediakan atribut yang akan memvalidasi permintaan untuk Anda di MVC. Implementasi berbeda antara perpustakaan Twilio.AspNet.Core dan Twilio.AspNet.Mvc .
Tambahkan metode .AddTwilioRequestValidation saat startup:
using Twilio . AspNet . Core ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services . AddTwilioRequestValidation ( ) ;Kemudian konfigurasikan validasi permintaan:
{
"Twilio" : {
"AuthToken" : " [YOUR_AUTH_TOKEN] " ,
"RequestValidation" : {
"AuthToken" : " [YOUR_AUTH_TOKEN] " ,
"AllowLocal" : false ,
"BaseUrlOverride" : " https://??????.ngrok.io "
}
}
}Beberapa catatan tentang konfigurasi:
Twilio:RequestValidation:AuthToken jatuh pada Twilio:AuthToken . Anda hanya perlu mengkonfigurasi salah satunya.AllowLocal akan melewatkan validasi ketika permintaan HTTP berasal dari LocalHost.BaseUrlOverride jika aplikasi Anda berada di belakang proxy terbalik atau terowongan seperti Ngrok. Jalur permintaan saat ini akan ditambahkan ke BaseUrlOverride untuk validasi permintaan.Info alih -alih mengkonfigurasi
BaseUrlOverride, Anda dapat menggunakan middleware header yang diteruskan untuk mengatur skema, port, host, dll yang benar pada permintaan HTTP saat ini.
using Microsoft . AspNetCore . HttpOverrides ;
using Twilio . AspNet . Core ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services . AddTwilioRequestValidation ( ) ;
builder . Services . Configure < ForwardedHeadersOptions > ( options => options . ForwardedHeaders = ForwardedHeaders . All ) ;
// more service configuration
var app = builder . Build ( ) ;
app . UseForwardedHeaders ( ) ;
// more request pipeline configuration
app . Run ( ) ; Akibatnya, Anda tidak perlu mengkonfigurasi BaseUrlOverride setiap kali Anda memulai kembali Ngrok, atau mengubah URL proxy terbalik. Ikuti panduan Microsoft untuk mengonfigurasi middleware header yang diteruskan dengan aman.
Anda juga dapat mengonfigurasi validasi permintaan secara manual:
using Twilio . AspNet . Core ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services
. AddTwilioRequestValidation ( ( serviceProvider , options ) =>
{
options . AuthToken = "[YOUR_AUTH_TOKEN]" ;
options . AllowLocal = false ;
options . BaseUrlOverride = "https://??????.ngrok.io" ;
} ) ;PERINGATAN JANGAN Kode Token Auth Anda ke dalam kode dan jangan memeriksanya ke kontrol sumber. Kami merekomendasikan menggunakan Secrets Manager untuk pengembangan lokal. Atau, Anda dapat menggunakan variabel lingkungan, layanan lemari besi, atau teknik lain yang lebih aman.
Setelah validasi permintaan telah dikonfigurasi, Anda dapat menggunakan atribut [ValidateRequest] di MVC. Anda dapat menerapkan atribut secara global, ke area, pengontrol, dan tindakan MVC. Berikut adalah contoh di mana atribut diterapkan pada tindakan Index :
using Twilio . AspNet . Common ;
using Twilio . AspNet . Core ;
using Twilio . TwiML ;
public class SmsController : TwilioController
{
[ ValidateRequest ]
public TwiMLResult Index ( SmsRequest request )
{
var response = new MessagingResponse ( ) ;
response . Message ( "Ahoy!" ) ;
return TwiML ( response ) ;
}
} .NET 7 memperkenalkan konsep filter titik akhir yang dapat Anda terapkan pada titik akhir inti ASP.NET. Perpustakaan helper untuk ASP.NET Core menambahkan filter titik akhir untuk memvalidasi permintaan twilio yang disebut ValidateTwilioRequestFilter .
Anda dapat menambahkan filter ini ke grup titik akhir atau titik akhir menggunakan metode ValidateTwilioRequest :
// add filter to endpoint
app . MapPost ( "/sms" , ( ) => .. . )
. ValidateTwilioRequest ( ) ;
// add filter to endpoint group
var twilioGroup = app . MapGroup ( "/twilio" ) ;
twilioGroup . ValidateTwilioRequest ( ) ;
twilioGroup . MapPost ( "/sms" , ( ) => .. . ) ;
twilioGroup . MapPost ( "/voice" , ( ) => .. . ) ;Atau, Anda dapat menambahkan filter titik akhir sendiri:
app . MapPost ( "/sms" , ( ) => .. . )
. AddEndpointFilter < ValidateTwilioRequestFilter > ( ) ; Ketika Anda tidak dapat menggunakan filter [ValidateRequest] atau ValidateTwilioRequestFilter , Anda dapat menggunakan ValidateTwilioRequestMiddleware sebagai gantinya. Anda dapat menambahkan menambahkan ValidateTwilioRequestFilter seperti ini:
app . UseTwilioRequestValidation ( ) ;
// or the equivalent: app.UseMiddleware<ValidateTwilioRequestMiddleware>(); Middleware ini akan melakukan validasi untuk semua permintaan. Jika Anda tidak ingin menerapkan validasi ke semua permintaan, Anda dapat menggunakan app.UseWhen() untuk menjalankan middleware secara kondisional.
Berikut adalah contoh cara memvalidasi permintaan yang dimulai dengan Path /Twilio-media , untuk melindungi file media yang hanya dapat diakses oleh Proxy Twilio:
using System . Net ;
using Microsoft . Extensions . FileProviders ;
using Microsoft . Extensions . Options ;
using Twilio . AspNet . Core ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services . AddTwilioRequestValidation ( ) ;
var app = builder . Build ( ) ;
app . UseWhen (
context => context . Request . Path . StartsWithSegments ( "/twilio-media" , StringComparison . OrdinalIgnoreCase ) ,
app => app . UseTwilioRequestValidation ( )
) ;
app . UseStaticFiles ( new StaticFileOptions
{
FileProvider = new PhysicalFileProvider ( Path . Combine ( builder . Environment . ContentRootPath , "TwilioMedia" ) ) ,
RequestPath = "/twilio-media"
} ) ;
app . Run ( ) ; Di web Anda.config Anda dapat mengonfigurasi validasi permintaan seperti yang ditunjukkan di bawah ini:
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< configuration >
< configSections >
< sectionGroup name = " twilio " type = " Twilio.AspNet.Mvc.TwilioSectionGroup,Twilio.AspNet.Mvc " >
< section name = " requestValidation " type = " Twilio.AspNet.Mvc.RequestValidationConfigurationSection,Twilio.AspNet.Mvc " />
</ sectionGroup >
</ configSections >
< twilio >
< requestValidation
authToken = " [YOUR_AUTH_TOKEN] "
baseUrlOverride = " https://??????.ngrok.io "
allowLocal = " false "
/>
</ twilio >
</ configuration >Anda juga dapat mengonfigurasi validasi permintaan menggunakan pengaturan aplikasi:
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< configuration >
< appSettings >
< add key = " twilio:requestValidation:authToken " value = " [YOUR_AUTH_TOKEN] " />
< add key = " twilio:requestValidation:baseUrlOverride " value = " https://??????.ngrok.io " />
< add key = " twilio:requestValidation:allowLocal " value = " false " />
</ appSettings >
</ configuration > Jika Anda mengonfigurasi validasi permintaan menggunakan kedua cara, pengaturan aplikasi akan menimpa elemen konfigurasi twilio/requestValidation .
Beberapa catatan tentang konfigurasi:
allowLocal akan melewatkan validasi ketika permintaan HTTP berasal dari LocalHost.baseUrlOverride jika Anda berada di depan proxy terbalik atau terowongan seperti Ngrok. Jalur permintaan saat ini akan ditambahkan ke baseUrlOverride untuk validasi permintaan.PERINGATAN JANGAN Kode Token Auth Anda ke dalam kode dan jangan memeriksanya ke kontrol sumber. Gunakan
UserSecretsConfigBuilderuntuk pengembangan lokal atau salah satu pembangun konfigurasi lainnya. Atau, Anda harus mengenkripsi bagian konfigurasi yang berisi rahasia seperti token auth.
Sekarang bahwa validasi permintaan telah dikonfigurasi, gunakan atribut [ValidateRequest] . Anda dapat menerapkan atribut secara global, ke area, pengontrol, dan tindakan MVC. Berikut adalah contoh di mana atribut diterapkan pada tindakan Index :
using Twilio . AspNet . Common ;
using Twilio . AspNet . Mvc ;
using Twilio . TwiML ;
public class SmsController : TwilioController
{
[ ValidateRequest ]
public TwiMLResult Index ( SmsRequest request )
{
var response = new MessagingResponse ( ) ;
response . Message ( "Ahoy!" ) ;
return TwiML ( response ) ;
}
} Atribut [ValidateRequest] hanya berfungsi untuk MVC. Jika Anda perlu memvalidasi permintaan di luar MVC, Anda dapat menggunakan kelas RequestValidationHelper yang disediakan oleh Twilio.AspNet . Atau, kelas RequestValidator dari Twilio SDK juga dapat membantu Anda dengan ini.
Berikut contoh API minimal yang memvalidasi permintaan yang masuk berasal dari Twilio:
using System . Net ;
using Microsoft . Extensions . Options ;
using Twilio . AspNet . Core ;
using Twilio . AspNet . Core . MinimalApi ;
using Twilio . TwiML ;
var builder = WebApplication . CreateBuilder ( args ) ;
// adds TwilioRequestValidationOptions
builder . Services . AddTwilioRequestValidation ( ) ;
var app = builder . Build ( ) ;
app . MapPost ( "/sms" , ( HttpContext httpContext ) =>
{
if ( IsValidTwilioRequest ( httpContext ) == false )
return Results . StatusCode ( ( int ) HttpStatusCode . Forbidden ) ;
var messagingResponse = new MessagingResponse ( ) ;
messagingResponse . Message ( "Ahoy!" ) ;
return Results . Extensions . TwiML ( messagingResponse ) ;
} ) ;
app . Run ( ) ;
bool IsValidTwilioRequest ( HttpContext httpContext )
{
var options = httpContext . RequestServices
. GetService < IOptions < TwilioRequestValidationOptions > > ( )
? . Value ?? throw new Exception ( "TwilioRequestValidationOptions missing." ) ;
string ? urlOverride = null ;
if ( options . BaseUrlOverride is not null )
{
var request = httpContext . Request ;
urlOverride = $ " { options . BaseUrlOverride . TrimEnd ( '/' ) } { request . Path } { request . QueryString } " ;
}
return RequestValidationHelper . IsValidRequest ( httpContext , options . AuthToken , urlOverride , options . AllowLocal ) ;
} AddTwilioRequestValidation menambahkan TwilioRequestValidationOptions , yang biasanya digunakan untuk atribut [ValidateRequest] , tetapi dalam sampel ini digunakan untuk mengambil sendiri konfigurasi validasi permintaan sendiri. Kemudian di dalam titik akhir /SMS , metode IsValidTwilioRequest digunakan untuk memvalidasi permintaan. IsValidTwilioRequest mengambil opsi validasi permintaan dari DI dan melakukan logika yang sama seperti yang akan dilakukan [ValidateRequest] untuk permintaan MVC. Jika permintaan tidak valid, kode status HTTP 403 dikembalikan, jika tidak, beberapa TWIML dikembalikan ke Twilio.