首页 >web前端 >js教程 >如何使用Twilio构建SMS约会提醒应用程序

如何使用Twilio构建SMS约会提醒应用程序

Lisa Kudrow
Lisa Kudrow原创
2025-02-18 11:04:13965浏览

如何使用Twilio构建SMS约会提醒应用程序

本文由马克·沃勒(Marc Towler)和布鲁诺·莫塔(Bruno Mota)审查。感谢SitePoint所有的同行评审员制作SitePoint内容的最佳功能! 在本教程中,我们将使用node.js构建SMS提醒应用程序。我们将使用用户的Google日历获得约会,然后与Twilio一起发送短信。

>一如既往,您可以从GitHub repo中找到本教程中使用的代码。

钥匙要点

>使用Google和Twilio设置必要的帐户,并启用用于获取约会的Google Calendar API等API。 >
    >实现OAuth 2.0以供用户身份验证,以安全地访问Google日历数据。>
  • >使用MySQL数据库存储从Google Calendar获取的用户数据和约会详细信息。
  • >使用node.js中的cron安排任务,以自动从Google日历中获取事件并通过Twilio发送SMS提醒。处理错误,并确保在开发和部署应用程序期间对问题进行故障排除。
  • >设置内容
  • 首先,您需要拥有一个Google帐户和一个Twilio帐户。如果您还没有这些,则可以继续注册。这是链接:
  • Google
twilio

>您不必担心Twilio,可以免费尝试。

    Google Console Project
  • >拥有Google帐户后,请转到Google控制台并创建一个新应用。默认情况下,Google Console页面向您显示了您使用的最新应用程序的仪表板。但是,如果您尚未从事任何项目,它将显示以下内容:
  • >
>您可以单击右上角的“选择项目”菜单,然后选择“创建项目”。这打开了一个模态窗口,该窗口允许您输入项目的标题。

>

创建项目后,将显示仪表板。从那里,您可以单击使用Google API,搜索Google Calendar API并启用它。>

>启用API后,它将要求您创建凭据。单击转到凭据开始设置。这将向您显示以下内容:

如何使用Twilio构建SMS约会提醒应用程序

单击“添加凭据”按钮,然后选择OAuth 2.0客户端ID。

>这将要求您首先配置同意屏幕。单击配置同意屏幕。如何使用Twilio构建SMS约会提醒应用程序

>输入向用户显示的产品名称的值,然后单击“保存”。如何使用Twilio构建SMS约会提醒应用程序

>配置后,您现在可以创建客户端ID。选择应用程序类型的Web应用程序,留下默认名称(如果需要),输入http:// localhost:3000/登录授权重定向的URIS,然后单击创建。

如何使用Twilio构建SMS约会提醒应用程序>这打开了一个模式,该模态显示客户端ID和客户端秘密。暂时注意这些注意事项,因为我们稍后将使用它们。

>

twilio

>创建了一个Twilio帐户后,请转到“设置”页面,并记下“ councipen”和“ accountId and authtoken”的值。

接下来转到可编程​​的语音仪表板。这是您可以看到沙箱号码的地方。您可以使用此数字来测试Twilio。但是稍后,您需要购买电话号码,以便Twilio发送的短信不会

“从Twilio Sandbox发送”

添加了。 Twilio沙箱号码的另一个限制是它只能与经过验证的数字一起使用。这意味着您必须在Twilio上注册一个电话号码才能向其发送消息。您可以从“管理呼叫者ID”页面上执行此操作。 构建应用程序

>现在我们准备构建该应用程序了。在继续之前,我想简要概述我们将如何实现该应用程序。将会有三个主要文件:一个用于服务器,一个用于Google日历的缓存事件,一个用于提醒用户。该服务器用于允许用户登录并获得访问令牌。这些事件将保存在MySQL数据库中,并且将在.json文件中添加全局应用程序配置。 Node的CRON实现将用于执行缓存事件的任务并提醒用户。

安装依赖项

在您的工作目录上,创建一个软件包。

