
シェア:
Jo is a developer advocate at Ably. She is passionate about Realtime Data, PWAs and great CSS. She has 10 years of experience as a front end developer and has worked in various parts of the tech industry from startups, agencies, charities to large organisations. She is also an instructor/mentor at codebar.io and Front End Foxes where she is able to act on her goals of not only teaching good use of the web but also improving the diversity and inclusivity of the tech industry.
Next.JS、Ably、Vercelを使ってSMS通知をブラウザに表示する
Vonageの Vonage SMS APIでは、Vonageからレンタルできるバーチャル番号を使って、世界中でテキストメッセージを送受信できます。
このチュートリアルでは、Vonage SMS API、Ablyリアルタイムメッセージングプラットフォーム、Next.js、Vercelを使用して、SMSメッセージを受信すると同時にブラウザでリアルタイムに受信します。
その方法を学んでみよう:
依存関係
Vonage API Account
To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.
This tutorial also uses a virtual phone number. To purchase one, go to Numbers > Buy Numbers and search for one that meets your needs.
このアプリを作るには、以下も必要です:
Ablyアカウントメッセージ送信用 Ablyアカウントを無料で作成する.
Vercelアカウント本番ホスティング用 無料でVercelアカウントを作成する.
ノード 12(LTS)以上: ノードのインストール.
ローカル・デベロッパーの事前要件
Ablyサービスの認証には、AblyからのAPIキーが必要です。API キーを取得するには Ably アカウントを作成します。:
あなたの アプリダッシュボードをクリックします。
新しいアプリに名前をつける
アプリが作成されたら、プライベートAPIキーをコピーしてください。Ablyサービスとの認証に使用しますので、大切に保管してください。
Vercelは、Next.jsのコマンドラインツールをいくつか提供しています。これらのツールはシステムにインストールする必要はありません。 npx.
Ablyを使ったVercelのWebSockets

