Skip to content

Latest commit

 

History

History
697 lines (541 loc) · 30.6 KB

File metadata and controls

697 lines (541 loc) · 30.6 KB

三、构建实时群聊应用

去年 11 月,我和几个同事参加了一个会议,我们希望让每个人都了解最新情况,并有组织地跟踪我们的计划。

我们建立了一个群聊系统,让其中一个成员发送短信,其他人都能收到,如果有人回复,我们都能看到回复。

这很方便,今天,我将向您展示如何构建一个类似的 web 应用。该应用将由一个简单的控制面板和一个后端组成,在控制面板上,你可以管理谁是一个组的一部分,后端将处理传入和传出的文本消息,并将它们路由到适当的组成员。

你还可以从网站上的一个页面实时发送和接收消息,当你可能没有带手机,但想给小组发消息时,反之亦然。

佐料

在继续之前,您需要设置好这些。

我们将使用 Flybase ( http://flybase.io/ )来处理 app 的数据存储和实时方面,Twilio ( www.twilio.com/ )来处理实际的短信工作,Node.js 用于系统本身。

我们将为一个单独的组构建这个特定的应用,但是将它扩展到多个组并不困难。

最后,我们将把这个应用作为一个免费的应用托管在 Heroku 上( https://heroku.com/ ,一个方便的托管平台,可以让你的项目快速启动和运行,尤其是在与 Flybase 和 Twilio 结合使用时)。

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

Flybase 是一个实时应用平台,将成为我们应用的首选数据存储。它将用于管理谁是一个组的成员,并存储传入和传出的消息以及它们来自谁。如果你还没有,现在就注册( https://app.flybase.io/signup )一个免费的 Flybase 帐户,然后在你的仪表盘内创建一个新的应用。你将在你的群聊系统中使用此应用。

Twilio 是我们一直以来都很方便的电话 API,它让我们可以构建像群聊应用甚至呼叫中心这样的服务。还没有 Twilio 帐户吗?免费报名( www.twilio.com/try-twilio )。

入门指南

我们首先需要设置 Node.js 应用。

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

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

javascript
{
  "name": "group-chat",
  "version": "0.0.1",
  "description": "SMS Group Chat powered by Flybase, Twilio and Node.js",
  "main": "app.js",
  "repository": "https://github.com/flybaseio/group-chat",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "twilio",
    "flybase",
    "sms"
  ],
  "author": "Roger Stringer",
  "license": "MIT",
  "dependencies": {
    "body-parser": "~1.16.0",
    "ejs": "~2.5.5",
    "express": "~4.14.0",
    "flybase": "^1.8.2",
    "less-middleware": "~2.2.0",
    "method-override": "~2.3.7",
    "moment": "~2.17.1",
    "node-buzz": "~1.1.0",
    "twilio": "~2.11.1"
  }
}

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

javascript
npm install

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

让我们设置我们的文件夹结构,并创建一个名为views的文件夹。这是我们将保持前端的地方。

现在,创建一个名为public的文件夹。这将托管我们的静态文件。在这个文件夹中,创建一个css文件夹和一个js文件夹。我们稍后将回到这些。

我们要创建的第一个文件是config.js;这将保存我们的配置信息:

javascript
module.exports = {
    // Twilio API keys
    twilio: {
        sid: "ACCOUNTSID",
        token: "AUTHTOKEN",
        from_number: "YOUR-NUMBER"
    },
    flybase: {
            api_key: "YOUR-API-KEY",
            app_name: "YOUR-FLYBASE-APP"
    },
    un: 'admin',
    pw: 'password'
};

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

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

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

然后,用您的 Flybase API 密钥替换YOUR-API-KEYYOUR-FLYBASE-APP

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

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

javascript
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 || 8080; // set our port

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

var flybase = require('flybase');
var messagesRef = flybase.init(config.flybase.app_name, "messages", config.flybase.api_key);
var groupRef = flybase.init(config.flybase.app_name, "groups", config.flybase.api_key);

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

我们将为我们的项目使用两个集合:一个包含messages,另一个包含groups。考虑到这一点,我们为我们的 Flybase 应用创建了两个不同的引用,一个用于消息,一个用于我们的组。这是我们应用的开始。接下来,我们将构建 web 界面来管理组成员,并允许发送和接收消息。

之后,我们将构建我们的 Twilio 界面,您将拥有一个有趣的应用来玩。

发送和接收文本

我们需要添加一些东西来发送和接收文本。我们的第一步是为 Twilio 添加一个监听器。

Twilio 使用 webhooks ( https://en.wikipedia.org/wiki/Webhook )来让您的服务器知道何时有消息或电话进入我们的应用。我们需要设置一个端点,我们可以告诉 Twilio 将它用于消息传递 webhook。

我们将为/message添加一条路由,它用一些 TwiML ( www.twilio.com/docs/api/twiml )进行响应。TwiML 是一组基本指令,当你收到来电或短信时,你可以用它来告诉 Twilio 该做什么。我们的代码将如下所示:

javascript
// listen for incoming sms messages
app.post('/message', function (request, response) {

      groupRef.where( {"memberNumber":request.param('From')} ).limit(1).on( "value", function ( data ){
            if( data.count() ){
                  data.forEach( function( snapshot ){
                        var member = snapshot.value();
                        messagesRef.push({
                              sid: request.param('MessageSid'),
                              type:'text',
                              tstamp: new Date().toLocaleString(),
                              fromName:member.memberName,
                              fromNumber:request.param('From'),
                              message:request.param('Body'),
                              media:"",
                              fromCity:request.param('FromCity'),
                              fromState:request.param('FromState'),
                              fromCountry:request.param('FromCountry'),
                              groupNumber:request.param('To')
                        });
                  });
            }
      });

      var numMedia = parseInt( request.param('NumMedia') );
      if (numMedia > 0) {
            for (i = 0; i < numMedia; i++) {
                  var mediaUrl = request.param('MediaUrl' + i);
                  groupRef.where( {"memberNumber":request.param('From')} ).limit(1).on( "value", function ( data ){
                        if( data.count() ){
                              data.forEach( function( snapshot ){
                                    var member = snapshot.value();
                                    messagesRef.push({
                                          sid: request.param('MessageSid'),
                                          type:'text',
                                          tstamp: new Date().toLocaleString(),
                                          fromName:member.memberName,
                                          fromNumber:request.param('From'),
                                          message:"",
                                          media:mediaUrl,
                                          fromCity:request.param('FromCity'),
                                          fromState:request.param('FromState'),
                                          fromCountry:request.param('FromCountry'),
                                          groupNumber:request.param('To')
                                    });
                              });
                        }
                  });
            }
      }
      var resp = new twilio.TwimlResponse();
      resp.message('Message received.');
      response.writeHead(200, {
            'Content-Type':'text/xml'
      });
      response.end(resp.toString());
});

这将监听任何传入的短信,并将它们存储在你的 Flybase 应用中,特别是在messages集合中。

作为存储消息的一部分,我们执行一个查找来找到与发送消息的电话号码相同的groups成员。然后,我们使用这个查找来验证该成员是否是组的一部分,并获取该成员的名称。

如果找不到成员,则不会发送任何消息。

一旦收到消息,我们使用 Twilio Node 库初始化一个新的 TwimlResponse 。然后我们使用消息关键字( www.twilio.com/docs/api/twiml/sms/message )来设置我们想要用什么来响应消息。在这种情况下,我们只说“消息已收到。”

然后,我们将响应的内容类型设置为text/xml,并发送我们构建的 TwimlResponse 的字符串表示。

倾听变化

作为我们的app.js代码的一部分,我们还想添加一些异步监听器来监听我们的 Flybase 应用的变化:

javascript
// when a new message is added to the Flybase app, send it via Twilio...
messagesRef.on("added", function (data ){
      var snapshot = data.value();
      sendMessage(
            snapshot.groupNumber,
            snapshot.fromName,
            snapshot.fromNumber,
            snapshot.message,
            snapshot.media || ""
      );
});

groupRef.on("added", function ( data ){
      var snapshot = data.value();
      var msg = snapshot.memberName + ' has joined the group';
      messagesRef.push({
            sid: "",
            type:'',
            tstamp: new Date().toLocaleString(),
            fromName:"Admin",
            fromNumber:"",
            message:msg,
            media:"",
            fromCity:"",
            fromState:"",
            fromCountry:"",
            groupNumber:snapshot.groupNumber
      });
});

groupRef.on("removed", function ( data ){
      var snapshot = data.value();
      var msg = snapshot.memberName + ' has left the group';
      //      send broadcast that a group member has been removed
      messagesRef.push({
            sid: "",
            type:'',
            tstamp: new Date().toLocaleString(),
            fromName:"Admin",
            fromNumber:"",
            message:msg,
            media:"",
            fromCity:"",
            fromState:"",
            fromCountry:"",
            groupNumber:snapshot.groupNumber
      });

});

//      broadcast a message to the group
function sendMessage( group_number, from_name, from_number, message, media ){
      var msg = from_name + ": " + message;
      groupRef.where( {"memberNumber":{"$not":from_number}} ).on( "value", function ( data ){
            if( data.count() ){
                  data.forEach( function( snapshot ){
                        var member = snapshot.value();
                        var msgObj = {
                              to:member.memberNumber,
                              from:group_number,
                              body:msg
                        };
                        if( media !== "" ){
                              msgObj.mediaUrl = media;
                        }
                        client.sendMessage( msgObj, function( err, data ) {});
                  });
            }
      });
}

我们设置了三个异步侦听器,一个用于 messages 集合,它侦听任何被“添加”到其中的消息,当它收到新消息的通知时,调用我们的 sendMessage 函数将消息发送给组中的其他成员。

另外两个异步监听器用于我们的集合:第一个监听器监听任何加入到组中的新成员,然后发送成员已经加入组的通知。

最后一个监听器将监听从组中“移除”的任何成员,并发送成员已经离开组的通知。

最后,我们的 sendMessage 函数用于向其他组成员发送消息;它将执行查询以返回该组的所有成员,不包括发送消息的人,并将消息发送给每个成员。

消息将以成员姓名后跟消息的格式显示:

John: How about pizza after work?

最后,让我们设置我们的服务器监听端口8080,并告诉它当我们从浏览器中查看它时该做什么:

javascript
// frontend routes =========================

// Create basic  middleware used to authenticate all admin requests
var auth = express.basicAuth(config.un, config.pw);

// route to handle all frontend requests with a password to protect unauthorized access....
app.get('*', auth, function(req, res) {
      res.render('index', {
            api_key:config.flybase.api_key,
            app_name:config.flybase.app_name,
            group_number:config.twilio.from_number
      });
});

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

这是我们群聊应用的后端部分。它会监听收到的短信,将其存储在我们的 Flybase 应用中,然后发送给小组的其他成员。

现在,我们需要建立我们的控制面板,管理员可以管理组成员,也可以发送和接收消息。

管理您的群组

我们将构建一个简单的 web 界面来管理我们的组成员。

我们为小组成员存储的数据将由以下三部分数据组成:

  • -群组电话号码(我们存储在"Getting Started"部分的 twilio_number 变量中的 Twilio 号码)

  • -成员姓名

  • -会员电话号码

我们还将显示一个基本的聊天框,让我们的管理员发送消息,并查看正在发送的消息。

首先,让我们创建视图。在/views文件夹中,创建名为index.ejs的文件:

`

HTML
<!doctype html>
<html>
<head>
      <link href='//fonts.googleapis.com/css?family=Lato:400,300italic,400italic&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
      <link rel="stylesheet" type="text/css" href="//angular-ui.github.com/ng-grid/css/ng-grid.css" />
      <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
      <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
      <link rel="stylesheet" type="text/css" href="/css/style.css">

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
      <script src="https://cdn.flybase.io/flybase.js?20150217"></script>
      <script src="https://cdn.flybase.io/libs/phone.js"></script>
      <script src="/js/group.js"></script>

      <title>Group Chat, powered by Flybase and Twilio</title>
</head>
<body>
      <div class='container'>
            <div class="row">
                  <div class="col-md-6">
                        <h3>Group Members</h3>
                        <div id="group_wrapper"></div>
                        <hr />
                        <h2>Add new member</h2>
                        <div class="well">
                              <form id="group_form" method="post" accept-charset="utf-8" class="form-inline">
                                    <div class="form-group">
                                          <div class="input-group">
                                                <div class="input-group-addon"><i class="fa fa-pencil"></i></div>
                                                <input type="text" class="form-control" id="name" name="name" placeholder="name">
                                          </div>
                                    </div>
                                    <div class="form-group">
                                          <div class="input-group">
                                                <div class="input-group-addon"><i class="fa fa-mobile"></i></div>
                                                <input type="tel" class="form-control" id="phone" name="phone" placeholder="+11112223333"/>
                                          </div>
                                    </div>
                                    <button type="submit" class="btn btn-primary">Save</button>
                              </form>
                        </div>
                  </div>
                  <div class="col-md-4 col-md-offset-1">
                        <div id="chatBox" class='chat'>
                              <header>Chat Log</header>
                              <ul id='messagesDiv' class='chat-messages'></ul>
                              <footer>
                                    <form id="msg_form" method="post" accept-charset="utf-8" class="form-inline">
                                          <input type="text" id="messageInput" placeholder="Type a message..." />
                                    </form>
                              </footer>
                        </div>
                  </div>
      </div>
      <script>
            $(function(){
//                  initialize our Flybase object
                  var myGroupManager = new groupManager( "<%= api_key %>", "<%= app_name %>", "<?%= group_number %>");
                  myGroupManager.start();
            });
      </script>
</body>
</html>

这将显示我们的控制面板,它将分为两个窗格,左侧用于查看群组成员,右侧用于查看聊天日志。

在页面底部,我们正在初始化我们的groupManager类。我们将很快创建该文件。

接下来,让我们创建我们的样式表。在public/css文件夹中,创建名为style.css的文件:

css
body{font-size:12pt;font-family:helvetica}
.chatWindow{float:left;margin:20px;border:1px solid #000;width:300px;background:#e5e5e5;border-radius:5px}
.chatName{margin-bottom:10px;background:#666;color:#fff;padding:4px}
.messages{padding:4px}
.message_outbound{color:blue;text-align:right}
.tstamp{font-size:9px;padding:2px;margin-bottom:10px;border-bottom:1px dotted #666;color:#666}
.error{color:red;text-align:center}
.messageForm textarea{float:left;width:220px;margin:5px}
#phone{width:140px;}
#chatBox{background-color: #f8f8f8;background: rgb(229, 228, 228);margin:10px;}
.hide {display: none; }
.chat {font-family: "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;border-radius: 3px;-webkit-box-shadow: 0px 8px 20px rgba(0, 0, 0, 0.2);box-shadow: 0px 8px 20px rgba(0, 0, 0, 0.2);background-color: #dfe3ea;border: 1px solid #CCC;overflow: auto;padding: 0px;font-size: 18px;line-height: 22px;color: #666; }
.chat header {background-color: #EEE;background: -webkit-gradient(linear, left top, left bottom, from(#EEEEEE), to(#DDDDDD));background: -webkit-linear-gradient(top, #EEEEEE, #DDDDDD);background: linear-gradient(top, #EEEEEE, #DDDDDD);-webkit-box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.9), 0px 1px 2px rgba(0, 0, 0, 0.1);box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.9), 0px 1px 2px rgba(0, 0, 0, 0.1);border-radius: 3px 3px 0px 0px;border-bottom: 1px solid #CCC;line-height: 24px;font-size: 12px;text-align: center;color: #999; }
.chat input {-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;-webkit-box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.2);box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.2);border-radius: 3px;padding: 0px 10px;height: 30px;font-size: 18px;width: 100%;font-weight: normal;outline: none; }
.chat .chat-toolbar {background-color: #FFF;padding: 10px;position: relative;border-bottom: 1px solid #CCC; }
.chat .chat-toolbar label {text-transform: uppercase;line-height: 32px;font-size: 14px;color: #999;position: absolute;top: 10px;left: 20px;z-index: 1; }
.chat .chat-toolbar input {-webkit-box-shadow: none;box-shadow: none;border: 1px solid #FFF;padding-left: 100px;color: #999; }
.chat .chat-toolbar input:active, .chat .chat-toolbar input:focus {color: #1d9dff;border: 1px solid #FFF; }
.chat ul {list-style: none;margin: 0px;padding: 20px;height: 200px;overflow: auto; }
.chat ul li {margin-bottom: 10px;line-height: 24px; }
.chat ul li:last-child {margin: 0px; }
.chat ul .chat-username {margin-right: 10px; }
.chat footer {display: block;padding: 10px; }
.chat footer input {border: 1px solid #ced3db;height: 40px; width:75%;}

现在,让我们来看看我们系统的大脑。在public/js文件夹中,我们将创建一个名为group.js的文件:

javascript
var groupManager = function(api_key, app_name, group_number) {
//      store the group number
        this.group_number = group_number;
//      reference to our messages collection...
        this.messagesRef = new Flybase(api_key, app_name, "messages");

//      reference to our group collection...
        this.groupRef = new Flybase(api_key, app_name, "groups");

        this.group_members = [];
};

这是我们 groupManager 课程的第一部分。到目前为止,我们已经告诉它启动两个 Flybase 引用,一个名为messagesRef,一个名为groupRef。我们还将我们的组号存储为一个名为group_number的变量。

现在,让我们开始行动:

javascript
groupManager.prototype.start = function(){
      var _this = this;

// list group members if any
      this.groupRef.on("value", function( data ){
            if( data.count() ){
                  data.forEach( function( snapshot ){
                        var member = snapshot.value();
                        _this.group_members[member._id] = member;
                  });
            }
            _this.displayGroup();
      });

// listen for new members being added
      this.groupRef.on("added", function( snapshot ){
            var member = snapshot.value();
            _this.group_members[member._id] = member;
            _this.displayGroup();
      });

// save new group member to our app
      $("#group_form").submit( function(e){
            e.preventDefault();
            var member = {
                  'groupNumber': _this.group_number,
                  'memberName': $("#name").val(),
                  'memberNumber': clean_phone( $("#phone").val() )
            };
            _this.groupRef.push( member );
            $("#name").val('');
            $("#phone").val('');
            return false;
      });

// listen for members being removed
      $('div').on('click','a.delete', function(e){
            var _id = e.target.id;
            _this.groupRef.remove(_id);
            return false;
      });

      this.groupRef.on("removed", function( snapshot ){
            var member = snapshot.value();
            _this.group_members[member._id] = undefined;
            _this.displayGroup();
      });

// list any existing chat message
      this.messagesRef.on('value', function (data) {
            if( data.count() ){
                  data.forEach( function(message){
                        _this.displayChatMessage(message.value() );
                  });
            }
      });
// listen for incoming chat messages
      this.messagesRef.on('added', function (data) {
            var message = data.value();
            _this.displayChatMessage( message );
      });

// listen for outgoing chat messages
      $('#msg_form').submit( function(e){
            e.preventDefault();
            var message = {
                        "tstamp": new Date().toLocaleString(),
                        "fromName": "Admin",
                        "fromNumber": "",
                        "message": $('#messageInput').val(),
                        "fromCity": "",
                        "fromState": "",
                        "fromCountry": "",
                        "groupNumber": _this.group_number
            }
            _this.messagesRef.push( message );
            $('#messageInput').val('');
            return false;
      });
};

我们的函数设置了异步监听器,以及通过按下delete按钮删除表单提交和成员的监听器。

如果添加了一个组成员,那么该成员将被添加到集合中,并且会向该组的其他成员发送一个通知。群组成员列表也将显示新成员。

如果一个人被删除,他们的名字将从列表中消失,一条消息将被发送给其余的组成员。

我们的 groupManager 类的另一面是我们程序的实际聊天面。当管理员键入一条消息时,它将被发送给其他组成员。同时,当另一个群组成员发送消息时,管理员会在聊天框中看到该消息。

我们还剩下两个功能:一个显示一个组的所有成员,另一个显示聊天消息。

对于我们的组,我们将信息存储在名为 group_members 的类范围变量中。这使我们能够在收到相关通知时快速添加、更新或删除成员:

javascript
// Display group members
groupManager.prototype.displayGroup = function(){
      $('#group_wrapper').html('');
      for (var i in this.group_members ) {
            var member = this.group_members[i];
            if( member !== undefined ){
                  var html = '';
                  html = '<span>'+member.memberName+' ( ' + member.memberNumber + ' )</span> <a href="#delete" class="delete" id="' + member._id+'">[remove]</a>';
                  $('<div/>').prepend( html ).appendTo($('#group_wrapper'));
            }
      }
};

我们的最后一个功能显示收到的每条聊天消息:

javascript
// Display chat messages
groupManager.prototype.displayChatMessage = function( message ){
      var _this = this;
      var msg = message.message;
      if( message.media !== "" ){
            msg += '<br /><img src="' + message.media + '" />';
      }
      $('<li/>')
            .attr("id",message._id)
            .html(msg)
            .prepend(
                  $("<strong class='example-chat-username' />").text(message.fromName+': ')
                  ).appendTo( $('#messagesDiv') );
      $('#messagesDiv')[0].scrollTop = $('#messagesDiv')[0].scrollHeight;
};

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

javascript
node app.js

我们已经告诉我们的应用在端口 8080 上运行,所以如果你在网络浏览器上键入http://localhost:8080/,你应该会看到你的群聊。

在 Heroku 上举办

Heroku 非常适合让服务器配置变得简单而轻松。我们可以更快地构建,并担心对我们重要的事情,而不是试图配置我们自己的服务器。这与我们在 Flybase 的理念完美契合,让我们可以快速地构建东西。让我们看看如何在几秒钟内将我们的群聊应用部署到 Heroku。

请前往 http://heroku.com 创建您的免费账户。仪表板非常简单和用户友好。

接下来,您需要安装 Heroku Toolbelt。Heroku Toolbelt 将让我们访问 Heroku 命令行实用程序。Heroku Toolbelt 程序有不同的操作系统,您可以从以下链接下载:

安装工具带后,我们将可以使用 heroku 命令。

现在,您需要执行以下操作:

  1. 在您创建群组聊天应用的文件夹中,创建一个新的 git 存储库

  2. 登录 Heroku

  3. 在 Heroku 中创建应用

  4. 将您的群组聊天储存库推送到 Heroku

  5. 告诉 Heroku 创建一个 dyno(一个 worker,用来响应 web 请求)

  6. heroku open在新的自定义网址打开网页浏览器

就这样。您的应用现在正在 Heroku 上运行。

将您的群聊指定给 Twilio 中的一个电话号码

现在,我们想回到 Twilio 帐户,打开我们用来发送消息的电话号码。

当你在 Heroku 上创建你的应用时,你可以给它一个唯一的 URL。例如,让我们说

T2https://my-group-chat.herokuapp.com/

我们通过短信接收信息的网址现在将变为 https://my-group-chat.herokuapp.com/message

现在向您的 Twilio 号码发送短信,您应该会收到回复。如果你不知道,看看 Twilio 应用监视器( www.twilio.com/user/account/developer-tools/app-monitor )来帮助确定哪里出了问题。

摘要

我们用 Flybase ( http://flybase.io )和 Twilio ( http://twilio.com )搭建了一个实时群聊 app。

这个群聊应用甚至可以处理传入的媒体(图片、Word 文档、视频等。)并将其重新发送给组中的其他人。

你可以在 GitHub ( https://github.com/flybaseio/group-chat )找到我们的群聊应用。

这个应用可以供一群人进行对话。这在参加活动时会很方便。

你可以用它来通知与会者即将到来的会谈。例如,一个会议可以将他们的与会者添加到一个组中,然后在谈话开始、午餐时间或紧急情况时发送广播。