在此文件中,我们正在指定应用程序依赖的库的名称和版本。这是每个库的使用情况:>
  • config - 用于存储和检索全局应用程序配置。
  • > cron - 用于在一天中的特定时间执行特定任务。在此应用程序中,我们正在使用它来运行该任务,以从用户Google日历并发送文本提醒。
  • express - node.js的Defatto Web框架。我们正在使用它来提供登录页面。
  • 时刻 - 日期和时间库。我们正在使用它来轻松地格式化我们从Google Calendar API获得的日期。
  • MOMMTEMZONE - 时区插件暂时。这设置了应用程序的默认时区。
  • > mysql - node.js的mySQL客户端
  • twilio - Node.js的官方Twilio客户端这使我们能够发送文本提醒。
  • >执行NPM从您的终端安装以安装所有依赖项。>
>数据库

如前所述,我们将为此应用使用MySQL数据库。继续使用您选择的数据库管理工具创建一个新数据库。然后使用以下SQL转储文件来创建表:timment-notifier.sql。

数据库中有两个表:用户和约会。用户表用于存储用户数据。在此应用程序的情况下,我们只能存储一个用户,只存储访问令牌。

约会表用于存储我们从Google日历API中获得的事件。请注意,它没有一个用户,因为我们只有一个用户。我们将获取所有作为零作为通知字段的值的行。

>应用程序配置

>在您的工作目录上,创建一个配置文件夹,然后在内部创建一个default.json文件。这是我们将全局应用程序配置放置的地方。这包括时区,我们将要发送提醒的电话号码,数据库,Google App和Twilio设置。
>

这是模板,请务必填写所有字段。

>

公共文件

作为好的开发人员,我们需要尽可能避免代码重复。这就是为什么我们需要放置我前面提到的这三个主要文件(服务器,缓存,通知)所需的代码。在工作目录上创建一个通用文件夹。这是我们要添加通用文件的地方。

>
{
  "name": "google-calendar-twilio",
  "version": "0.0.1",
  "dependencies": {
    "config": "^1.17.1",
    "cron": "^1.1.0",
    "express": "^4.13.3",
    "googleapis": "^2.1.6",
    "moment": "^2.10.6",
    "moment-timezone": "^0.4.1",
    "mysql": "felixge/node-mysql",
    "twilio": "^2.6.0"
  }
}
>数据库

>在公共目录内创建一个db.js文件,然后添加以下内容:>

>这使用配置库来获取我们在config/default.json文件上之前添加的配置值。具体来说,我们正在获取数据库配置,以便我们可以连接到数据库。然后,我们将导出此模块,以便以后可以从另一个文件中使用它。>

时间

time.js文件用于设置使用Misms timeZone库的默认时区。我们还导出了时区的值,因为在运行两个CRON任务(缓存事件并通知用户)时,我们将稍后使用它。

>。
{
  "name": "google-calendar-twilio",
  "version": "0.0.1",
  "dependencies": {
    "config": "^1.17.1",
    "cron": "^1.1.0",
    "express": "^4.13.3",
    "googleapis": "^2.1.6",
    "moment": "^2.10.6",
    "moment-timezone": "^0.4.1",
    "mysql": "felixge/node-mysql",
    "twilio": "^2.6.0"
  }
}

Google

> Google.js文件用于初始化Google客户端和OAuth2客户端。为了初始化OAuth2客户端,我们需要传递客户端ID,客户端秘密和重定向URL,我们在配置文件中已添加了该客户端。然后,我们初始化Google日历服务。最后,我们导出OAuth2客户端,日历和Google配置。

>

{
    "app": {
        "timezone": "Asia/Manila"
    },

    "me": {
        "phone_number": ""
    },

    "db": {
        "host": "localhost",
        "user": "root",
        "password": "secret",
        "database": "calendar_notifier"
    },

    "google":{
        "client_id": "THE CLIENT ID OF YOUR GOOGLE APP",
        "client_secret": "THE CLIENT SECRET OF YOUR GOOGLE APP",
        "redirect_uri": "http://localhost:3000/login",
        "access_type": "offline",
        "scopes": [
            "https://www.googleapis.com/auth/plus.me",
            "https://www.googleapis.com/auth/calendar"
        ]
    },

    "twilio": {
        "sid": "YOUR TWILIO SID",
        "secret": "YOUR TWILIO SECRET",
        "phone_number": "+YOUR TWILIO PHONE NUMBER / SANDBOX NUMBER"
    }

}
创建服务器

