1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Twilio Functionsで作る:SMS放置→自動電話催促の動作イメージデモ

Posted at

はじめに

こんにちは。
今回は 「SMS通知の無視を検知して自動で電話催促を行う」 というユースケースをデモで表現するために作ったコードをご紹介します。

システムからメールを送ってもユーザーが反応してくれないので、SMSを送ってますが
それでも反応してもらえないという嘆きの声をよく聞きます。
そのような方のために、このデモでは、次のような流れをイメージしてTwilioの有用性を示しています。

  1. SMSで通知を送信
  2. 一定時間、相手が対応しなければ
  3. 自動で電話をかけ、内容を音声で再通知

放置 → 電話催促 という行動トリガーを視覚化し、
サーバーレス(Twilio Functions & Assets)で構築したシンプルな例です。
あくまでもデモ用なので、「通知の無視を検知して自動で」の部分は実装されていません。
実装方法は色々ありますが、TwilioのSMSとVoiceの機能を見て頂くためのデモプログラムになっています。
私がお客様に対してデモを行うときに使用するツールという立ち位置なので、自動化せず手動でSMS・Voiceの発信を行うような仕様に敢えてしています。

完成したコードはこちら:
GitHubリポジトリ:sms-to-call-demo

このデモコードの目指したポイント

  • 視覚的なわかりやすさ
  • Twilio APIの容易さ
  • ユースケースのイメージが持ちやすい
  • Twilioで完結できる(画面・バックエンド)

アーキテクチャの概要

動作の流れ

  1. 管理者(またはシステム)からユーザーにSMS通知を送信
  2. ユーザーにSMSが届く
    • ※ 今回のデモでは、ユーザーが対応したかどうかに関わらず「未対応」とみなして次に進みます
  3. 一定時間後、Twilio Functionsがトリガーされ自動で電話を発信
    • ※ 今回のデモでは、ボタンでコールボタンを押す形式にしています。
  4. Twilioの音声通話でメッセージを読み上げ、ユーザーに催促

ポイント

「SMS → 無視 → 自動通話」の流れをシンプルなロジックで再現し、
本番環境では「対応検知(例:返信SMSやリンククリック)」などを加えることでさらに高度化できます。


コードと構成

今回のデモは Twilio Functions & Assets だけで構築しています。
外部サーバーやデータベースは使用せず、サーバーレスで完結するシンプルな構成です。

Functionsの構成

Function名 役割
/send_sms ユーザーにSMSを送信
/make_call 自動で電話を発信し、TTSでメッセージを読み上げ

主なコードの抜粋と解説

1. SMS送信(/send_sms)

exports.handler = async function(context, event, callback) {
    const client = require('twilio')(context.ACCOUNT_SID, context.AUTH_TOKEN);
  
    const { to, smsBody } = event;
  
    try {
      const message = await client.messages.create({
        to: to,
        from: "TWILIODEMO",
        body: smsBody,
      });
      return callback(null, { sid: message.sid });
    } catch (error) {
      return callback(error);
    }
};  

ポイント

  • event.toevent.smsBody を受け取り、指定の宛先にSMSを送信。

2. 自動通話(/make_call)

exports.handler = async function(context, event, callback) {
    const client = require('twilio')(context.ACCOUNT_SID, context.AUTH_TOKEN);
    const { to, voiceMessage } = event;
    const twiml = `
      <Response>
        <Say language="ja-JP" voice="alice">
          ${voiceMessage}
        </Say>
      </Response>
    `;
    try {
      const call = await client.calls.create({
        to: to,
        from: context.CALLER_ID,
        twiml: twiml
      });
      return callback(null, { callSid: call.sid });
    } catch (error) {
      return callback(error);
    }
  };

ポイント

  • 指定の宛先に音声通話を発信。
  • **TTS(Text to Speech)**でvoiceMessageの内容を読み上げ。
  • TwiMLをコード内に直接埋め込んでいるため、別途TwiML BinやURLの用意が不要

環境変数(Environment Variables)

環境変数 説明
TWILIO_PHONE_NUMBER 発信元のTwilio電話番号

開発時の工夫とポイント

1. Functionsだけで完結

私は、Twilioのプリセールスエンジニアなので、最大限Twilioの機能だけで実装することが最適です。
通常、SMSや通話のトリガー処理はバックエンドサーバーやデータベースと連携するケースが多いですが、
今回は Twilio Functions & Assetsだけ で完結させました。

これにより:

  • 外部サーバーの準備や運用が不要
  • コストが最小限(Twilioの利用料のみ)
  • デプロイや修正が圧倒的にシンプル

2. TwiMLをコード内に直接記述

twiml: `<Response><Say language="ja-JP" voice="alice">${voiceMessage}</Say>`

TwiML Bin外部Webhook の準備が不要になり、構成がシンプルになりました。

3. 今後の拡張も容易

今回は「必ず電話催促に進む」という簡易ロジックですが、
次のような拡張も想定しています:

  • SMS内に「URLリンク」を含め、クリックを検知して通話をスキップ
  • 送信されたSMSに対して返信されなかったものに対してオートコールする
  • 音声合成(TTS)の音声や言語をカスタマイズ

最低限の構成でスタートし、必要に応じて機能を追加できるのがサーバーレス設計の強みです。


ユースケース例

今回の仕組みは、さまざまなシーンで活用できます。

  • ビジネスアラート通知:重要な業務アラートをSMS+自動電話で確実に伝達
  • 家族見守り通知:SMSでの注意喚起に反応がない場合に音声で再通知
  • 業務リマインダー:タスクや予定のリマインダーをSMSと音声の両方で送信
  • 督促通知:支払いリマインダーや契約更新の通知をフォローアップ

誰におすすめ?

このデモはこんな方におすすめ

  • 顧客対応やリマインダーの自動化を考えているエンジニア
  • TwilioのSMS・Voice機能をこれから学びたい方
  • サーバーレス開発を実践したい方

まとめ

今回は 「SMS通知→無視→自動通話」 という行動トリガーの自動化を、
Twilio Functions & Assetsだけ で実現する方法を紹介しました。

コード全文とデプロイ手順はGitHubにて公開しています:
GitHubリポジトリ:sms-to-call-demo

今後の発展として、ユーザー対応の検知や、応答に応じた柔軟なフロー設計など、さらに高度なユースケースに応用可能です。

ぜひ皆さんもTwilio APIを使った開発を楽しんでみてください!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?