>一如既往,您可以从GitHub repo中找到本教程中使用的代码。
钥匙要点
>您不必担心Twilio,可以免费尝试。
>
>启用API后,它将要求您创建凭据。单击转到凭据开始设置。这将向您显示以下内容:
单击“添加凭据”按钮,然后选择OAuth 2.0客户端ID。
>这将要求您首先配置同意屏幕。单击配置同意屏幕。>输入向用户显示的产品名称的值,然后单击“保存”。
>配置后,您现在可以创建客户端ID。选择应用程序类型的Web应用程序,留下默认名称(如果需要),输入http:// localhost:3000/登录授权重定向的URIS,然后单击创建。
>
twilio接下来转到可编程的语音仪表板。这是您可以看到沙箱号码的地方。您可以使用此数字来测试Twilio。但是稍后,您需要购买电话号码,以便Twilio发送的短信不会
“从Twilio Sandbox发送”添加了。 Twilio沙箱号码的另一个限制是它只能与经过验证的数字一起使用。这意味着您必须在Twilio上注册一个电话号码才能向其发送消息。您可以从“管理呼叫者ID”页面上执行此操作。 构建应用程序
安装依赖项
如前所述,我们将为此应用使用MySQL数据库。继续使用您选择的数据库管理工具创建一个新数据库。然后使用以下SQL转储文件来创建表:timment-notifier.sql。
>应用程序配置
>在您的工作目录上,创建一个配置文件夹,然后在内部创建一个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" } }>数据库
>这使用配置库来获取我们在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" } }
>
{ "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;分解它:
首先,我们导入了我们之前创建的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负责将用户约会保存到数据库中。这使我们不必每次发送提醒时都必须查询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'); } }); });在包含选项的对象中,我们有以下内容:
>
创建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预约应用程序的问题(常见问题解答)>我如何安排不同时区的提醒?安排不同时区的提醒可能有些棘手。您需要为每个约会存储时区信息,并在安排提醒时使用此信息。 JavaScript的日期对象可以处理时区转换,或者您可以使用Moment.js之类的库来进行更复杂的方案。
如果SMS未能发送?您还可以在代码中设置错误处理以记录这些失败并采取适当的操作,例如重新发送消息或通知用户。
>此应用程序中的数据的安全性? Twilio提供安全的通信渠道,但您还需要确保服务器和数据库安全。这可能涉及使用安全协议,加密敏感数据以及遵循Web安全性的最佳实践。
发送带有Twilio的SMS提醒的费用是多少您发送的消息和发送给的国家。 Twilio在其网站上提供了详细的定价结构。
以上是如何使用Twilio构建SMS约会提醒应用程序的详细内容。更多信息请关注PHP中文网其他相关文章!