>现在我们准备在服务器上工作了。服务器负责获取访问令牌。可以用于与Google日历API通信,而无需当前登录用户。首先创建一个server.js文件并添加以下内容:>

var config = require('config');

var db_config = config.get('db');
var mysql = require('mysql');
var connection = mysql.createConnection({
    host: db_config.host,
    user: db_config.user,
    password: db_config.password,
    database: db_config.database
});

exports.db = connection;
分解它:

首先,我们导入了我们之前创建的Google和DB模块。>

>创建在Localhost端口3000上运行的Express服务器。这就是为什么我们在应用程序配置和Google的重定向URI上添加了http:// localhost:3000/登录:
var config = require('config');
var app_timezone = config.get('app.timezone');
var moment = require('moment-timezone');
moment.tz.setDefault(app_timezone);

exports.config = {
    timezone: app_timezone
};

exports.moment = moment;
>

定义一个UpdateAccessToken功能。这接受了两个论点:令牌和响应。代币是用户获得必要权限后从Google获得的访问令牌。响应是来自Express的响应对象。我们将其传递给此功能,以便我们可以向用户发送响应。在功能内部,我们更新第一行的访问。如前所述,此应用仅适用于单个用户。 Access_Token更新后,我们发送响应。
var config = require('config');
var google_config = config.get('google');

var google = require('googleapis');
var OAuth2 = google.auth.OAuth2;
var oauth2Client = new OAuth2(google_config.client_id, google_config.client_secret, google_config.redirect_uri);

var calendar = google.calendar('v3');

exports.oauth2Client = oauth2Client; 
exports.calendar = calendar;
exports.config = google_config;
>

>添加主页的路由。 http:// localhost:访问3000时执行此操作。从这里我们生成身份验证URL。这使用了OAuth2Client的GenerateAuthurl方法。它接受包含access_type和范围的对象。我们从之前创建的应用程序配置文件中获取这些值。最后,我们发送用户可以单击的实际链接。请注意,您应该始终在视图中执行此操作,但是为了简化内容,我们将直接返回链接。
var google = require('./common/google');
var connection = require('./common/db');

var express = require('express');
var app = express();

var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
});


function updateAccessToken(tokens, response){

    connection.db.query(
        "UPDATE users SET access_token = ? WHERE id = 1", 
        [JSON.stringify(tokens)],
        function(err, rows, fields){
            if(!err){
                console.log('updated!');
                response.send('connected!');
            }else{
                console.log('error updating table');
                console.log(err);
                response.send('error occured, please try again');
            }
        }
    );

}

app.get('/', function(req, res){
    var url = google.oauth2Client.generateAuthUrl({
      access_type: google.config.access_type,
      scope: google.config.scopes
    });

    res.send('<a href="' + url + '">login to google</a>');
});


app.get('/login', function(req, res){
    var code = req.query.code;
    console.log('login');

    google.oauth2Client.getToken(code, function(err, tokens){

      if(!err){
        console.log('tokens');
        console.log(tokens);

        updateAccessToken(tokens, res);

      }else{
        res.send('error getting token');
        console.log('error getting token');
      }
    });

});

>添加登录路由。这是用户在授予应用程序必要权限后重定向的路线。 Google通过称为代码的查询参数传递。我们正在通过请求中的查询对象获取它。然后,我们调用GetToken方法并将代码作为参数传递。这将为我们提供访问令牌。因此,我们调用UpdateAccessToken函数以将其保存到数据库中。
var google = require('./common/google');
var connection = require('./common/db');
>
{
  "name": "google-calendar-twilio",
  "version": "0.0.1",
  "dependencies": {
    "config": "^1.17.1",
    "cron": "^1.1.0",
    "express": "^4.13.3",
    "googleapis": "^2.1.6",
    "moment": "^2.10.6",
    "moment-timezone": "^0.4.1",
    "mysql": "felixge/node-mysql",
    "twilio": "^2.6.0"
  }
}

创建Cacher

> cacher负责将用户约会保存到数据库中。这使我们不必每次发送提醒时都必须查询Google日历API目录。创建一个cache.js文件,并添加以下内容:

