
Compartilhar:
Steve é um ex-membro da equipe da Vonage. Ele atuou como Developer Advocate .NET na Vonage, engenheiro de software full-stack poliglota, especializado em IA/ML
Como receber um SMS com o Blazor e o SignalR
Quando se trata de gerenciar mensagens SMS com a Messages API da Vonage, receber mensagens SMS é fundamental. Neste tutorial, vamos explorar como receber mensagens SMS em nosso aplicativo e enviá-las para nosso front-end em tempo real usando o Blazor e SignalR Core.
Ir direto para o código
Se você quiser ir direto para o código, basta acessar o repositório desta demonstração no GitHub.
Pré-requisitos
Você precisará de um Account na API da Vonage
Você precisará da versão mais recente do SDK do .NET Core 3.1
Você precisará do Visual Studio 2019, do Visual Studio para Mac ou do Visual Studio Code; vou usar o VS Code para esta demonstração
Criar o aplicativo
Vá até o diretório onde deseja colocar a pasta do projeto e execute o seguinte comando no terminal.
Depois de fazer isso, cd na ReceiveSmsBlazor pasta que criamos e execute code . para iniciar o VS Code. Como alternativa, você pode abrir o ReceiveSmsBlazor.csproj arquivo no Visual Studio.
Instalar pacotes do NuGet
Existem dois pacotes do NuGet dos quais vamos precisar para esta demonstração.
Volte ao seu terminal e execute:
Criar o SMS Hub
O SignalR distribui todas as mensagens por meio de “Hubs” centrais. Um hub notifica todos os clientes conectados a ele quando ocorre um determinado evento; neste caso, os eventos que receberemos são mensagens SMS recebidas.
Crie uma pasta chamada Hubs. Nessa pasta, crie um arquivo chamado SmsHub.cs e importe o SignalR com using Microsoft.AspNetCore.SignalR; dentro dela. Em seguida, crie uma classe SmsHub dentro do ReceiveSmsBlazor.Hubs namespace da seguinte forma:
namespace ReceiveSmsBlazor.Hubs
{
public class SmsHub : Hub
{
}
}Você não precisa adicionar nenhum código aqui; vamos controlá-lo de fora desta classe; ele só precisa estar aqui para que possamos nos comunicar com todos os clientes do Hub.
Criar nosso controlador
Vamos precisar criar um controlador de API. É nesse controlador que receberemos nossos webhooks de SMS recebidos da Vonage.
Crie uma nova pasta no nível superior do nosso projeto chamada Controllers, e adicione um novo arquivo SmsController.cs a essa pasta.
Abra SmsController.cs e adicione as seguintes instruções using a ele.
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Newtonsoft.Json;
using Vonage.Messaging;
using System.IO;
using System.Threading.Tasks;
using ReceiveSmsBlazor.Hubs;Em seguida, crie uma SmsController classe no ReceiveSmsBlazor.Controllers namespace estendendo Controller e anote-a com uma Route para api/[controller] e um ApiController atributo assim:
namespace ReceiveSmsBlazor.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class SmsController : Controller
{
}
} Injetar o contexto do SmsHub
Para acessar o SmsHub, vamos injetar sua dependência de contexto. Crie uma IHubContext propriedade chamada HubContext na sua SmsController classe e, em seguida, adicione um construtor que receba um IHubContex como argumento e atribua nossa HubContext propriedade a esse valor.
IHubContext<SmsHub> HubContext { get; set; }
public SmsController(IHubContext<SmsHub> hubContext)
{
HubContext = hubContext;
} Adicionar a ação de webhook para SMS recebidos
Agora que nosso Hub já está disponível, só precisamos adicionar um método para processar as mensagens SMS recebidas e enviá-las ao nosso cliente.
Adicione um novo método assíncrono chamado InboundSms que retorne um Task. Nesse método, vamos ler o SMS do corpo da solicitação e, em seguida, enviar uma mensagem para todos os clientes conectados ao nosso SmsHub contendo o Msisdn (o número de origem da mensagem) e Text.
[HttpPost("[action]")]
public async Task<IActionResult> InboundSms()
{
using (var reader = new StreamReader(Request.Body))
{
var json = await reader.ReadToEndAsync();
var inbound = JsonConvert.DeserializeObject<InboundSms>(json);
await HubContext.Clients.All.SendAsync("ReceiveMessage", inbound.Msisdn, inbound.Text);
}
return NoContent();
}Se você tem acompanhado, a rota ficará assim api/sms/inboundsms em nosso servidor quando ele for lançado. Lembre-se disso para mais tarde, pois é para lá que direcionaremos nossos webhooks quando estivermos configurando-os.
Configurar o middleware na inicialização
Como estamos usando controladores e o SignalR, precisamos nos certificar de que o middleware está configurado. Abra Startup.cs e adicione using Microsoft.AspNetCore.ResponseCompression; à seção de importação. Em seguida, acesse o ConfigureServices e adicione o seguinte.
services.AddSignalR();
services.AddResponseCompression(opts => {
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes
.Concat(new []{"application/octet-stream"});
});Este trecho de código irá adicionar o SignalR e a compactação de respostas do SignalR ao seu aplicativo.
Adicionar controlador e SmsHub
O próximo passo é configurar nosso aplicativo para usar nossos controladores e nosso SmsHub. Acesse o Configure método em Startup.cs e adicione a linha app.UseResponseCompression(); no início do método. Em seguida, no UseEndpoints delegado, adicione endpoints.MapControllers(); e endpoints.MapHub("/smshub");. Quando tudo estiver pronto, seu app.UseEndpoints deverá ficar mais ou menos assim:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapHub<Hubs.SmsHub>("/smshub");
endpoints.MapFallbackToPage("/_Host");
}); Adicionar um front-end
Agora que já temos toda a parte interna funcionando para lidar com as mensagens SMS recebidas e que todos os nossos serviços e hubs estão em funcionamento, a última coisa que precisamos fazer é criar uma interface de usuário.
Se você executou dotnet run no seu console e abriu o aplicativo em localhost:5001 você veria a página inicial genérica do Blazor.
Generic Blazor
Se você quiser remover a barra de navegação lateral, basta acessar Shared/MinLayout.razor e remova o sidebar div.
Tudo o mais que precisamos fazer está em Pages/index.razor , então vá em frente e abra esse arquivo agora.
Incorporar dependências
Exclua tudo abaixo da linha 2 em index.razor , pois se trata apenas de um código genérico do tipo “hello world”. Feito isso, vamos importar nosso cliente SignalR, injetar um gerenciador de navegação e declarar que implementaremos a interface IDisposable para limpar o hub do SignalR quando ele for encerrado.
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
@implements IDisposable Adicionar nossa tabela de mensagens
Vamos exibir as mensagens recebidas em uma tabela. Vamos adicionar uma tabela simples ao nosso index.razor arquivo. Adicione o seguinte código Razor.
<h1>Messages</h1>
<table class="table" id="messageList">
<thead>
<tr>
<th>From Number</th>
<th>Message</th>
</tr>
@foreach (var message in _messages)
{
<tr>
<td>@message.FromNumber</td>
<td>@message.Text</td>
</tr>
}
</thead>
</table>O `foreach` percorrerá a _messages e criará uma nova linha com o FromNumber e Text.
Tratar mensagens recebidas
De volta ao nosso controlador, usamos a chamada await HubContext.Clients.All.SendAsync("ReceiveMessage", inbound.Msisdn, inbound.Text); para enviar o Msisdn e Text para todos os clientes conectados ao hub de SMS. Agora é hora de nos conectarmos a esse hub. Vou mostrar a vocês o @code código e, em seguida, explicar como cada parte funciona.
@code {
private HubConnection _hubConnection;
private List<Message> _messages = new List<Message>();
private class Message
{
public string FromNumber { get; set; }
public string Text { get; set; }
}
protected override async Task OnInitializedAsync()
{
_hubConnection = new HubConnectionBuilder()
.WithUrl(NavigationManager.ToAbsoluteUri("/SmsHub"))
.Build();
_hubConnection.On<string, string>("ReceiveMessage", (from, text) =>
{
var message = new Message { FromNumber = from, Text = text };
_messages.Add(message);
StateHasChanged();
});
await _hubConnection.StartAsync();
}
public bool IsConnected => _hubConnection.State == HubConnectionState.Connected;
public void Dispose()
{
_ = _hubConnection.DisposeAsync();
}
} Declarar campos privados e a classe de mensagens
O trecho de código a seguir declara os campos privados do componente. É dessa _messages lista é de onde vamos extrair as mensagens.
private HubConnection _hubConnection;
private List<Message> _messages = new List<Message>();
private class Message
{
public string FromNumber { get; set; }
public string Text { get; set; }
} OnInitializedAsync
Nós sobrescrevemos o OnInitializedAsync método; esse é o método que é chamado quando o componente é inicializado. Esse método inicializa a _hubConnection (a conexão com nosso SmsHub). Em seguida, ele registra um manipulador para o ReceiveMessage callback que estamos invocando com nosso SmsController. Assim, sempre que esse evento ocorrer, esse método será acionado, adicionaremos a mensagem recebida à nossa _messages coleção e, em seguida, chamaremos a StateHasChanged função para informar ao componente que ele precisa ser renderizado novamente; isso fará com que nossas mensagens sejam recarregadas em tempo real. Por fim, iniciamos _hubConnection.
Testes com o Ngrok
Agora que já temos tudo montado, podemos prosseguir e começar a testar com o ngrok. O ngrok nos permite criar um túnel da nossa máquina local até o nosso servidor. Se você estiver usando o ngrok com o IIS Express, recomendo que consulte nosso guia explicativo sobre o assunto , pois há algumas considerações especiais. Para esta demonstração, como estamos usando a CLI do dotnet, não precisamos nos preocupar com isso. Abra seu Properties/launchSettings.json arquivo no objeto profiles; o perfil com o nome do seu aplicativo será usado na inicialização. Verifique o applicationUrl; normalmente, ele apontará para https://localhost:5001 e http://localhost:5000. Certifique-se de excluir aquele que não for SSL e, em seguida, execute o comando a seguir em outra janela do prompt de comando.
Substitua 5000 pelo número da porta em que seu aplicativo será executado sem SSL.
Este comando criará um túnel para essa porta. Agora você pode executar seu aplicativo usando o dotnet run comando. Verifique novamente seu console do ngrok; ele informará a URL acessível publicamente do seu aplicativo.
ngrok
No meu caso, ele está apontando para http://09c1cd61e26e.ngrok.io/. Ao acessar essa URL, consigo ver a interface do usuário do meu aplicativo.
frontend
Configure seus Webhooks
A rota para os webhooks de SMS recebidos é /api/sms/inboundsms com nossa URL do ngrok como caminho base. Isso significa que a rota completa será algo como http://09c1cd61e26e.ngrok.io/api/sms/inboundsms. Agora, basta acessarmos nossa página de configurações e definir a URL das mensagens recebidas como nossa rota, além de definir o método HTTP como POST-JSON. Clique no Save Changes botão na parte inferior e pronto.
SMS settings
Teste
Para testar, basta enviar uma mensagem de texto para um número da Vonage associado a esta Account. Ele pode ser encontrado no painel de controle, na seção Numbers->Seu número.
Ficará mais ou menos assim depois que você receber uma mensagem.
Inbound Message
Conclusão
É só isso que precisamos para poder ver as mensagens SMS chegando em um aplicativo em tempo real. Fica claro que, combinando o SignalR, o Blazor e as APIs da Vonage, podemos criar coisas bem legais!
Recursos
O código desta demonstração pode ser encontrado em GitHub
Você pode saber mais sobre as APIs da Vonage em nosso site para desenvolvedores