Vercelは、Next.jsアプリとServerless Functionsをホストするためにゼロから構築されたホスティングプラットフォームです。ユーザーは次のようなデプロイが可能です。 サーバーレスファンクションこれは基本的にHTTPリクエストに応答するコードのブロックに過ぎない。
しかし、これらの関数には最大実行タイムアウトがあり、この方法ではWebSocket接続を維持することは不可能です。
そこでAblyの出番だ。クライアントは Ably チャンネルに接続してメッセージを送受信することで、WebSocket 接続を管理してアプリにリアルタイム機能を追加することができます。このチュートリアルでは、リアルタイム機能を使うアプリの作り方を説明します。Next.jsとVercelのWebSocketについてもっと知りたい方は、" をご覧ください。Next.jsとVercelでリアルタイムチャットアプリを作る".
リアルタイムSMSアプリの構築
スターターアプリを作成する:
ターミナルで
npx create-next-appを入力して、空のNext.jsアプリを作成します。ディレクトリのルートに
.envというファイルを作成する。ここにプロジェクトの環境変数を置く。AblyのAPIキーを.envファイルに追加します:
ABLY_API_KEY=your-ably-api-key:goes-hereNext.jsアプリケーションのディレクトリに移動し、コンソールに次のように入力します:
Next.jsの開発サーバーが立ち上がり、空のNext.JSスターターアプリが表示されます。この上にSMSアプリを構築します。
AblyのリアルタイムPub/Subメッセージング
このアプリは Ablyを使用しています。 パブ/サブメッセージングを使用しています。Pub/SubはPublish and Subscribeの略で、リアルタイムデータ配信によく使われるパターンです。アプリは publishアプリは アブリチャンネル.アプリを使用するクライアントは subscribedに接続され、メッセージを受信することができます。
Ablyサービスによる認証
Vercel Next.jsアプリは、従来の「サーバーサイドコード」を実行しません。しかし、JavaScriptファイルを /pages/api/*にJavaScriptファイルを追加すると、VercelのデプロイエンジンがそれぞれをAPIエンドポイントとして扱い、サーバーレス関数として管理してくれます。
ローカルで開発する場合、Next.jsツールはこれらの関数をNodeサーバーで実行するので、ローカルの開発環境と同じように動作します。先ほど作成したスターターコードにNext.js / Vercelサーバーレス関数を追加して、アプリをAblyで認証し、Ablyサービス上でメッセージの送受信を開始できるようにします。
Ablyに接続するサーバーレス関数を書く
をインストールする必要がある。 Ably npmパッケージ(をインストールする必要があります(Vercelとの互換性のため、このアプリではAbly 1.2.5以上を実行していることが必須です)。
ターミナルで、新しいアプリのルートで実行する:
次に ./pages/api/createTokenRequest.jsという名前のファイルを作成し、そこに以下のコードを追加する:
import Ably from "ably/promises";
export default async function handler(req, res) {
const client = new Ably.Realtime(process.env.ABLY_API_KEY);
const tokenRequestData = await client.auth.createTokenRequest({ clientId: 'ably-nextjs-demo' });
res.status(200).json(tokenRequestData);
};このサーバーレス関数は、Ably SDK を使用して、API キーで tokenRequestを作成します。このトークンは後で使用します。Next.jsアプリでこのトークンを使用する間、「本当の」APIキーを安全に保つことができます。
デフォルトでは、このAPIは http://localhost:3000/api/createTokenRequest.クライアントでこのURLをAbly SDKに提供して、Ablyと認証することになります。
VonageとVercelを使ってSMSを受信する
Vonageでは、APIダッシュボードで携帯電話番号を設定することができます。SMSを受信すると、APIが起動します。
そのためには Vercel Serverless functionを追加する必要があります。このサーバーレス関数は、SMSを受信するたびにVonageから呼び出されます(電話番号を設定したら!)。この関数にSMSメッセージを解凍するコードを記述し、それをReactアプリに送信するには Ably channel.
このプロセスは、エイブリーのセットアップとよく似ている。 createTokenRequest.
という名前のファイルを作成する。 ./pages/api/acceptWebhook.jsという名前のファイルを作成し、そこに以下のコードを追加する:
import Ably from "ably/promises";
export default async function handler(req, res) {
// Unpack the SMS details from the request query string
const incomingData = getSmsDetails(req, res);
// If the request was invalid, return status 400.
if (!incomingData.success) {
res.status(400).end();
return;
}
// Create an Ably client, get your `sms-notifications` channel
const client = new Ably.Realtime(process.env.ABLY_API_KEY);
const channel = client.channels.get("sms-notifications");
// Publish your SMS contents as an Ably message for the browser
await channel.publish({ name: "smsEvent", data: incomingData });
// Return the received data as a 200 OK for debugging.
res.send(incomingData);
res.status(200).end();
};
function getSmsDetails(req, res) {
const params = req.query;
if (!params.to || !params.msisdn) {
console.log('This is not a valid inbound SMS message!');
return { success: false };
}
return {
success: true,
messageId: params.messageId,
from: params.msisdn,
text: params.text,
type: params.type,
timestamp: params['message-timestamp']
};
}今はアプリに戻るが、アプリがデプロイされ Vercelにデプロイされ、関数が public url.
SmsComponentでSMSメッセージに反応する
のページは Next.jsはReactコンポーネントである。 pages/index.jsホームページはページレイアウトを含むReactコンポーネントである。
によって生成されるデフォルトのページです。 create-next-appアプリのロジックはこの中に含まれている。 SmsComponent.jsx.
まず、ファイルの先頭で必要なインポートを参照します:
import React, { useEffect, useState } from 'react';
import { useChannel } from "./AblyReactEffect";
import styles from './SmsComponent.module.css';次に、Reactコンポーネントとしてエクスポートされる関数を定義する。
const SmsComponent = () => {
let messageEnd = null;
const [receivedMessages, setMessages] = useState([]);
を使用してください。 react hook:
const [channel, ably] = useChannel("sms-notifications", (message) => {
const history = receivedMessages.slice(-199);
setMessages([...history, message]);
});
useChannelは リアクトフック形式の API です。チャンネル名と、メッセージを受信したときに呼び出されるコールバックを指定します。
次に、各メッセージを表示できるようにデータをフォーマットし、到着時刻と送信者の電話番号を表示する。
const messages = receivedMessages.map((message, index) => {
console.log(message);
let from = [message.data.from.slice(0, 2) + " " + message.data.from.slice(2, 6) + " " + message.data.from.slice(6, 9) + " "+ message.data.from.slice(9)];
let date = new Date(message.data.timestamp);
let day = date.toDateString().replace(/^\S+\s/,'');
let time = date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
return (
<div key={index} className={styles.message}>
<span className={styles.from}>{from}</span>
<span className={styles.when}>{day}, {time}</span>
<span className={styles.text}>{message.data.text}</span>
</div>
);
});
最後に、コンポーネントを作成し、それを返す:
return (
<div className={styles.chatHolder}>
<h1 className={styles.title}>Text Messages</h1>
<div className={styles.chatText}>
{messages}
<div ref={(element) => { messageEnd = element; }}></div>
</div>
</div>
)
}
ファイルの一番下に、関数を SmsComponentとしてエクスポートされ、Next.jsのインデックスページで参照できるようになっています。
ReactコンポーネントでAblyを正しく使う
React Functional ComponentsでAblyを使用する際に難しいのは、いつどこでSDKのインスタンスを作成し、いつどこでチャンネルに接続するかを知ることです。コンポーネントのレンダリング時に SDK をインスタンス化するのは避けたいところです。複数の接続が発生し、Ably アカウントの上限を使い果たしてしまう可能性があるからです。
アプリがコンポーネントの再描画、マウント、アンマウントを正しく処理するために AblyReactEffectは リアクトフックをエクスポートします。
Reactのフックは、初めて使うときには少し変わったものに見えるかもしれない。フックとは
期待される機能を実行する
componentDidMount実行するリターン 別のフレームワークによって実行される別の関数を返します。
componentDidUnmountが呼び出されるその他必要な動作を行う
このReactフックは useEffect.参照されると、Ably SDK のインスタンスが作成され (これは一度だけ行われます)、サーバーレス関数の URLにサーバーレス関数の createTokenRequestを認証に使用するように設定されます:
import Ably from "ably/promises";
import { useEffect } from 'react'
const ably = new Ably.Realtime.Promise({ authUrl: '/api/createTokenRequest' });コンポーネントのスコープ外でAblyライブラリをインスタンス化することは、それが一度だけ作成されることを意味し、制限の使用量を抑えることができます。
次に、コンポーネントで使用するために、エクスポートする関数(フック)を作成する必要があります。ここでは useChannelチャンネル名とコールバックを引数にとります。呼び出されるたびに useChannelがコールされるたびに getリクエストされたチャンネルをAbly-JS SDKから取得し、フック関数を準備します。
オンマウントは、コンポーネントがレンダリングされるたびに実行されるコードです。onMountの内部では、指定されたチャンネルを購読し、メッセージを受信するたびにトリガーします。
callbackOnMessageをトリガーします。onUnmountは、コンポーネントが再レンダリングされる前にアンマウントされるたびに実行されるコードです。ここでチャンネルからの登録を解除すると、偶発的な複数回の接続が停止され、アカウントの上限が節約されます。
useEffectHookは、これらの関数を正しく呼び出し、Reactが使用するonUnmountを返す関数である。
でエクスポートされたフックは次のようになります。 AblyReactEffect.jsは次のようになる:
export function useChannel(channelName, callbackOnMessage) {
const channel = ably.channels.get(channelName);
const onMount = () => {
channel.subscribe(msg => { callbackOnMessage(msg); });
}
const onUnmount = () => {
channel.unsubscribe();
}
const useEffectHook = () => {
onMount();
return () => { onUnmount(); };
};
useEffect(useEffectHook);
return [channel, ably];
}
を返します。 useChannelフックは、現在の Ably チャンネルと、呼び出し元のコードがメッセージ送信に使用する Ably SDK の両方を返します。このフックは、React 機能コンポーネントの Ably pub/sub を一箇所にカプセル化するので、他の場所で気にする必要はなく、これを使用するコードは受け取ったメッセージを処理できます。
モジュールCSSですべてを美しく見せるSmsComponent.module.css
チャット・コンポーネントを書くとき、あなたは気づいたかもしれません。 Next.jsにはコンパイラが強制する規約があり、CSSをどこに保存し、どのようにインポートするかが決められていることに気づいたかもしれません。
このアプリでは、CSSファイルを .jsx拡張子 .module.cssこれでコンポーネントの管理が簡単になります。将来的にこのコンポーネントを削除したい場合は、CSSも削除すれば簡単です。
一度作成すれば、それをコンポーネントにインポートすることができる:
import styles from './SmsComponent.module.css';JSX要素にCSSクラスを作成する場合は、要素上で以下の構文を使用します:
className={styles.yourClassName}それに付随するCSSは次のようになる:
.yourClassName {
styles: gohere;
} Vercelでのホスティング
開発サーバーとビルドパイプラインとして Vercelを開発サーバーとビルド・パイプラインとして使っている。
Next.jsをプロダクションにデプロイする最も簡単な方法は、Next.jsのクリエイターが提供するVercelプラットフォームを使うことです。Vercelは、静的デプロイとJamstackデプロイをサポートするグローバルCDNとサーバーレス機能を備えたオールインワンのプラットフォームです。-- Next.jsドキュメント
新しいSMSアプリをVercelにデプロイするには、以下の作業が必要です:
アカウント作成 GitHubアカウント(まだ持っていない場合)
新しいVercelアプリを作成し、GitHubリポジトリからアプリをインポートします。(VercelがあなたのGitHubアカウントを使用できるようにする必要があります。)
環境変数として
ABLY_API_KEYを環境変数として追加する。アプリのデプロイを見る
新しく作成したURLにブラウザでアクセスする!
アプリにSMS番号を設定する
SMSメッセージを受信するには、Vonageからバーチャル電話番号を借りて設定する必要がある。
まず、Vonageアカウントにログインします。 ダッシュボード.アカウントの作成と認証が完了したら、Numbers => Buy Numbersで番号を購入できます。自分に合った番号を検索し、クレジットを追加して番号を支払います。
番号を購入したら、次の設定を行う必要があります。 SMS Inbound Webhook URL.
そのためには、「Numbers」⇒「Your Numbers」⇒「ペンのアイコン」をクリックします。
モーダルダイアログボックスが表示されるので、そこに acceptWebhookAPI URLを入力する必要があります。
あなたのVercelアプリが your-vercel-appであれば、ウェブフックのURLは https://your-vercel-app.vercel.app/api/acceptWebhook.
自分のものにする!
このデモははオープンソースなので、フォークして自分のものにしてください。あなたが作ったものを私たちに見せるのをお忘れなく。 @ablyRealtime.
このプロジェクトをさらに発展させる方法をお探しなら、次のような方法が考えられる:
テレビ投票アプリの構築
メッセージを保存するデータベースの追加
応答テキストを送信する機能を追加。
お知らせ
このチュートリアルが役に立った場合、またはプロジェクトでNext.jsとAblyを使用している場合は、ぜひお聞かせください。ぜひ ツイッターまたは devrel@ably.io.
シェア:
Jo is a developer advocate at Ably. She is passionate about Realtime Data, PWAs and great CSS. She has 10 years of experience as a front end developer and has worked in various parts of the tech industry from startups, agencies, charities to large organisations. She is also an instructor/mentor at codebar.io and Front End Foxes where she is able to act on her goals of not only teaching good use of the web but also improving the diversity and inclusivity of the tech industry.