>
{
    "app": {
        "timezone": "Asia/Manila"
    },

    "me": {
        "phone_number": ""
    },

    "db": {
        "host": "localhost",
        "user": "root",
        "password": "secret",
        "database": "calendar_notifier"
    },

    "google":{
        "client_id": "THE CLIENT ID OF YOUR GOOGLE APP",
        "client_secret": "THE CLIENT SECRET OF YOUR GOOGLE APP",
        "redirect_uri": "http://localhost:3000/login",
        "access_type": "offline",
        "scopes": [
            "https://www.googleapis.com/auth/plus.me",
            "https://www.googleapis.com/auth/calendar"
        ]
    },

    "twilio": {
        "sid": "YOUR TWILIO SID",
        "secret": "YOUR TWILIO SECRET",
        "phone_number": "+YOUR TWILIO PHONE NUMBER / SANDBOX NUMBER"
    }

}

分解它:

首先,我们导入我们需要的所有模块。

var config = require('config');

var db_config = config.get('db');
var mysql = require('mysql');
var connection = mysql.createConnection({
    host: db_config.host,
    user: db_config.user,
    password: db_config.password,
    database: db_config.database
});

exports.db = connection;
>附加功能负责将约会保存到约会表中。这接受了约会的Event_ID,摘要,开始和结束日期。 Event_ID基本上是Google日历中特定约会的ID。我们将其用作主要密钥的值,这意味着重复的人不会插入约会表中。这里缺少的是比较数据库中已经在数据库中的约会以及API返回的约会的手段。如果出于某种原因更改约会的时间表,则不会更新数据库,因为我们在这里所做的只是插入表中。我将把它留给您的待办事项清单。

var config = require('config');
var app_timezone = config.get('app.timezone');
var moment = require('moment-timezone');
moment.tz.setDefault(app_timezone);

exports.config = {
    timezone: app_timezone
};

exports.moment = moment;
getEvents功能负责通过API返回的所有约会进行循环。这使用了附加方法来保存循环的每次迭代的约会。

>

var config = require('config');
var google_config = config.get('google');

var google = require('googleapis');
var OAuth2 = google.auth.OAuth2;
var oauth2Client = new OAuth2(google_config.client_id, google_config.client_secret, google_config.redirect_uri);

var calendar = google.calendar('v3');

exports.oauth2Client = oauth2Client; 
exports.calendar = calendar;
exports.config = google_config;
>缓存方法是对Google日历API进行实际调用的方法。这是通过使用Google客户端的。在这里,我们在日历对象上调用列表方法。这接受两个参数:第一个是包含查询选项的对象,第二个是返回结果后要执行的函数。

var google = require('./common/google');
var connection = require('./common/db');

var express = require('express');
var app = express();

var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
});


function updateAccessToken(tokens, response){

    connection.db.query(
        "UPDATE users SET access_token = ? WHERE id = 1", 
        [JSON.stringify(tokens)],
        function(err, rows, fields){
            if(!err){
                console.log('updated!');
                response.send('connected!');
            }else{
                console.log('error updating table');
                console.log(err);
                response.send('error occured, please try again');
            }
        }
    );

}

app.get('/', function(req, res){
    var url = google.oauth2Client.generateAuthUrl({
      access_type: google.config.access_type,
      scope: google.config.scopes
    });

    res.send('<a href="' + url + '">login to google</a>');
});


app.get('/login', function(req, res){
    var code = req.query.code;
    console.log('login');

    google.oauth2Client.getToken(code, function(err, tokens){

      if(!err){
        console.log('tokens');
        console.log(tokens);

        updateAccessToken(tokens, res);

      }else{
        res.send('error getting token');
        console.log('error getting token');
      }
    });

});
在包含选项的对象中,我们有以下内容:

>

  • auth - 这是OAuth2Client。这用于对请求进行身份验证。
  • >
  • 日历 - 我们将在其中获得约会的日历的ID。在这种情况下,我们使用的是主要日历。 Google日历实际上允许您创建许多日历。其他人也可以向您分享他们的日历。这些日历中的每个日历都有自己的ID。这就是我们在这里指定的。如果您有兴趣访问其他日历,请务必在日历上查看API文档。 > MaxResults - 您要返回的结果总数。
  • >单个事件 - 允许您指定是否仅返回单个一次性事件。在这里,我们使用了True,这意味着重复发生的事件不会返回。
  • >
  • 订单 - 允许您指定返回结果的顺序。在这种情况下,我们使用了启动时间,该开始时间根据其开始时间按顺序订购结果。仅当单个Events选项设置为true时才可用。
  • >
  • 所有这些选项以及许多其他选项都可以在事件中找到:列表文档
  • >
