https://a.storyblok.com/f/270183/40798/1408cb519b/blog_blazor-signalr_1200x600.png

BlazorとSignalRでSMSを受信する方法

最終更新日 May 5, 2021

所要時間:4 分

SMSメッセージの管理に関しては Vonage Messaging APIでSMSメッセージを管理する場合でSMSメッセージを管理する場合、インバウンドのSMSメッセージを受信することが最も重要です。このチュートリアルでは、SMSメッセージをアプリで受信し、リアルタイムでフロントエンドにプッシュする方法について説明します。 BlazorSignalR コア.

コードへジャンプ

コードにすぐに飛びつきたい場合は、このデモのリポジトリにある GitHub.

前提条件

  • Vonage APIアカウントが必要です。

  • 最新バージョンの .NET Core 3.1 SDK

  • Visual Studio 2019、Visual Studio for Mac、またはVisual Studio Codeのいずれかが必要です。

アプリの作成

プロジェクト・フォルダーを置きたいディレクトリに移動し、ターミナルで以下のコマンドを実行する。

dotnet new blazorserver -o ReceiveSmsBlazor

それが終わったら cd作成した ReceiveSmsBlazorフォルダを作成し code .を実行してVS Codeを起動する。あるいは ReceiveSmsBlazor.csprojファイルを開くこともできる。

NuGetパッケージのインストール

このデモに必要なNuGetパッケージは2つある。

  1. ボネージ

  2. Microsoft.AspNetCore.SignalR.クライアント

コンソールに戻って実行する:

dotnet add package Microsoft.AspNetCore.SignalR.Client dotnet add package Vonage

SMSハブの作成

SignalRは、中央の「ハブ」を通じてすべてのメッセージを配信する。ハブは、特定のイベントが発生すると、それに接続しているすべてのクライアントに通知する。この場合、受信するイベントはSMSメッセージである。

というフォルダを作成する。 Hubs.そのフォルダに SmsHub.csというファイルを作成し using Microsoft.AspNetCore.SignalR;をインポートします。次に、SmsHub クラスを ReceiveSmsBlazor.Hubsを作成する:

namespace ReceiveSmsBlazor.Hubs
{
    public class SmsHub : Hub
    {

    }
}

ここにコードを追加する必要はない。このクラスの外側からこのコードを動かす。

コントローラーの構築

APIコントローラを作成する必要があります。このコントローラで、Vonage からの SMS webhook を受信します。

プロジェクトのトップ・レベルに、新しいフォルダ Controllersという名前の新しいフォルダを作成し、このフォルダに新しいファイル SmsController.csを追加する。

を開き SmsController.csを開き、以下のusing文を追加する。

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Newtonsoft.Json;
using Vonage.Messaging;
using System.IO;
using System.Threading.Tasks;
using ReceiveSmsBlazor.Hubs;

次に SmsControllerクラスを ReceiveSmsBlazor.Controllersを拡張する名前空間にクラスを作成し Controllerでアノテーションを付けます。 Routeapi/[controller]属性と ApiController属性でアノテーションする:

namespace ReceiveSmsBlazor.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class SmsController : Controller
    {

    }
}

SmsHub コンテキストを注入する

SmsHub にアクセスするには、そのコンテキストを依存注入します。そのコンテキストに IHubContextというプロパティを作成します。 HubContextというプロパティを SmsControllerクラスを作成し IHubContexを引数として取るコンストラクタを追加します。 HubContextプロパティをその値に代入します。

IHubContext<SmsHub> HubContext { get; set; }

public SmsController(IHubContext<SmsHub> hubContext)
{
    HubContext = hubContext;
}

受信SMS Webhookアクションを追加する

これでHubが利用可能になったので、あとは受信SMSを処理してクライアントに送信するメソッドを追加するだけだ。

という新しい非同期メソッドを追加する。 InboundSmsを返す Task.このメソッドでは、Request のボディから SMS を読み込み、SmsHub に接続しているすべてのクライアントに、受信メッセージの Msisdn(メッセージの発信元番号) と 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();
}

もし、あなたがこのルートについてきているのであれば、このルートは我々のサーバー上で次のように表示されます。 api/sms/inboundsmsのようになります。Webhookを設定するときに、このルートがWebhookのターゲットになるので、このことを覚えておいてください。

スタートアップでミドルウェアを設定する

コントローラとSignalRを使用するので、ミドルウェアの設定を確認する必要がある。以下を開いて Startup.csを開き、importセクションに using Microsoft.AspNetCore.ResponseCompression;をインポートセクションに追加する。次に ConfigureServicesメソッドに追加します。

services.AddSignalR();
services.AddResponseCompression(opts => {
    opts.MimeTypes = ResponseCompressionDefaults.MimeTypes
        .Concat(new []{"application/octet-stream"});
});

このスニペットは、アプリケーションにSignalRとSignalR用のレスポンス圧縮を追加します。

コントローラーとSmsHubの追加

次に必要なのは、アプリケーションにコントローラと SmsHub を使用するように指示することです。アプリケーションの Configureメソッドの Startup.csメソッドにドロップし、メソッドの最初に app.UseResponseCompression();を追加します。次に UseEndpointsデリゲートに endpoints.MapControllers();そして endpoints.MapHub("/smshub");.すべて終わったら app.UseEndpointsはこのようになる:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapBlazorHub();
    endpoints.MapHub<Hubs.SmsHub>("/smshub");
    endpoints.MapFallbackToPage("/_Host");
});

