
تساعدك مكتبة Twilio Helper لـ ASP.NET (Twilio.aspnet) ، على دمج Twilio SDK الرسمي لـ C# و .NET في تطبيقات ASP.NET الخاصة بك. تدعم المكتبة ASP.NET MVC على .NET Framework و ASP.NET CORE.
تساعدك هذه المكتبة على الاستجابة لـ Webhooks ، وتضيف عميل Twilio إلى حاوية حقن التبعية ، والتحقق من طلب HTTP نشأ من Twilio.
يتطلب .NET 6.0 أو أحدث.
قم بتشغيل الأمر التالي لتثبيت الحزمة باستخدام .NET CLI:
dotnet add package Twilio.AspNet.Coreبدلاً من ذلك ، من وحدة تحكم Package Manager أو المطور PowerShell ، قم بتشغيل الأمر التالي لتثبيت أحدث إصدار:
Install-Package Twilio.AspNet.Coreبدلاً من ذلك ، استخدم Nuget Package Manager لـ Visual Studio أو Nuget Window for JetBrains Rider ، ثم ابحث عن twilio.aspnet.core وتثبيت الحزمة.
يتطلب .NET 4.6.2 أو أحدث.
من وحدة تحكم Package Manager أو مطور PowerShell ، قم بتشغيل الأمر التالي لتثبيت أحدث إصدار:
Install-Package Twilio.AspNet.Mvcبدلاً من ذلك ، استخدم Nuget Package Manager لـ Visual Studio أو Nuget Window for JetBrains Rider ، ثم ابحث عن twilio.aspnet.mvc وتثبيت الحزمة.
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 ) ;
}
} ستعامل وحدة التحكم هذه مع SMS Webhook. سيتم ربط تفاصيل الرسائل القصيرة الواردة بمعلمة SmsRequest request . من خلال الوراثة من TwilioController ، يمكنك الوصول إلى طريقة TwiML التي يمكنك استخدامها للرد مع 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 ) ;
}
} ستعامل وحدة التحكم هذه مع Webhook الصوتي. سيتم ربط تفاصيل المكالمة الصوتية الواردة بمعلمة VoiceRequest request . من خلال الوراثة من TwilioController ، يمكنك الوصول إلى طريقة TwiML التي يمكنك استخدامها للرد مع TWIML.
TwiML بدلاً من الوراثة من TwilioController إذا لم تتمكن من الوراثة من فئة TwilioController ، فيمكنك استخدام طرق تمديد 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 ) ;
}
} هذه العينة هي نفس عينة WebHook SMS السابقة ، ولكن بدلاً من الوراثة من TwilioController ، يرث SmsController من Controller ASP.NET MVC ، ويستخدم this.TwiML . twiml لاستخدام طريقة تمديد TwiML .
Twilio.aspnet.core لديه أيضا دعم للحد من واجهات برمجة التطبيقات.
يوضح لك هذه العينة كيف يمكنك أن تحمل Webhook SMS باستخدام HTTP GET والنشر.
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 ( ) ; في وحدات تحكم MVC التقليدية ، سيتم ربط SmsRequest و VoiceRequest وكائن الطلب المكتب الآخر ، لكن الحد الأدنى من واجهات برمجة التطبيقات لا يدعم نفس الربط النموذج.
بدلاً من ذلك ، يمكنك ربط المعلمات الفردية لـ HTTP الحصول على طلبات باستخدام سمة FromQuery . عندما لا تحدد سمة FromQuery ، سيتم النظر في مصادر متعددة لربطها بالإضافة إلى معلمات سلسلة الاستعلام. بالنسبة لطلبات نشر HTTP ، يمكنك الحصول على النموذج ثم استرداد المعلمات الفردية عن طريق فهرس السلسلة.
للرد مع TWIML ، استخدم Results.Extensions.TwiML طريقة.
يأتي Twilio.aspnet مع فئات متعددة لمساعدتك في ربط البيانات من Webhooks إلى كائنات .NET المكتوبة بقوة. إليك قائمة الفصول:
SmsRequest : يحتفظ ببيانات لطلبات Webhook SMS الواردةSmsStatusCallbackRequest : يحتفظ ببيانات لتتبع حالة تسليم SMS Twilio الخارجي أو MMSStatusCallbackRequest : يحتفظ ببيانات لتتبع حالة مكالمة صوتية Twilio الصادرةVoiceRequest : يحتفظ ببيانات للمكالمات الصوتية الواردةلاحظ فقط وحدات التحكم في MVC وصفحات الحلاقة النموذجية الملزمة لكائنات .NET المكتوبة. في الحد الأدنى من واجهات برمجة التطبيقات والسيناريوهات الأخرى ، سيتعين عليك كتابة التعليمات البرمجية لاستخراج المعلمات بنفسك.
توضح العينة التالية كيفية قبول الرسائل القصيرة الواردة ، والرد ، وتتبع حالة استجابة الرسائل القصيرة.
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 ) ;
}
} كما هو موضح في العينة أعلاه ، يمكنك إضافة SmsRequest كمعلمة ، وسيقوم MVC بربط الكائن لك. ثم يستجيب الكود باستخدام SMS مع معلمة status method . عندما تتغير حالة الرسائل القصيرة ، سترسل Twilio طلب نشر HTTP إلى إجراءات StatusCallback . يمكنك إضافة SmsStatusCallbackRequest كمعلمة ، وسيقوم MVC بربط الكائن لك.
في ASP.NET Core ، يمكنك إضافة عميل Twilio REST API إلى خدمات ASP.NET Core باستخدام طريقة .AddTwilioClient ، مثل هذا:
using Twilio . AspNet . Core ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services . AddTwilioClient ( ) يمكنك الآن طلب ITwilioRestClient و TwilioRestClient عبر حقن التبعية.
يمكنك تكوين عميل Twilio باستخدام التكوين التالي:
{
"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
}
}
}بضع ملاحظات:
Twilio:Client:AuthToken يعود على Twilio:AuthToken . تحتاج فقط إلى تكوين واحد منهم.Twilio:Client:CredentialType على القيم الصالحة التالية: Unspecified ، AuthToken ، أو ApiKey .Twilio:Client:CredentialType على اطلب اختياري وافتراضيات إلى Unspecified . إذا كان Unspecified ، سواء قمت بتكوين مفتاح API أو تم اكتشاف رمز مصادقة.إذا كنت لا ترغب في تكوين عميل Twilio باستخدام تكوين .NET ، يمكنك القيام بذلك يدويًا:
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 ;
} ) ;تحذير لا ترمز إلى الرمز المميز الخاص بك أو مفتاح API في الكود ولا تتحقق من التحكم في المصدر. نوصي باستخدام مدير الأسرار للتطوير المحلي. بدلاً من ذلك ، يمكنك استخدام متغيرات البيئة أو خدمة قبو أو تقنيات أخرى أكثر أمانًا.
افتراضيًا عند الاتصال .AddTwilioClient ، يتم تكوين مصنع عميل HTTP يتم استخدامه لتوفير HttpClient لعميل Rest Twilio. إذا كنت ترغب في تخصيص عميل HTTP هذا ، فيمكنك القيام بذلك عن طريق تجاوز مصنع عميل HTTP "Twilio" ، بعد استدعاء .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 أن تكون نقطة النهاية متوفرة للجمهور ، ولكن هذا يقدم أيضًا خطرًا على أن الجهات الفاعلة السيئة قد تجد عنوان URL الخاص بك على الويب ومحاولة إساءة استخدامه.
لحسن الحظ ، يمكنك التحقق من أن طلب HTTP نشأ من Twilio. توفر مكتبة Twilio.AspNet سمة من شأنها التحقق من صحة طلبك في MVC. يختلف التنفيذ بين مكتبة Twilio.AspNet.Core و Twilio.AspNet.Mvc .
أضف طريقة .AddTwilioRequestValidation عند بدء التشغيل:
using Twilio . AspNet . Core ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services . AddTwilioRequestValidation ( ) ;ثم قم بتكوين التحقق من صحة الطلب:
{
"Twilio" : {
"AuthToken" : " [YOUR_AUTH_TOKEN] " ,
"RequestValidation" : {
"AuthToken" : " [YOUR_AUTH_TOKEN] " ,
"AllowLocal" : false ,
"BaseUrlOverride" : " https://??????.ngrok.io "
}
}
}بضع ملاحظات حول التكوين:
Twilio:RequestValidation:AuthToken يعود مرة أخرى على Twilio:AuthToken . تحتاج فقط إلى تكوين واحد منهم.AllowLocal التحقق من الصحة عندما نشأ طلب HTTP من المضيف المحلي.BaseUrlOverride في حالة وجود تطبيقك خلف وكيل عكسي أو نفق مثل Ngrok. سيتم إلحاق مسار الطلب الحالي بـ BaseUrlOverride للتحقق من صحة الطلب.معلومات بدلاً من تكوين
BaseUrlOverride، يمكنك استخدام البرامج الوسيطة التي يتم إعادة توجيهها لتعيين المخطط الصحيح ، المنفذ ، المضيف ، إلخ. على طلب HTTP الحالي.
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 ( ) ; نتيجة لذلك ، لا يتعين عليك تكوين BaseUrlOverride كلما قمت بإعادة تشغيل Ngrok ، أو تغيير عناوين URL العكسية. اتبع إرشادات Microsoft لتكوين البرامج الوسيطة التي يتم إعادة توجيهها بشكل آمن.
يمكنك أيضًا تكوين التحقق من صحة الطلب يدويًا:
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" ;
} ) ;تحذير لا ترمز إلى رمز المصادقة في رمز ولا تحقق من التحكم في المصدر. نوصي باستخدام مدير الأسرار للتطوير المحلي. بدلاً من ذلك ، يمكنك استخدام متغيرات البيئة أو خدمة قبو أو تقنيات أخرى أكثر أمانًا.
بمجرد تكوين التحقق من صحة الطلب ، يمكنك استخدام سمة [ValidateRequest] في MVC. يمكنك تطبيق السمة على مستوى العالم ، على مناطق MVC ، وحدات التحكم ، والإجراءات. فيما يلي مثال حيث يتم تطبيق السمة على إجراء 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 مفهوم مرشحات نقطة النهاية التي يمكنك تطبيقها على أي نقطة نهاية ASP.NET الأساسية. أضافت مكتبة Helper لـ ASP.NET Core مرشح نقطة النهاية للتحقق من طلبات Twilio التي تسمى ValidateTwilioRequestFilter .
يمكنك إضافة هذا المرشح إلى أي نقطة نهاية أو مجموعة نقطة النهاية باستخدام طريقة 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" , ( ) => .. . ) ;بدلاً من ذلك ، يمكنك إضافة مرشح نقطة النهاية بنفسك:
app . MapPost ( "/sms" , ( ) => .. . )
. AddEndpointFilter < ValidateTwilioRequestFilter > ( ) ; عندما لا يمكنك استخدام مرشح [ValidateRequest] أو ValidateTwilioRequestFilter ، يمكنك استخدام ValidateTwilioRequestMiddleware بدلاً من ذلك. يمكنك إضافة إضافة ValidateTwilioRequestFilter مثل هذا:
app . UseTwilioRequestValidation ( ) ;
// or the equivalent: app.UseMiddleware<ValidateTwilioRequestMiddleware>(); سيؤدي هذا الوسيطة التحقق من الصحة لجميع الطلبات. إذا كنت لا ترغب في تطبيق التحقق من الصحة على جميع الطلبات ، فيمكنك استخدام app.UseWhen() لتشغيل الوسيطة بشكل مشروط.
فيما يلي مثال على كيفية التحقق من صحة الطلبات التي تبدأ بـ Path /Twilio-Media ، فيما يتعلق بحماية ملفات الوسائط التي يجب أن يكون الوكيل 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 ( ) ; في web.config ، يمكنك تكوين التحقق من صحة الطلب كما هو موضح أدناه:
<? 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 >يمكنك أيضًا تكوين التحقق من صحة الطلب باستخدام إعدادات التطبيق:
<? 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 > إذا قمت بتكوين التحقق من صحة الطلب باستخدام كلا الاتجاهين ، فسيقوم إعداد التطبيق بكتابة عنصر تكوين twilio/requestValidation .
بضع ملاحظات حول التكوين:
allowLocal التحقق من الصحة عندما نشأ طلب HTTP من المضيف المحلي.baseUrlOverride في حال كنت أمام وكيل عكسي أو نفق مثل Ngrok. سيتم إلحاق مسار الطلب الحالي بـ baseUrlOverride للتحقق من صحة الطلب.تحذير لا ترمز إلى رمز المصادقة في رمز ولا تحقق من التحكم في المصدر. استخدم
UserSecretsConfigBuilderللتطوير المحلي أو أحد بناة التكوين الأخرى. بدلاً من ذلك ، يجب عليك تشفير أقسام التكوين التي تحتوي على أسرار مثل رمز المصادقة.
الآن تم تكوين التحقق من صحة الطلب ، استخدم سمة [ValidateRequest] . يمكنك تطبيق السمة على مستوى العالم ، على مناطق MVC ، وحدات التحكم ، والإجراءات. فيما يلي مثال حيث يتم تطبيق السمة على إجراء 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 ) ;
}
} سمة [ValidateRequest] تعمل فقط مع MVC. إذا كنت بحاجة إلى التحقق من صحة الطلبات خارج MVC ، فيمكنك استخدام فئة RequestValidationHelper التي توفرها Twilio.AspNet . بدلاً من ذلك ، يمكن أن تساعدك فئة RequestValidator من Twilio SDK في ذلك.
إليك مثال API الحد الأدنى الذي يتحقق من صحة الطلب الوارد الذي نشأ من 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 تقوم بإضافة TwilioRequestValidationOptions ، والتي يتم استخدامها عادةً في سمة [ValidateRequest] ، ولكن في هذه العينة يتم استخدامها لاسترداد تكوين التحقق من صحة الطلب بنفسك. ثم داخل نقطة نهاية /sms ، يتم استخدام طريقة IsValidTwilioRequest للتحقق من صحة الطلب. يسترجع IsValidTwilioRequest خيارات التحقق من صحة الطلب من DI ويؤدي نفس المنطق الذي سيفعله [ValidateRequest] لطلبات MVC. إذا كان الطلب غير صالح ، فسيتم إرجاع رمز حالة HTTP 403 ، وإلا فإن بعض TWIML يتم إرجاعه إلى Twilio.