>从数据库中获取access_token,并将其用于为oauth2client客户端设置凭据。完成此操作后,创建一个新的CRON作业,该作业每天都会在午夜12点运行缓存方法。

创建Notifier

{
  "name": "google-calendar-twilio",
  "version": "0.0.1",
  "dependencies": {
    "config": "^1.17.1",
    "cron": "^1.1.0",
    "express": "^4.13.3",
    "googleapis": "^2.1.6",
    "moment": "^2.10.6",
    "moment-timezone": "^0.4.1",
    "mysql": "felixge/node-mysql",
    "twilio": "^2.6.0"
  }
}
>最后但并非最不重要的一点,我们有通知器(notify.js)。这负责从数据库中获得约会,并确定它们是否已经成熟通知。如果是的话,我们将它们发送。

分解它:

{
    "app": {
        "timezone": "Asia/Manila"
    },

    "me": {
        "phone_number": ""
    },

    "db": {
        "host": "localhost",
        "user": "root",
        "password": "secret",
        "database": "calendar_notifier"
    },

    "google":{
        "client_id": "THE CLIENT ID OF YOUR GOOGLE APP",
        "client_secret": "THE CLIENT SECRET OF YOUR GOOGLE APP",
        "redirect_uri": "http://localhost:3000/login",
        "access_type": "offline",
        "scopes": [
            "https://www.googleapis.com/auth/plus.me",
            "https://www.googleapis.com/auth/calendar"
        ]
    },

    "twilio": {
        "sid": "YOUR TWILIO SID",
        "secret": "YOUR TWILIO SECRET",
        "phone_number": "+YOUR TWILIO PHONE NUMBER / SANDBOX NUMBER"
    }

}
导入所有必需的模块。

>创建一个updateAppointment函数。这接受任命的ID作为其论点。它所做的只是将通知字段的值设置为1,这意味着已经发送了特定约会的通知。

var config = require('config');

var db_config = config.get('db');
var mysql = require('mysql');
var connection = mysql.createConnection({
    host: db_config.host,
    user: db_config.user,
    password: db_config.password,
    database: db_config.database
});

exports.db = connection;
接下来,我们将具有sendnotification函数。这是负责实际发送Twilio的文本提醒。从数据库中获取约会后,此功能被调用。这就是为什么它具有错误,结果和字段参数传递的原因。该错误包含数据库中的任何错误。结果包含从数据库返回的行。并且这些字段包含有关返回结果字段的信息。

在功能中,我们从应用程序配置中获取用户电话号码。
var config = require('config');
var app_timezone = config.get('app.timezone');
var moment = require('moment-timezone');
moment.tz.setDefault(app_timezone);

exports.config = {
    timezone: app_timezone
};

exports.moment = moment;
>
{
  "name": "google-calendar-twilio",
  "version": "0.0.1",
  "dependencies": {
    "config": "^1.17.1",
    "cron": "^1.1.0",
    "express": "^4.13.3",
    "googleapis": "^2.1.6",
    "moment": "^2.10.6",
    "moment-timezone": "^0.4.1",
    "mysql": "felixge/node-mysql",
    "twilio": "^2.6.0"
  }
}

检查是否有任何错误,是否没有任何错误继续循环浏览所有返回的结果。

>
{
    "app": {
        "timezone": "Asia/Manila"
    },

    "me": {
        "phone_number": ""
    },

    "db": {
        "host": "localhost",
        "user": "root",
        "password": "secret",
        "database": "calendar_notifier"
    },

    "google":{
        "client_id": "THE CLIENT ID OF YOUR GOOGLE APP",
        "client_secret": "THE CLIENT SECRET OF YOUR GOOGLE APP",
        "redirect_uri": "http://localhost:3000/login",
        "access_type": "offline",
        "scopes": [
            "https://www.googleapis.com/auth/plus.me",
            "https://www.googleapis.com/auth/calendar"
        ]
    },

    "twilio": {
        "sid": "YOUR TWILIO SID",
        "secret": "YOUR TWILIO SECRET",
        "phone_number": "+YOUR TWILIO PHONE NUMBER / SANDBOX NUMBER"
    }

}
在循环内部,我们提取所需的所有值并构造要发送的实际消息。我们还获得了当前时间和约会开始时间之间的小时差异。我们检查小时差小于还是等于24小时。