フロントエンドの追加

さて、インバウンドのSMSを処理するための内部的なものがすべて動作し、すべてのサービスとハブが立ち上がったので、最後にフロントエンドを作成する必要がある。

コンソールで dotnet runコンソールで localhost:5001でアプリを開くと、一般的なblazorのスターターページが表示されます。

Generic BlazorGeneric Blazor

サイドのナビゲーションバーを削除したい場合は Shared/MinLayout.razorsidebardiv.

他に必要なことはすべて Pages/index.razorにあるので、そのファイルを開く。

依存関係を取り込む

の2行目以下をすべて削除する。 index.razorの2行目以下を削除する。これで、SignalRクライアントをインポートし、ナビゲーション・マネージャーをインジェクトし、SignalRハブが終了したときにクリーンアップするためにIDisposableを実装することを宣言しよう。

@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
@implements IDisposable

メッセージ・テーブルの追加

受信メッセージをテーブルに表示します。簡単なテーブルを index.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>

foreachはページの _messagesコレクションをループし、各メッセージの FromNumberそして Text.

インバウンドメッセージの処理

コントローラに戻って await HubContext.Clients.All.SendAsync("ReceiveMessage", inbound.Msisdn, inbound.Text);を呼び出して、受信メッセージの MsisdnTextをSMSハブに接続されているすべてのクライアントに送信します。次に、ハブに接続する。次に、SMSハブに接続する方法を説明します。 @codeブロブ全体をお見せしてから、各パーツがどのように動作するかを説明します。

@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();
    }
}

プライベート・フィールドとメッセージ・クラスの宣言

次のコードでは、コンポーネントのプライベート・フィールドを宣言している。この _messagesリストがメッセージを引っ張ってくる場所です。

private HubConnection _hubConnection;
private List<Message> _messages = new List<Message>();
private class Message
{
    public string FromNumber { get; set; }
    public string Text { get; set; }
}

OnInitializedAsync

メソッドをオーバーライドします。 OnInitializedAsyncこれはコンポーネントが初期化されるときに呼び出されるメソッドです。このメソッドは _hubConnection(への接続)を初期化します。 SmsHub).そして ReceiveMessageコールバックのハンドラを登録します。 SmsController.したがって、イベントが発生するたびにこのメソッドが起動し、受信メッセージを _messagesコレクションに追加し StateHasChanged関数を呼び出してコンポーネントに再レンダリングの必要性を伝えます。最後に _hubConnection.

Ngrokを使ったテスト

これですべてのビルドが完了したので、ngrokを使ってテストしてみよう。ngrok を使うと、ローカルマシンからサーバーへのトンネルを作成できる。IIS Expressでngrokを使用している場合は、このテーマに関する私たちの解説をチェックすることをお勧めする。 の説明を参照してください。このデモでは、dotnet CLIを使用するので、この点を心配する必要はない。プロファイル・オブジェクトの Properties/launchSettings.jsonファイルをprofilesオブジェクトで開き、アプリの名前にちなんだプロファイルが起動時に使用されます。をチェックしてください。 applicationUrlをチェックしてください。 https://localhost:5001そして http://localhost:5000.これらのうち、SSLでない方を確実に削除してから、別のコマンド・プロンプト・ウィンドウで以下のコマンドを実行してください。

ngrok http 5000

5000を、SSLなしで実行するアプリのポート番号に置き換えてください。

このコマンドは、そのポートへのトンネルを構築する。これで dotnet runコマンドを使ってアプリケーションを実行できます。ngrokコンソールに戻って確認してください; あなたのアプリの一般にアクセス可能なURLが表示されます。

ngrokngrok

私の場合は http://09c1cd61e26e.ngrok.io/.そのURLにナビゲートすることで、私のアプリケーションのフロントエンドを見ることができる。

frontendfrontend

ウェブフックの設定

受信SMSウェブフックのルートは /api/sms/inboundsmsで、ngrokのURLをベースパスとしています。つまり、完全なルートは以下のようになります。 http://09c1cd61e26e.ngrok.io/api/sms/inboundsms.あとは 設定ページに移動し、受信メッセージの URL をルートに設定し、HTTP メソッドを POST-JSON.一番下の Save Changesボタンをクリックすれば完了です。

SMS settingsSMS settings

テスト

テストするには、このアカウントに関連付けられているVonage Numbersにテキストメッセージを送信するだけです。これはダッシュボードの 番号->あなたの番号.

メッセージを受信すると、このように表示されます。

Inbound MessageInbound Message

まとめ

これだけで、SMSメッセージがリアルタイムでアプリに入ってくるのを見ることができる。SignalR、Blazor、そしてVonage APIを組み合わせることで、クールなものが作れることは明らかだ!

リソース

シェア:

https://a.storyblok.com/f/270183/384x384/73d57fd8eb/stevelorello.png
Steve Lorelloヴォネージの卒業生

スティーブは、かつてVonageチームの一員でした。彼はVonageで.NET開発者アドボケートを務め、フルスタックかつ多言語対応のソフトウェアエンジニアであり、AI/MLの専門家でもありました。