Skip to content

Latest commit

 

History

History
412 lines (315 loc) · 18.1 KB

File metadata and controls

412 lines (315 loc) · 18.1 KB

四、创建“点击呼叫”呼叫中心

本章涵盖了 Flybase 和 Twilio 的一些有趣的领域。我们将建立一个“点击呼叫”呼叫中心,访问者可以点击页面上的产品,开始与另一个网页上的代理进行 Twilio 客户呼叫。为此,我们将使用 Flybase 的自定义事件。

本教程基于去年 Twilio 发表的一篇关于使用 Pusher、Twilio 和 Python 构建一个类似系统的文章( www.twilio.com/blog/2014/07/creating-a-click-to-call-service-with-twilio-client-pusher-and-python.html ),但我们的会简单一点,因为涉及的系统更少。

Flybase 的自定义事件

Flybase 为开发人员提供了许多好用的工具。在本教程中,我们将使用 Flybase 的自定义事件来构建一个自定义的“点击呼叫”呼叫中心。

什么是自定义事件?你知道预约事件( http://flybase.io/docs/web/guide/reading-data.html ),如valueaddedchangedonlineremoved,但我们也有定制事件。自定义事件可以方便地在设备、用户、不同集合甚至同一应用的不同部分之间传递消息或数据。

下面是自定义事件侦听器的一个基本示例:

javascript
flybase.on("custom_event", function(message) {
      console.log( message );
});

flybase.trigger("custom_event", "Hi")

当您想要在设备之间传递数据,但不一定需要将数据保存在任何地方时,应该使用自定义事件。在这种情况下,它更像一个信号服务器,让设备知道正在发生的事情。

什么是点击呼叫系统?

“点击呼叫”允许客户点击一个链接,开始与人进行浏览器内语音通话。在建立语音通话的同时,有关客户的上下文信息(例如他们正在查看的商品或他们的姓名/兴趣/脸书喜欢的东西)被传递给处理通话的人,然后该人可以提供高度个性化的体验。客户不需要告诉他们自己的名字或他们感兴趣的产品/服务:点击呼叫为你做了这一切。它摆脱了呼叫中心令人讨厌的部分,让你继续做对你来说重要的事情。

必要的工具

在本章中,我们将使用以下工具:

  • Twilio 让我们可以构建像短信应用甚至呼叫中心这样的服务。

  • Flybase 将用于管理谁是一个组的成员,并存储传入和传出的消息以及它们来自谁。

  • Node.js 将是我们应用的后端部分;这是我们为 Twilio 构建监听器的地方,无论我们何时发送或接收文本消息,我们都可以与之对话。

设置 Twilio 客户端

让我们从创建一个 TwiML 应用开始,这个应用可以重复用于 TwiML 配置,可以应用于 Twilio 电话号码或 TwiML 应用。每个 TwiML 应用都有一个唯一的 SID,我们用它来为 Twilio 客户端生成安全令牌。

转到你的账户的应用页面( www.twilio.com/user/account/apps ),点击“创建 TwiML 应用”创建一个新的应用

我们称我们的 TwiML 应用为“点击呼叫演示”您需要将语音请求 URL 链接到您网站上的 URL。我们将单击 Save,这将为 TwiML 应用生成一个 SID,我们稍后将使用它,所以请将它放在手边。

入门指南

我们首先需要设置我们的 Node.js app。

除了 Twilio 和 Flybase 模块,我们将使用 express 框架( http://expressjs.com/ )来设置我们的 Node web 服务器,以接收来自 Twilio 的 POST 请求,因此我们需要安装 Express 包。我们还将使用主体解析器模块,所以我们也将安装它。

让我们创建我们的 package.json 文件:

```javascript
{
      "name": "call-ads",
      "version": "0.0.1",
      "description": "Click-to-call call Center powered by Flybase, Twilio and Node.js",
      "main": "app.js",
      "repository": "https://github.com/flybaseio/call-ads",
      "scripts": {
            "test": "echo \"Error: no test specified\" && exit 1"
      },
      "keywords": [
            "twilio",
            "data mcfly",
            "flybase",
            "twilio",
            "sms"
      ],
      "author": "Roger Stringer",
      "license": "MIT",
      "dependencies": {
            "twilio": "~1.6.0",
          "ejs": "~0.8.5",
            "express": "~3.4.8",
            "flybase": "~1.5.2",
            "node-buzz": "~1.1.0",
            "moment": "~2.5.1",
            "less-middleware": "~0.2.1-beta",
            "body-parser" : "~1.4.2",
            "method-override" : "~2.0.2"
      },
      "engines": {
            "node": "0.12"
      }
}
```js

保存该文件,并从终端运行以下命令:

npm install

这将创建一个“node_modules”文件夹,其中包含我们想要使用的所有模块。

让我们设置我们的文件夹结构,并创建一个名为“views”的文件夹这是我们将保持前端的地方。现在,创建一个名为“public”的文件夹这将托管我们的静态文件。在该文件夹中,创建一个“图像”文件夹;我们将在本章的后面回到这个问题上来。我们要创建的第一个文件是 config.js 。这将保存我们的配置信息:

javascript
module.exports = {
      // Twilio API keys
      twilio: {
            sid: "ACCOUNT-SID",
            token: "AUTH-TOKEN",
            appid: 'YOUR-TWILIO-APP-ID'
      },
      //      Flybase settings
      flybase: {
            api_key: "YOUR-API-KEY",
            app_name: "YOUR-FLYBASE-APP"
      },
      //      Username and password for admin section.
      un: 'admin',
      pw: 'password'
};

该文件用于我们的配置。我们可以在任何时候通过引用文件和调用键来访问这里的任何东西。例如,为了获得我们的 Flybase API 密钥,我们将调用

var config = require('./config');
console.log( config.flybase.api_key );

ACCOUNTSIDAUTHTOKENYOUR-Twilio-APP-IDYOUR-NUMBER 替换为您将使用的 TWILIO 帐户中的 TWILIO 凭证和电话号码。

显示了 YOUR-TWILIO-APP-ID 的占位符的 appid 变量是存储您在上一步中创建的 SID 的地方。接下来,将 YOUR-API-KEYYOUR-FLYBASE-APP 替换为要使用的 Flybase API Key。

最后, unpw 变量是您存储用户名和密码的地方,当您通过“/cc”路径访问您的控制面板时会用到它们。

在我们的 app.js 文件的开头,我们需要 require express 并将其初始化为一个名为 app 的变量。我们还将使用 bodyParser 中间件( https://github.com/expressjs/body-parser )来方便地使用我们将在 POST 请求中获得的数据。

创建一个名为 app.js 的新文件,并需要 twilio、express 和 flybase 包:

var express = require('express');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var path = require('path');
var config = require('./config');

var app = express();
app.set('views', path.join(process.cwd(), 'views'));
app.set('view engine', 'ejs');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({      extended: true      }));
app.use(express.static(__dirname + '/public')); // set the static files location /public/img will be /img for users

var port = process.env.PORT || 5000; // set our port

var twilio = require('twilio');
var client = twilio(config.twilio.sid, config.twilio.token);

var flybase = require('flybase');
var leadsRef = flybase.init(config.flybase.app_name, "leads", config.flybase.api_key);

Flybase 使用集合来组织应用中的数据,因此一个应用可以有几个集合。如果您熟悉关系数据库,这相当于一个表。我们将为我们的项目使用一个名为 leads 的集合。

自定义事件同样链接到我们所连接的集合,所以如果我们建立了到leads的 Flybase 连接,那么我们将监听 leads 集合中的所有事件,无论是否保留。

这是我们应用的开始。接下来,我们将构建 web 界面来管理组成员,并允许发送和接收消息。之后,我们将构建我们的 Twilio 界面,您将有一个有趣的应用可以玩:

javascript

//      listen for incoming sms messages
app.post('/voice', function (req, res) {
      leadsRef.trigger("new-caller", {
            item: req.param('item'),
            name:req.param('name')
      });

      res.writeHead(200, {
            'Content-Type':'text/xml'
      });

      var resp = new twilio.TwimlResponse();
      resp.dial(function() {
            this.client('Admin');
      });

      res.type('text/xml');
      res.end( resp.toString() );
});

当我们收到对/voice路线的新POST请求时,我们将其存储在我们的 Flybase 应用中的 new-caller 事件中,然后将该调用连接到我们的 admin 用户,在本例中我们称之为“Admin”。

最后,我们设置我们的前端路由,/cc/,然后告诉我们的服务器监听端口5000,并告诉它当我们从浏览器查看它时该做什么:

javascript
var auth = express.basicAuth(config.un, config.pw);

// route to handle all frontend requests, with a password to protect unauthorized access....
app.get('/cc', auth, function(req, res) {
      var capability = new twilio.Capability( config.twilio.sid, config.twilio.token );
      capability.allowClientIncoming( 'Admin' );
      capability.allowClientOutgoing( config.twilio.appid );
    var token = capability.generate();

      res.render('cc', {
            token:token,
            api_key:config.flybase.api_key,
            app_name:config.flybase.app_name
      });
});

app.get('/', function(req, res) {
      var client_name = "anonymous";
      if( typeof req.param("client") !== "undefined" ){
            client_name = req.param("client");
      }

      var capability = new twilio.Capability( config.twilio.sid, config.twilio.token );
      capability.allowClientIncoming( client_name );
      capability.allowClientOutgoing( config.twilio.appid );
    var token = capability.generate();

      res.render('index', {
            call_token: token,
            client_name: client_name
      });
});

var server = app.listen(port, function() {
      console.log('Listening on port %d', server.address().port);
});

/cc/路由都调用 Twilio 为 Twilio 客户端创建功能令牌。这些让网页发出和接收呼叫。

我们做了一件事,在主页上显示跟踪。如果您访问附加了一个?client=myname变量的页面,那么客户端的名称就会改变。这是为了演示传递上下文信息。

设置模板

我们现在需要构建我们的模板文件。会有两个: index.ejscc.ejs 。我们会将它们存储在views文件夹中。

首先,我们来设置一下 index.ejs :

HTML
<!DOCTYPE html>
<html>
<head>
      <title>Fly Shop</title>
      <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css">
      <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css" rel="stylesheet">

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
      <script type="text/javascript" src="//static.twilio.com/libs/twiliojs/1.2/twilio.min.js"></script>
      <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.0/js/bootstrap.min.js"></script>
</head>
<body>
      <div class="container">
            <div class="row">
                  <div class="col-md-6">
                        <h1>Fly Shop</h1>
                  </div>
            </div>
            <div class="well">
                  <h4 class="text-center">Click an ad to purchase now!</h4>
            </div>
            <div class="row">
                  <div class="col-md-4">
                        <a onclick="call('Apple LCD TV');">
                        <div class="panel panel-default">
                              <div class="panel-heading"><h4>55" Apple LCD TV</h4></div>
                              <div class="panel-body text-center">
                                    <img srcimg/apple1.png">
                              </div>
                        </div></a>
                  </div>
                  <div class="col-md-4">
                        <a onclick="call('Apple iPad');">
                        <div class="panel panel-default">
                              <div class="panel-heading"><h4>Apple iPad</h4></div>
                              <div class="panel-body text-center">
                                    <img srcimg/apple2.png">
                              </div>
                        </div></a>
                  </div>
                  <div class="col-md-4">
                        <a onclick="call('MacBook Pro');">
                        <div class="panel panel-default">
                              <div class="panel-heading"><h4>MacBook Pro</h4></div>
                              <div class="panel-body text-center">
                                    <img srcimg/apple6.png">
                              </div>
                        </div></a>
                  </div>
            </div>
            <div class="well" style="display:none;" id="hangupbox">
                  <a onClick="hangup();" class="btn btn-primary" id="hangup">Hang up</a>
            </div>
      </div>
      <script type="text/javascript">
            var myname = '';
            Twilio.Device.setup("<%=call_token%>");
            function call(item_of_choice) {
                  params = {"item": item_of_choice, "name": "<%= client_name %>"};
                  Twilio.Device.connect(params);
                  $("#hangupbox").show();
            }
            function hangup() {
                  Twilio.Device.disconnectAll();
                  $("#hangupbox").hide();
            }
      </script>
</body>
</html>

这将显示样品产品,让游客点击一个。当他们这样做时,它将开始呼叫代理。

这些图片在“公共/图片”文件夹中,只是一些随机的产品图片。你可以把它们换成任何你想要的真实图像。这只是让你知道它是如何工作的。

这个页面的实际工作在 JavaScript 中,它接受模块 call_tokenclient_name 以及用户感兴趣谈论的选定项目,并开始浏览器电话呼叫。

现在,让我们设置 cc.ejs ,这是代理控制面板:

<!DOCTYPE html>
<html>
<head>
      <title>Control Center</title>
      <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css">
      <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css" rel="stylesheet">

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
      <script type="text/javascript" src="//static.twilio.com/libs/twiliojs/1.2/twilio.min.js"></script>
</head>
<body>
      <div class="container">
            <div class="well">
                  <h1>Incoming calls</h1>
            </div>
            <br />
            <div class="well">
                  <div class="list-group">
                        <div class="list-group-item">
                              <h4 class="list-group-item-heading warning"></h4>
                        </div>
                  </div>
            </div>
      </div>
      <script src="https://cdn.flybase.io/flybase.js?20150817"></script>
      <script>
            $(function(){
                  var leadsRef = new Flybase( "<%= api_key %>", "<%= app_name %>", "leads");
                  leadsRef.on("new-caller", function( call ) {
                        $('.warning').val( call.name + ' wants a ' + call.item );
                  });

                  Twilio.Device.setup("<%= token %>");
                  Twilio.Device.incoming(function (conn) {
                        // accept the incoming connection and start two-way audio
                        conn.accept();
                  });

                  function hangup() {
                        Twilio.Device.disconnectAll();
                  }
            });
      </script>
</body>
</html>

这看起来有点像“索引”文件。不同之处在于,当访问者点击开始呼叫时,代理可以查看。屏幕上会出现一个提示,电话会被接听。

在我们的 app.js 文件中,我们还设置了一个基本密码,这样只有代理可以访问它。

最后一件事,让我们启动我们的应用:

node app.js

我们已经告诉我们的应用在端口5000上运行,所以如果你去你的网络浏览器并输入http://localhost:5000/,你应该看到你的呼叫中心广告页面,如果你去http://localhost:5000/cc,你应该看到你实际的呼叫中心,等待网站访问者的呼叫。点击主页上的广告将触发呼叫中心的呼叫。

如果你在本地运行这个,你会希望在进入下一步之前确保你已经运行了 ngrok 。如果你以前没有使用过 ngrok ( https://ngrok.com/ ),Twilio 的凯文·维尼里整理了一个很棒的教程( www.twilio.com/blog/2013/10/test-your-webhooks-locally-with-ngrok.html )来帮助你入门。

摘要

我们已经使用 Flybase ( http://flybase.io )和 Twilio ( http://twilio.com )构建了一个实时点击呼叫呼叫中心应用。这是一个非常基本的实现,旨在向您展示使用 Twilio 客户端和 Flybase 的实时“点击呼叫”服务的可能性。您可以使用这个项目和开放源代码( https://github.com/flybaseio/call-ads )来扩展教程并开始构建您自己的应用。

这里有一些想法,让你的大脑思考如何通过“点击呼叫”来使用这样的实时信息:

  • -拨打电话时调出来电者信息,以加快通话速度。

  • -从呼叫者处收集位置数据,自动确定他们的地理位置。

  • -允许多个代理。甚至可以考虑使用 Flybase 来存储来电队列,并将客户连接到第一个可用的代理。