Эта статья была написана для компании Twilio и первоначально опубликована в блоге Twilio.
Когда вы разрабатываете веб-приложения на своей локальной машине, вам иногда требуется, чтобы ваше приложение было доступно из интернета. Одной из наиболее распространенных причин для этого является разработка веб-крючков.
Webhooks — это способ получения уведомления от внешней службы о наступлении события. Вместо того чтобы вы отправляли HTTP-запрос в эту службу, служба отправляет HTTP-запрос в вашу публичную веб-службу.
Для локальной разработки веб-крючков можно использовать туннельный сервис, например ngrok, который создает туннель между вашей локальной сетью и Интернетом. Однако, если вы используете бесплатный тарифный план ngrok, ngrok будет создавать случайный публичный URL при каждом перезапуске туннеля. Это означает, что вам необходимо обновлять веб-крючки с новым URL при каждом его изменении. Если обновление URL веб-крючков требует множества щелчков и нажатий клавиш, это может быть довольно хлопотно.
К счастью, вы можете избежать повторяющейся работы, автоматизировав ее! В этом руководстве вы узнаете, как автоматически запускать ngrok при запуске приложения ASP.NET Core. Затем вы узнаете, как получить произвольный URL ngrok и использовать его для автоматической настройки веб-крючков Twilio.
Предварительные условия
Вам понадобятся следующие элементы:
- ОС с поддержкой .NET (Windows/macOS/Linux)
- .NET 6 SDK
- Редактор кода или IDE (рекомендуется VS Code с плагином C#, Visual Studio или JetBrains Rider).
- Ngrok CLI
- Бесплатная учетная запись Ngrok (необязательно)
- Бесплатный аккаунт Twilio (если вы зарегистрируетесь здесь, то получите $10 в кредит Twilio при переходе на платный аккаунт!)
Исходный код этого руководства вы можете найти на GitHub. Используйте исходный код, если у вас возникнут какие-либо проблемы, или отправьте проблему в эту репозиторию GitHub, если у вас возникнут проблемы.
Создание веб-проекта ASP.NET Core
Откройте предпочитаемую оболочку и с помощью команд ниже создайте новую папку с именем NgrokAspNet и перейдите в нее:
mkdir NgrokAspNet
cd NgrokAspNet
С помощью .NET CLI создайте новый пустой веб-проект:
dotnet new web
Ваш новый проект содержит один файл C# с именем Program.cs:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
Программа создает новое веб-приложение с одной конечной точкой, отвечающей на «Hello World». Вернитесь в оболочку и запустите проект с помощью .NET CLI:
dotnet run
Вывод должен выглядеть следующим образом:
Building...
info: Microsoft.Hosting.Lifetime[14]
Now listening on: https://localhost:7121
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:5033
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: /Users/nswimberghe/NgrokAspNet/
Обратите внимание на два URL-адреса localhost, которые были выбраны при создании веб-проекта.
Выберите один из URL и откройте его в веб-браузере. В браузере должно появиться сообщение «Hello World!».
Оставьте проект .NET запущенным и откройте новую оболочку, чтобы выполнить следующие команды!
Используйте ngrok для туннелирования локального веб-сервера в Интернет
Вы можете запустить инструмент ngrok CLI на своей машине для туннелирования локального URL в публичный URL, похожий на https://66a605a7ced5.ngrok.io, с другим поддоменом. Каждый раз, когда вы запускаете новый туннель с помощью ngrok, поддомен будет другим.
В новой оболочке выполните следующую команду:
ngrok http [YOUR_HTTP_SERVER_URL]
Замените [YOUR_HTTP_SERVER_URL] на URL веб-сервера, начинающийся с http://localhost.
Это запустит новый туннель к новому публичному URL, который вы сможете найти в отображаемом выводе:
Переключитесь обратно на веб-браузер и перейдите к одному из URL Forwarding, перечисленных в вашей оболочке. Некоторые браузеры могут предупредить вас о том, что это обманчивый сайт, на что в данном случае можно не обращать внимания. Браузер должен снова выдать «Hello World», но на этот раз через публичный URL. Это означает, что вы можете поделиться этим URL с кем угодно, и они также смогут общаться с вашим локальным веб-сервером. Это также означает, что веб-крючки смогут связаться с вашим локальным сервером.
Вы также можете туннелировать HTTPS URL, но для этого вам необходимо зарегистрироваться в ngrok (бесплатно) и аутентифицировать ваш инструмент ngrok CLI. После этого вы также можете запустить команду ngrok http
с URL, начинающимся с https://localhost.
Помимо URL переадресации, также отображается URL веб-интерфейса. Это место, где вы можете получить доступ к локальной приборной панели и API ngrok. Переключитесь обратно в браузер и перейдите по адресу http://localhost:4040. Здесь вы снова найдете URL переадресации, а также журнал всех HTTP-запросов, проходящих через туннель.
Остановите процесс ngrok, нажав ctrl + c, и закройте этот экземпляр оболочки. Переключитесь на другую оболочку и остановите проект .NET, нажав ctrl + c.
Автоматический запуск ngrok при запуске ASP.NET Core
Вы смогли публично обслужить свое веб-приложение, запустив проект ASP.NET, а затем запустив ngrok в отдельной оболочке. Этот рабочий процесс можно оптимизировать, интегрировав ngrok в процесс запуска вашего проекта ASP.NET.
Чтобы запустить туннель ngrok программно, вам нужно будет выполнить команду ngrok CLI из кода. Вы можете использовать API Process
.NET, но существует библиотека с открытым исходным кодом, которая упрощает взаимодействие с инструментами и процессами CLI: CliWrap.
Добавьте пакет CliWrap NuGet с помощью .NET CLI:
dotnet add package CliWrap
На момент написания этой статьи пакет CliWrap NuGet имеет версию 3.4.0.
Создайте новый файл C# в каталоге проекта NgrokAspNet с именем TunnelService.cs и добавьте следующий код:
using System.Text.Json.Nodes;
using CliWrap;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
namespace NgrokAspNet;
public class TunnelService : BackgroundService
{
private readonly IServer server;
private readonly IHostApplicationLifetime hostApplicationLifetime;
private readonly IConfiguration config;
private readonly ILogger<TunnelService> logger;
public TunnelService(
IServer server,
IHostApplicationLifetime hostApplicationLifetime,
IConfiguration config,
ILogger<TunnelService> logger
)
{
this.server = server;
this.hostApplicationLifetime = hostApplicationLifetime;
this.config = config;
this.logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await WaitForApplicationStarted();
var urls = server.Features.Get<IServerAddressesFeature>()!.Addresses;
// Use https:// if you authenticated ngrok, otherwise, you can only use http://
var localUrl = urls.Single(u => u.StartsWith("http://"));
logger.LogInformation("Starting ngrok tunnel for {LocalUrl}", localUrl);
var ngrokTask = StartNgrokTunnel(localUrl, stoppingToken);
var publicUrl = await GetNgrokPublicUrl();
logger.LogInformation("Public ngrok URL: {NgrokPublicUrl}", publicUrl);
await ngrokTask;
logger.LogInformation("Ngrok tunnel stopped");
}
private Task WaitForApplicationStarted()
{
var completionSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
hostApplicationLifetime.ApplicationStarted.Register(() => completionSource.TrySetResult());
return completionSource.Task;
}
private CommandTask<CommandResult> StartNgrokTunnel(string localUrl, CancellationToken stoppingToken)
{
var ngrokTask = Cli.Wrap("ngrok")
.WithArguments(args => args
.Add("http")
.Add(localUrl)
.Add("--log")
.Add("stdout"))
.WithStandardOutputPipe(PipeTarget.ToDelegate(s => logger.LogDebug(s)))
.WithStandardErrorPipe(PipeTarget.ToDelegate(s => logger.LogError(s)))
.ExecuteAsync(stoppingToken);
return ngrokTask;
}
private async Task<string> GetNgrokPublicUrl()
{
using var httpClient = new HttpClient();
for (var ngrokRetryCount = 0; ngrokRetryCount < 10; ngrokRetryCount++)
{
logger.LogDebug("Get ngrok tunnels attempt: {RetryCount}", ngrokRetryCount + 1);
try
{
var json = await httpClient.GetFromJsonAsync<JsonNode>("http://127.0.0.1:4040/api/tunnels");
var publicUrl = json["tunnels"].AsArray()
.Select(e => e["public_url"].GetValue<string>())
.SingleOrDefault(u => u.StartsWith("https://"));
if (!string.IsNullOrEmpty(publicUrl)) return publicUrl;
}
catch
{
// ignored
}
await Task.Delay(200);
}
throw new Exception("Ngrok dashboard did not start in 10 tries");
}
}
Класс TunnelService
будет отвечать за запуск туннеля с помощью ngrok CLI, а позже он также настроит веб-крючки Twilio.
Это очень много кода, поэтому давайте разберем его по частям.
public TunnelService(
IServer server,
IHostApplicationLifetime hostApplicationLifetime,
IConfiguration config,
ILogger<TunnelService> logger
)
{
this.server = server;
this.hostApplicationLifetime = hostApplicationLifetime;
this.config = config;
this.logger = logger;
}
Конструктор принимает несколько параметров, которые будут предоставлены контейнером инъекции зависимостей, встроенным в ASP.NET Core. Все параметры хранятся в приватных полях, поэтому они доступны во всем классе.
- Параметр
server
содержит информацию о запущенном веб-сервере. После запуска веб-сервера вы можете получить локальные URL из поляserver
. - Параметр
hostApplicationLifetime
позволяет подключиться к различным событиям жизненного цикла (запущен/остановлен/остановлен). Параметрconfig
будет содержать всю конфигурацию, переданную в приложение .NET через аргументы командной строки, переменные окружения, JSON-файлы, пользовательские секреты и т. д. Сейчас config не используется, но он будет использован в одном из следующих разделов. - Параметр
logger
будет использоваться для записи в журнал любой информации, относящейся к запуску туннеля.
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await WaitForApplicationStarted();
var urls = server.Features.Get<IServerAddressesFeature>()!.Addresses;
// Use https:// if you authenticated ngrok, otherwise, you can only use http://
var localUrl = urls.Single(u => u.StartsWith("http://"));
logger.LogInformation("Starting ngrok tunnel for {LocalUrl}", localUrl);
var ngrokTask = StartNgrokTunnel(localUrl, stoppingToken);
var publicUrl = await GetNgrokPublicUrl();
logger.LogInformation("Public ngrok URL: {NgrokPublicUrl}", publicUrl);
await ngrokTask;
logger.LogInformation("Ngrok tunnel stopped");
}
TunnelService
наследуется от абстрактного класса BackgroundService
, поэтому вам необходимо реализовать абстрактный метод ExecuteAsync
. ExecuteAsync
является основным методом этого класса и будет вызываться при запуске веб-приложения. ExecuteAsync
будет ждать запуска веб-приложения с помощью WaitForApplicationStarted
, а затем возьмет локальные URL. Из локальных URL будет взят один URL. Если вы аутентифицировали ngrok ранее, вы можете использовать HTTPS URL вместо HTTP URL, заменив "http://"
на "https://"
.
Далее будет запущен туннель ngrok, затем будет получен публичный URL ngrok, и, наконец, ожидается Task
для запуска ngrok CLI. Когда веб-приложение остановится, процесс ngrok также будет остановлен, что приведет к завершению ngrokTask
.
private Task WaitForApplicationStarted()
{
var completionSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
hostApplicationLifetime.ApplicationStarted.Register(() => completionSource.TrySetResult());
return completionSource.Task;
}
WaitForApplicationStarted
создаст ожидающую Task
, которая будет завершена при срабатывании события ApplicationStarted
. Странно, но события жизненного цикла на IHostApplicationLifetime
не используют делегаты или события C#, вместо этого они представляют собой CancellationToken
.
Вы можете передать лямбду или делегат в метод CancellationToken.Register
, который будет вызван, когда CancellationToken
будет отменен. В случае токена отмены, хранящегося в свойстве IHostApplicationLifetime.ApplicationStarted
, когда токен отменяется, это означает, что приложение запущено. Как (не)интуитивно, я прав?
Чтобы сделать это более интуитивным в использовании, вы можете создать TaskCompletionSource
и установить его результат в обратный вызов hostApplicationLifetime.ApplicationStarted.Register
. Это установит Task
как завершенную, что в данном случае будет означать запуск приложения.
Если все это немного запутано, важно понять, что await WaitForApplicationStarted()
будет ждать запуска веб-приложения.
private CommandTask<CommandResult> StartNgrokTunnel(string localUrl, CancellationToken stoppingToken)
{
var ngrokTask = Cli.Wrap("ngrok")
.WithArguments(args => args
.Add("http")
.Add(localUrl)
.Add("--log")
.Add("stdout"))
.WithStandardOutputPipe(PipeTarget.ToDelegate(s => logger.LogDebug(s)))
.WithStandardErrorPipe(PipeTarget.ToDelegate(s => logger.LogError(s)))
.ExecuteAsync(stoppingToken);
return ngrokTask;
}
StartNgrokTunnel
будет использовать библиотеку CliWrap для запуска ngrok CLI. Результирующая команда будет выглядеть следующим образом:
ngrok http [YOUR_LOCAL_SERVER_URL] --log stdout
Эта команда запустит туннель ngrok, как и раньше, но с добавлением аргумента --log stdout
. Этот аргумент log указывает ngrok вести журнал на стандартный вывод, который затем может быть захвачен через WithStandardOutputPipe
. Стандартный вывод и вывод ошибок будут переданы в logger
.
Важной деталью является то, что stoppingToken
передается в ExecuteAsync
. Токен stoppingToken
будет отменен, когда приложение будет остановлено. Вы можете использовать этот токен для изящной обработки, когда приложение собирается быть остановленным. Передавая stoppingToken
в ExecuteAsync
, процесс ngrok также будет остановлен, когда приложение будет остановлено. Таким образом, у вас не будет никаких дочерних процессов ngrok.
private async Task<string> GetNgrokPublicUrl()
{
using var httpClient = new HttpClient();
for (var ngrokRetryCount = 0; ngrokRetryCount < 10; ngrokRetryCount++)
{
logger.LogDebug("Get ngrok tunnels attempt: {RetryCount}", ngrokRetryCount + 1);
try
{
var json = await httpClient.GetFromJsonAsync<JsonNode>("http://127.0.0.1:4040/api/tunnels");
var publicUrl = json["tunnels"].AsArray()
.Select(e => e["public_url"].GetValue<string>())
.SingleOrDefault(u => u.StartsWith("https://"));
if (!string.IsNullOrEmpty(publicUrl)) return publicUrl;
}
catch
{
// ignored
}
await Task.Delay(200);
}
throw new Exception("Ngrok dashboard did not start in 10 tries");
}
Функция GetNgrokPublicUrl
получает публичный HTTPS URL и возвращает его. Вы можете получить публичный URL туннеля, запросив его из локального API ngrok по адресу http://127.0.0.1:4040/api/tunnels.
К сожалению, когда ngrok CLI запущен, это еще не означает, что туннель готов. Вот почему этот код окружен циклом, который будет пытаться получить публичный URL до 10 раз, каждые 200 миллисекунд. Не стесняйтесь изменять задержку в 200 мс и retryCount
так, как вам удобно.
Класс TunnelService
завершен, но вам еще нужно настроить веб-приложение для его работы в фоновом режиме. Обновите файл Program.cs, руководствуясь выделенными строками ниже:
var builder = WebApplication.CreateBuilder(args);
if (builder.Environment.IsDevelopment())
builder.Services.AddHostedService<NgrokAspNet.TunnelService>();
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
TunnelService
будет настроен для работы в фоновом режиме, но только когда приложение запущено в среде разработки. В конце концов, вы хотите использовать туннель ngrok только для локальной разработки.
Не имеет смысла запускать его в staging или production, и, скорее всего, он вызовет проблемы, если будет запущен. Вместо того чтобы запускать это только в среде разработки, вы также можете добавить более явный элемент конфигурации, но это уже на ваше усмотрение!
Вот и все! Запустите приложение с помощью .NET CLI и посмотрите на результат:
dotnet run
Публичный ngrok URL будет записан в выходной файл следующим образом: «Публичный ngrok URL: https://6797-72-66-29-154.ngrok.io». Возьмите публичный ngrok URL и перейдите на него в браузере. Вы снова увидите «Hello World!».
Автоматическое обновление Twilio Webhooks с помощью ngrok URLs
Начните работу с Twilio
Если вы еще этого не сделали, вам нужно будет настроить следующие параметры Twilio:
- Приобретите новый телефонный номер у Twilio. Стоимость телефонного номера будет применена к вашему бесплатному рекламному кредиту. Обязательно запишите ваш новый телефонный номер Twilio. Он понадобится вам позже!
- Если вы используете пробную учетную запись Twilio, вы можете отправлять текстовые сообщения только на проверенные идентификаторы абонентов. Проверьте свой номер телефона или номер телефона, на который вы хотите отправить SMS, если его нет в списке проверенных идентификаторов абонентов.
- Наконец, вам нужно найти SID вашего аккаунта Twilio и Auth Token. Перейдите на страницу вашего аккаунта Twilio и обратите внимание на SID вашего аккаунта Twilio и Auth Token, расположенные в левой нижней части страницы.
Обновление веб-крючков Twilio Phone Number Webhooks
Twilio SDK для C# и .NET поможет вам взаимодействовать с API Twilio и отвечать на веб-крючки. Добавьте пакет Twilio NuGet в свой проект:
dotnet add package twilio
Вернитесь в редактор кода и откройте файл TunnelService.cs. Обновите утверждения using
в верхней части файла, чтобы включить эти три новые ссылки Twilio:
using System.Text.Json.Nodes;
using CliWrap;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Twilio.Clients;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
Обновите метод ExecuteAsync
, чтобы вызвать асинхронный метод ConfigureTwilioWebhook
после регистрации публичного URL ngrok:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await WaitForApplicationStarted();
var urls = server.Features.Get<IServerAddressesFeature>()!.Addresses;
// Use https:// if you authenticated ngrok, otherwise, you can only use http://
var localUrl = urls.Single(u => u.StartsWith("http://"));
logger.LogInformation("Starting ngrok tunnel for {LocalUrl}", localUrl);
var ngrokTask = StartNgrokTunnel(localUrl, stoppingToken);
var publicUrl = await GetNgrokPublicUrl();
logger.LogInformation("Public ngrok URL: {NgrokPublicUrl}", publicUrl);
await ConfigureTwilioWebhook(publicUrl);
await ngrokTask;
logger.LogInformation("Ngrok tunnel stopped");
}
Добавьте асинхронный метод ConfigureTwilioWebhook
после метода GetNgrokPublicUrl
:
private async Task ConfigureTwilioWebhook(string publicUrl)
{
var twilioClient = new TwilioRestClient(config["TwilioAccountSid"], config["TwilioAuthToken"]);
var phoneNumber = (await IncomingPhoneNumberResource.ReadAsync(
phoneNumber: new PhoneNumber(config["TwilioPhoneNumber"]),
limit: 1,
client: twilioClient
)).Single();
phoneNumber = await IncomingPhoneNumberResource.UpdateAsync(
phoneNumber.Sid,
voiceUrl: new Uri($"{publicUrl}/voice"), voiceMethod: Twilio.Http.HttpMethod.Post,
smsUrl: new Uri($"{publicUrl}/message"), smsMethod: Twilio.Http.HttpMethod.Post,
client: twilioClient
);
logger.LogInformation(
"Twilio Phone Number {TwilioPhoneNumber} Voice URL updated to {TwilioVoiceUrl}",
phoneNumber.PhoneNumber,
phoneNumber.VoiceUrl
);
logger.LogInformation(
"Twilio Phone Number {TwilioPhoneNumber} Message URL updated to {TwilioMessageUrl}",
phoneNumber.PhoneNumber,
phoneNumber.SmsUrl
);
}
Метод ConfigureTwilioWebhook
получает публичный ngrok URL в качестве параметра. SID аккаунта и Auth Token извлекаются из поля config
и передаются в конструктор TwilioRestClient
.
Вы можете использовать API-ключи для аутентификации вместо использования SID учетной записи и Auth Token. API-ключи имеют меньше прав доступа и могут быть легче отозваны, что делает их более безопасным вариантом.
Данные телефонного номера Twilio запрашиваются с помощью TwilioRestClient
, а затем данные телефонного номера используются для обновления URL голосового webhook и URL SMS webhook. URL голосового и SMS вебхуков будут установлены в публичный URL туннеля с приставкой /voice
и /message
соответственно_._
Теперь проект зависит от конфигурационного элемента TwilioAccountSid
, TwilioAuthToken
и TwilioPhoneNumber
, но они еще не настроены. Вы можете использовать секреты пользователей .NET для настройки этих типов чувствительной конфигурации.
Инициализируйте пользовательские секреты для своего проекта с помощью .NET CLI:
dotnet user-secrets init
Выполните следующую команду для настройки секретов:
dotnet user-secrets set TwilioAccountSid [YOUR ACCOUNT SID]
dotnet user-secrets set TwilioAuthToken [YOUR AUTH TOKEN]
dotnet user-secrets set TwilioPhoneNumber [YOUR TWILIO PHONE NUMBER]
Замените [YOUR ACCOUNT SID]
на SID вашего аккаунта Twilio, [YOUR AUTH TOKEN]
на ваш Twilio Auth Token, и [YOUR TWILIO PHONE NUMBER]
на ваш Twilio Phone Number.
Протестируйте свою работу, запустив приложение:
dotnet run
Вы должны увидеть дополнительный вывод, который выглядит следующим образом: «Twilio Phone Number +1234567890 Voice URL updated to https://5fb3-72-66-29-154.ngrok.io/voice» и «Twilio Phone Number +1234567890 Message URL updated to https://5fb3-72-66-29-154.ngrok.io/message».
Ответ на веб-крючки Twilio
После установки URL веб-крючков Twilio будет отправлять HTTP-запросы на ваши публичные URL всякий раз, когда на ваш номер телефона Twilio поступает звонок или SMS.
Вам необходимо принять эти HTTP-запросы для /voice
и /message
, а затем ответить на них инструкциями TwiML. Обновите Program.cs на основе выделенных строк в приведенном ниже коде:
using Twilio.TwiML;
var builder = WebApplication.CreateBuilder(args);
if (builder.Environment.IsDevelopment())
builder.Services.AddHostedService<NgrokAspNet.TunnelService>();
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.MapPost("/voice", () =>
{
var response = new VoiceResponse();
response.Say("Hello World!");
return Results.Text(response.ToString(), "application/xml");
});
app.MapPost("/message", () =>
{
var response = new MessagingResponse();
response.Message("Hello World!");
return Results.Text(response.ToString(), "application/xml");
});
app.Run();
Когда Twilio отправит HTTP POST запрос на /voice
, конечная точка ответит следующим TwiML:
<?xml version="1.0" encoding="utf-8"?>
<Response>
<Say>Hello World!</Say>
</Response>
В результате Twilio расшифрует «Hello World!» на аудио и передаст его звонящему.
Когда Twilio отправит HTTP POST запрос на /message
, конечная точка ответит следующим TwiML:
<?xml version="1.0" encoding="utf-8"?>
<Response>
<Message>Hello World!</Message>
</Response>
В результате Twilio ответит текстовым сообщением со словами «Hello World!».
Тестирование веб-крючков Twilio
Если все прошло успешно, теперь вы можете разрабатывать и тестировать webhooks, выполнив одну команду dotnet run
. Запустите приложение с помощью .NET CLI:
dotnet run
Дождитесь обновления URL-адресов веб-крючков, а затем позвоните и/или отправьте сообщение на ваш номер телефона Twilio.
Если вы позвоните, вы должны услышать «Hello World!», а если отправите СМС, то получите текстовое сообщение с текстом «Hello World!».
Как интегрировать ngrok в ASP.NET и автоматически обновлять веб-крючки
В этом руководстве вы узнали, как упростить процесс разработки webhook, интегрировав ngrok в стартап ASP.NET Core и автоматически обновляя webhooks, с помощью следующих шагов:
- Получите локальные URL-адреса ASP.NET
- Используйте
BackgroundService
для запуска туннеля ngrok - Получите URL пересылки ngrok из локального API ngrok.
- Обновляйте URL ваших веб-крюков, используя URL переадресации ngrok.
У Twilio есть много других продуктов, которые вы можете интегрировать в свои приложения. Посмотрите это руководство о том, как совершать телефонные звонки из Blazor WebAssembly с помощью Twilio Voice и Twilio Client.
Дополнительные ресурсы
Ознакомьтесь со следующими ресурсами для получения дополнительной информации по темам и инструментам, представленным в этом руководстве:
TwiML для программируемого голоса — Узнайте больше о TwiML и о том, как вы можете использовать TwiML для обработки телефонных звонков.
TwiML для программируемых SMS — Узнайте больше о TwiML и о том, как вы можете использовать TwiML для ответа на текстовые сообщения.
Исходный код этого руководства на GitHub — Используйте этот исходный код, если у вас возникнут какие-либо проблемы, или отправьте проблему на этом репозитории GitHub, если у вас возникнут проблемы.
Нильс Свимберге — бельгийско-американский инженер-программист и создатель технического контента в компании Twilio. Общайтесь с Нильсом в Twitter @RealSwimburger и следите за личным блогом Нильса о .NET, Azure и веб-разработке на сайте swimburger.net.