var config = require('config');

var db_config = config.get('db');
var mysql = require('mysql');
var connection = mysql.createConnection({
    host: db_config.host,
    user: db_config.user,
    password: db_config.password,
    database: db_config.database
});

exports.db = connection;
如果小于或等于24小时,我们会发送通知。这是通过使用Twilio客户端的。我们调用sendmessage并将其传递到包含TO(用户电话号码)的对象,从(Twilio的Sandobox号码或您从Twilio购买的电话号码)以及包含短信的主体。如果没有任何错误,我们假设已发送该通知。因此,我们调用UpdateAppointment函数将“通知”字段设置为1,因此在任务运行时不会选择它。

var config = require('config');
var app_timezone = config.get('app.timezone');
var moment = require('moment-timezone');
moment.tz.setDefault(app_timezone);

exports.config = {
    timezone: app_timezone
};

exports.moment = moment;
>最后,我们有了StartTask方法。它所做的就是从尚未发送通知的约会表中选择所有约会。此功能每12点和下午6点执行一次。

>

var config = require('config');
var google_config = config.get('google');

var google = require('googleapis');
var OAuth2 = google.auth.OAuth2;
var oauth2Client = new OAuth2(google_config.client_id, google_config.client_secret, google_config.redirect_uri);

var calendar = google.calendar('v3');

exports.oauth2Client = oauth2Client; 
exports.calendar = calendar;
exports.config = google_config;
结论

就是这样!在本教程中,您已经学会了如何使用Twilio创建SMS提醒应用程序。具体来说,我们研究了如何通过Google日历API获得用户的约会。我们已将这些保存在数据库中,并通过Twilio通知了用户。您可以从GITHUB存储库中找到本教程中使用的代码。

经常询问有关使用Twilio

构建SMS预约应用程序的问题(常见问题解答)

我如何测试我的SMS约会提醒应用程序的功能?

>测试您的SMS预约提醒应用程序的功能对于确保其按预期工作至关重要。您可以使用Twilio的内置测试工具来模拟发送和接收消息。您也可以将单元测试框架(例如Jest或Mocha)用于JavaScript代码。请记住测试所有功能,包括预约创建,提醒计划和发送SMS。 。消息内容通常在您的服务器端代码中定义。您可以对此进行修改以包括您想要的任何信息,例如约会时间,位置或与约会有关的任何其他详细信息。

>

>我如何安排不同时区的提醒?安排不同时区的提醒可能有些棘手。您需要为每个约会存储时区信息,并在安排提醒时使用此信息。 JavaScript的日期对象可以处理时区转换,或者您可以使用Moment.js之类的库来进行更复杂的方案。

如果SMS未能发送?

如果SMS未能发送?您还可以在代码中设置错误处理以记录这些失败并采取适当的操作,例如重新发送消息或通知用户。

>

我可以为多个用户使用此应用程序吗?是的,您可以将此应用用于多个用户。您需要修改代码以将约会与特定用户相关联,并确保将提醒发送到正确的电话号码。这可能涉及在数据库中添加用户身份验证和管理用户数据。

此应用程序中的数据的安全性? Twilio提供安全的通信渠道,但您还需要确保服务器和数据库安全。这可能涉及使用安全协议,加密敏感数据以及遵循Web安全性的最佳实践。

我可以将此应用程序与我现有的调度系统集成吗?您现有的调度系统。这将涉及修改代码与系统的API或数据库进行交互。确切的详细信息将取决于调度系统的细节。

>

发送带有Twilio的SMS提醒的费用是多少您发送的消息和发送给的国家。 Twilio在其网站上提供了详细的定价结构。

我可以向国际号码发送提醒吗?但是,您需要确保您遵守每个国家 /地区的SMS法规,并且成本可能高于国内消息。 🎜>您可以使用各种工具监视应用程序的性能。 Twilio为您的SMS使用情况提供分析,您可以使用服务器监视工具来跟踪服务器端代码的性能。您还应该实施日志记录以帮助诊断出现的任何问题。

>

以上是如何使用Twilio构建SMS约会提醒应用程序的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn