[node.js]LINE BOT API Trialで自作のchatbotを動かす

4月ごろから、LINE BOT API Trial版が一般向けに公開されました。
元々先着1万名だったのですがそれは撤廃されて、GWが始まったくらいに再開され誰でも使えるように。
友達50人に制限されていますが、お試し版ということで普段使っているLINEでbotを作れるのは面白いということで注目度は高いですね。

「LINE BOT API Trial Account」の募集再開–ID検索にも対応 http://japan.cnet.com/news/service/35081826/

ここで、思い出してみますと、
某所で作ったchatterbot「ゆうき」ちゃんを流用することで、LINEのりんねみたいにLINEで話せるじゃあないですか。
GWだけどぼっちでやることなかったので、ちょうどいいです。
これで何時間でも飽きるまでLINEできます!やったリア充だ!

まずはアカウント取得。当然ながらLINEのアカウントが必要です。
(どうでもいいけど、LINEとNaverのアカウントって別なんだよね
ここまではすんなり行けると思います。誰でも。後は、botアカウントを作って、QRコードから友達になれるかまず確認。
これで数少ないLINEの友達が増えました。しかし、当然ながらこのままだと話しても何も返ってこないただのカカシ状態。

yuuki

ここで、LINE BOT APIの構造をかなり簡単に説明。

  • BOTに話しかけると、BOT管理者が設定したcallback URLに話しかけた情報がPOSTされます。
  • <li>その情報をもとに、自分のサーバで処理を行い、LINEのAPIサーバにPOSTを送ることで、BOTが返答します。</li>

    こんな感じ、簡素ですが、その分かなり簡単です。
    なお、署名キーも送られてくるため検証も可能です。
    問題点として、httpsオンリーという制約がちょっとだけ重たいですが、let’s encryptやStart SSLも正式に対応したのでお金もかからず簡単に作れると思います。

    いつものように、処理サーバはnode.js(javascript)で作ってます。ざっと見た感じ、node.jsで動かしてる記事は無かったのでちょうどいいですね。
    node.js(Expressフレームワーク)環境です。chatbotのソースは省きます。検証も省いてます。
    外部モジュールとしてfetch APIのようなものであるsuperagent使ってます。

    var request = require('superagent');
    var express = require('express');
    var app = express();
    //expressの設定等は省きます このままだと多分動きません
    app.post('/line/callback', function (req, res) {
        if (req != undefined && req.body != undefined) {
            var linecontent = req.body.result[0].content;
            if (linecontent) {
                //テキストメッセージのみ対応してます
                if (linecontent.contentType == 1) {
                    var linetext = linecontent.text; //テキストデータ
                    var linefrom = linecontent.from; // 送信ユーザのMID
                    var token = "token";
                    //chatbotの処理
                    api.gettext(linetext, token, function (restext) {
                        //callbackのrestextがchatbotの返答
                        //LINE BOT APIサーバにPOST
                        var sendmessage = {};
                        sendmessage["to"] = [linefrom];
                        sendmessage["toChannel"] = 1383378250; //固定値
                        sendmessage["eventType"] = "138311608800106203"; //固定値
                        sendmessage["content"] = {};
                        sendmessage["content"]["contentType"] = 1;
                        sendmessage["content"]["toType"] = 1;
                        sendmessage["content"]["text"] = restext;
                        //console.dir(sendmessage);
                        request.post("https://trialbot-api.line.me/v1/events")
                            .set('Content-Type', 'application/json; charset=UTF-8')
                            .set('X-Line-ChannelID', [APIのChannelID])
                            .set('X-Line-ChannelSecret', [APIのChannel Secret])
                            .set('X-Line-Trusted-User-With-ACL', [APIのMID])
                            .send(sendmessage)
                            .end(function (res) {
                            });
                    });
                } else {
                    //非対応!
                }
            }
        }
        res.send("res");
    
    });
    
    

    動かしてみるとこんな感じ。いやーやっぱりこういうのはなんか作ってると愛着湧いてきますね。

    chatbotに関して、自作と書いてますが、別に全部作ったものではなく、歴史あるchatterbotであるreudy1.9©Gimite,Glass_sagaを改変したものとなってます。
    まだ機械学習という言葉無い時代のものですが、よくできてると思います。

    その他ハマった点。
    多分レアケースなはまり方。というかプロキシ立ち上げてる人くらいしか躓かないと思うが、自分の環境でのミス。
    1.header
    headerはHOST:https://domain.com:443/callbackといった形になります。自分はheaderをHOST:https://domain.com/callbackに振り分けていたため、動作せず数分悩みました
    headerで振り分けなんかをしている人は要注意です。

    2.Let’s encryptを使う場合、中間CA証明書が必要
    CA Listに記載されているルートCA証明書を含んだ公開鍵証明書が使えるため、Let’s encryptの中間CA証明書が必要になります。
    なのでプロキシ環境では公開鍵としてfullchain.pemを使う必要があります。
    Let’s encryptじゃなくても中間CA証明書が無いと多分動作しません。アクセスログにも表示されないので注意。

    元々Let’s encryptは使えなかったようですが、今回は更新したてのほやほやでしたが使えました(ハマった点を除いて)。Let’s encrypt Autority X3なら問題ないかと。

    SSL証明書”Let’s Encrypt”でhttps環境を構築した

    ついに、以前記事で紹介したLet’s Encryptがpublic Betaになり、誰でも使えるようになりました。

    それ以前に、自分はClosed Betaに参加していたので、それで実は結構前から動かしていました。
    今回は、どんな感じで動くのかのレビュー記事です。

    前の記事:無償利用で使えるSSL証明書”Let’s Encrypt”を仮想環境で動かしてみたかった
    Preview版ではvirtualenvを自分で作成しないとならないため、割と手間でしたが、今回は、
    ダウンロードした後に./letsencrypt-autoというコマンドを打つだけで、
    必要なもののインストールから、let’s Encrypt clientのコンパイル、Apacheやnginxのインストール、そしてSSLの導入、全てを自動で行ってくれるようになり、さらにわかりやすく、楽になりました。
    これだけでhttps対応のWebサーバが最初から作れるっていうことですね。

    自分のサーバのnode.jsでプロキシを組んでるので、SSL証明書はnode.jsに組み込みます。
    なので、スタンドアローン版を選択し、生成された証明書を手動で組み込みます。
    スタンドアローンの場合、本当にそのドメインが存在しているか確認のため、80/443ポートを使ってlet’s EncryptのAPIにアクセスしてるような挙動をします。
    なので、既にWebサーバを立てている人は一時的にサーバが使えなくなります。まあ設定は数分で終わりますが。
    Apacheやnginxの場合でも、自動で作ると(多分)SSLの設定も勝手に作られちゃうと思うので、
    知識のある人ならスタンドアローンで証明書だけ作って、自分で設定を作って組み込んだほうがいいかもしれません。

    証明書に関しては、/etc/letsencrypt/liveに格納されています。

    • privkey.pem (サーバ秘密鍵)
    • cert.pem (サーバ証明書[公開鍵])
    • chain.pem (中間CA証明書)
    • fullchain.pem (サーバ公開鍵+中間CA証明書)
      が入ってます。
      node.jsの場合は、privkey.pem、cert.pemを組み込めば動きました。
      node.jsのhttps対応に関しては、この記事を参考に。
      [node.js]HTTPS通信に対応させてみる(SSL-リバースプロキシ環境を構築する)
      そして、導入したものがこちら。
      letsencrypt
      オレオレ証明書ではなく、ちゃんとLet’s Encryptから正式なものと証明されています。
      これで毎回Chromeさんに情報抜き取られるサイトかもしれないという報告を受けなくて済みます。自分のサイトなのに。
      まだ証明書の期限は短く、3カ月(90日)となっていますが、
      ベータではなく正式版になれば、期間が延び、自動更新も可能になるかもしれません。

    Monaca+node.js+socket.ioでWebsocketアプリを作るてすと

    最近はjavaばっかり使ってる気がしますが、
    この手の記事は、ググってもあまり出ていないので書き留めておくことにしました。

    つまりはPhonegap(cordova)なハイブリットアプリとnode.js鯖、socket.ioでWebsocketなアプリを簡単に作ろうということです。
    Phonegap、大体はスタンドアローン(単体)で動くアプリの作り方や、ajaxを利用した通信なんかがほとんどなので。

    そして、今回は構築環境が簡単で簡単にビルドもできるクラウド環境で動く
    cordova開発プラットフォームMonacaを使います。
    サーバに関してはこれもクラウド環境で。開発環境構築までやってくれるサーバサイド開発プラットフォームCloud9使います。
    サーバサイドプログラミングもクライアントサイドプログラミングも全部クラウド任せ。
    今の時代開発は何から何まで全部クラウドで出来るんだよ。ローカルなんていらないんだよ?っていう目的の記事でもあります。

    とりあえず、そもそもCordovaフレームワークでsocket.ioって使えるのかなと思っていたのですが、公式にすごくわかりやすい例がありました。
    Socket.IO with Apache Cordova

    これを見ると、クライアント側のsocket.io.jsは公式が用意されているCDNを使えばcordovaでも問題なく動くらしいですね。
    <script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>;

    これで、ちゃんと動いてくれるのか試してみよう。
    サーバ側のコード。socket.ioさえ使えればいいのでhttpサーバを立てる必要はありません。
    process.env.PORTは、Cloud9で自動的にポートを振り分けてくれます。

    var io = require('socket.io')(process.env.PORT);
    
    io.sockets.on('connection', function (socket) {
        console.log('socket connected');
    
        socket.on('disconnect', function () {
            console.log('socket disconnected');
        });
    
        socket.emit('text', 'socket.io connect!');
    });

    クライアント側(monaca)に書くコード。省略してjsファイルだけです。

    (function () { //即時関数
        //接続先の指定
        var url = "test-potproject.c9.io"; //websocketサーバのURL。
    
        //接続
        var socket = io.connect(url);
        socket.on('connect', function() {
            socket.on('text',function(text){
                alert(text);
            });
         });
    }());

    接続できればアラートが表示されるだけの簡単なアプリです。PCのChromeではちゃんと動作しました。
    しかし、本元はアプリなんで、AndroidやiOSで動くのか。

    で、何故だが動かない。
    WebViewだから動くと思ったのに。試した端末としてはAndroid4.4です。対応してないってことはなさそうなんだけど・・・

    で、試行錯誤したところ。WebsocketURLをws://test-potproject.c9.ioと記述しないと動きませんでした。ブラウザの仕様の問題か・・・
    Web技術はやりやすくてとてもいいのだが、ブラウザが違うと動かなくなったりするのでこのあたりにぶち当たると痛い。

    Android4.4 Nexus7で試したところですが、すぐに動きました。ほかのブログには接続に5秒とか待たされるとか聞きましたが、問題なく。
    この部分もブラウザと端末で差がかなりありそうです。というか多分古いAndroidなんかでは動かないでしょうし・・・。
    ネイティブJavaで記述されたsocket.ioのcordova pluginもありますが、古いのでこれはこれで最新版のsocket.ioで動くのか気になるところです。


    ここから余談。

    最近知りましたが、
    プロトコルを省略して//blog.potproject.net/という風に書くこともできるらしいですね。
    これも相対URLの一つだとか。ちゃんとしたものでクソ古いブラウザ以外は動作するらしいです。

    つまり、画像を表示するには
    <img src="//blog.potproject.net/wp-content/uploads/2015/02/aapicture.png" />
    と書けばよろしいと。
    表示させてみる。

    後にhttps対応させるとかならこういう方法もあるのね。と。

    node.jsなんかでオンラインなゲームを作る(5) ルーム機能(socket.io)

    Websocketを利用して、特定の処理や通知などをそのルーム、またはその人にだけ行う。

    WebSocket – Wikipedia
    Websocketは双方向通信のプロトコルです。html5と対応ブラウザなら動作します。
    双方向通信なので、つまりは、サーバ側からクライアントにプッシュ通知、クライアントからサーバ側にデータ送信、といったことが可能になります。
    connectionが成立した後は後ろでプロトコルが動いてくれますので、動的なWebサイトとして、しかもサーバとのやり取りをずっと行えます。
    この技術を応用すれば、オンラインゲームに必須なチャット機能的なこと、ダメージ処理とかそういうの、が全部ブラウザ上で動くってことですね。
    Ajax(XMLHttpRequest)なんかだとクライアントから問い合わせは出来てもサーバから受け取ることは難しいので、Ajaxの上位互換みたいな感じらしいです。
    socket.ioは、Websocketを使うためのnode.jsモジュールです。

    まずは、初期設定的な何か。
    サーバ(app.js)
    socketio = require('socket.io')
    var server = http.createServer(app);
    var io = socketio.listen(server);
    これで、websocketプロトコルをlistenします。一応独自プロトコルなのですがTCP 80/443で動作しますので、そのままhttp(TCP 80)に乗っける形になるのでこう書きます。

    クライアント(main.js)
    var socket = io.connect();
    クライアントは、事前にhtmlから/socket.io/socket.io.jsをロードして使用します。
    (socket.ioサーバーを立てた段階で、自動的にサイトからロードできるようになります)
    前回作成したejsに書いておきます。
    そうすれば、この一行を書くだけで使えるようになります。
    socket.ioは、socket.emit(送信する値)で送信、socket.onで受け取りの処理(callback)大体この二つを使います。

    socket.ioでのROOM処理は、この辺を参照。
    既にjoinメゾットというのが準備されていて、同じ部屋にjoinしたクライアントだけ、emit(送る)ことが出来ます。
    参考:Socket.IO — Rooms and Namespaces
    Node.js – Socket.IO覚え書き(Room、joinまわり) – Qiita

    順を追って書いていくと、
    クライアントが接続するので、その接続をサーバ側が受け取り、サーバ側はRoomIDにしたがってjoinメゾットで部屋を振り分けます。
    その後、to(room).emitメゾットでその部屋のみ送ります。

    クライアント(main.js)

    socket.on('connected', function() {
                //部屋番号送信・初期表示
                socket.emit('init', {'room': RoomID});
            });
            //文章受け取り
            socket.on("logmessage", function (data) {
                logpush(data); //dataを文章を表示する関数
            });
    

    s.on(‘connected’,[callback])はWebsocket接続完了時に自動的に呼び出されます。それに、RoomIDをinitとしてサーバに送信。

    サーバ(app.js)

    var chat = io.sockets.on('connection', function(socket) {
        socket.emit('connected');
        console.log(socket.id+" connected");
        //room別に管理
        socket.on("init",function(req){
            //join(room)で部屋を作る
            socket.setRoominfo=req.room;
            socket.join(req.room); //roomIDごとに登録
            socket.join(socket.id); //個別に識別するためにクライアント識別子であるsocketidを登録
    
            console.log(req.room+" join");
    
        });
        socket.on('msg post', function(msg) { //Room内にメッセージ送信
            chat.to(socket.setRoominfo).emit("logmessage", msg);
        });
    });

    簡単なチャットとしての機能が出来ました。
    socket.setRoominfoに、一時的なデータを格納するためRoomIDを入れています。
    これで、各クライアントが’msg post’と文字列をemitすると、同じルームに入っているクライアント全てに表示されます。
    その後、Disconnection(ブラウザから離れた時)の処理、gameをstartした時の処理、などでログを表示するようにします。
    game
    まあ、ゲームの道のりは遠い。次はmongoDBです。


    githubにソースがあります。製作中。ソースは自由に。

    前:node.jsなんかでオンラインなゲームを作る(4) ルーム機能

    [node.js]HTTPS通信に対応させてみる(SSL-リバースプロキシ環境を構築する)

    タイトルの通り。httpsのこともこれから勉強していかなければならないのかなーと思い。

    きっかけはこの記事です。

    『証明書を無料で発行、HTTPSの導入を支援する「Let’s Encrypt」』は何に使え、何に使えないのか – いろいろやってみるにっき

    HTTPS普及を推進するプロジェクト「Let’s Encrypt」、Linux Foundation傘下に

    これを見ながら10年後くらいはWeb全てがhttpsになってんじゃねーかなと思えてきて。

    無料なら個人でも気兼ねなく使えますもんね。商用には辞めたほうがいい感じですけれど・・・

     

    当然、証明書は所謂オレオレ証明書です。

    ・・・オレオレ証明書って言い方はどうなんだろうとちょっと思います。別に偽サイトじゃないのにニュアンスからそう思わせてしまうじゃないかと。

    ソースコード。

    var https = require('https');
    var fs = require('fs');
    
    var ssloptions={key: fs.readFileSync('server.key', 'utf8'),
        cert: fs.readFileSync('server.crt', 'utf8')};
    
    var serverhttps = https.createServer(ssloptions,function ( req, res ) {
            res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('SSL Connection');
    });
    
    serverhttps.listen(443);

    URL:https://potproject.net/

    ※オレオレ証明書なので当然https通信に関する警告が各ブラウザで出ます。

    node.jsには標準モジュールとして既にhttpsが存在します。これでencrypt関連のことは全く知らなくても使えます。

    なので、最小限のコードであれば通常のhttp通信と違うところは証明書の登録をしなくてはならないという点だけです。

    証明書(秘密鍵・公開鍵)に関してはopensslで生成。ここに公的機関が発行した証明書を入れ替えればすぐに使えます。

    これで通信は暗号化されたわけですが、最近はSSL絡みの脆弱性がいっぱい出てきてますし、規格に関してはまだまだ変わっていくのでしょうかねー・・・

    このブログもhttpsに対応させよう

    せっかくなのでブログも対応させよう。

    httpsに対応することで、ログイン時に盗聴されて乗っ取られることはなくなると思います。そもそもまずそんなことは起きない・・・というツッコミはさておき。
    鯖自体、リバースプロキシサーバでサブドメインごとに振り分けているため、設定は結構複雑になってきます。

    こんな感じで鯖の構造も変更しました。
    http-node-proxy(リバースプロキシサーバ | port 80/443[外部ポート番号])
    —potproject.net(Node.js | port 8080(http/https)
    —blog.potproject.net(Apache | port 8081(http)/8443(https))
    別途、ApacheにSSLの設定をしなくてはならないです。

    と思ったんですが、リバースプロキシからの通信は暗号化する必要ないので(同じ鯖で内部ルーティングしているため)、
    ネットワークからリバースプロキシまでをSSLで暗号化、
    リバースプロキシからapacheの受付内部ポートまでは暗号化せずhttpで渡すようにしました。
    なので、バーチャルホスト設定で8443ポートを内部ルーティングできるようにして、ApacheのSSL設定は停止しました。
    Apache ssl.conf設定。ssl.confだけどSSL切ってます

    Listen 8443 https
    
    <VirtualHost _default_:8443>
    
    # General setup for the virtual host, inherited from global configuration
    DocumentRoot "/var/www/wordpress"
    ServerName blog.potproject.net
    SetEnv HTTPS on
    
    #   SSL Engine Switch:
    #   Enable/Disable SSL for this virtual host.
    SSLEngine off
    
    ---中略---
    
    </VirtualHost>

    node.jsプロキシサーバの設定。

    var https = require('https');
    var fs = require('fs');
    
    var httpsoptions={target:'http://127.0.0.1:8443',secure:false};
    
    var ssloptions={key: fs.readFileSync('server.key', 'utf8'),
        cert: fs.readFileSync('server.crt', 'utf8')};
    
    var serverhttps = https.createServer(ssloptions,function ( req, res ) {
            if (req.headers.host == 'potproject.net') {
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('SSL Connection');
        }else if (req.headers.host == 'blog.potproject.net') {
            Proxy.web( req, res ,httpsoptions);
    
        }
    
    });
    serverhttps.listen(443);

    こんな形に変更しました。

    options[secure]はhttps -> httpsでプロキシをする時にtrueにします。今回はhttps -> httpなのでfalseです。

    そしてhttpsでつながった・・・のはいいのですが、デザインが崩れて明らかにCSSやJSが読み込めていない。
    調べたところ、こういう問題があるようです。
    WordPress をSSL運用すると管理画面でアップロードした画像が見れない
    こんな問題があるらしい。ってことはまだ治っていないのだろうか?それともテーマの問題か?
    ということでSetEnv HTTPS onをssl.confに追加し、コードを組むことででちゃんと表示されるようになりました。
    その後、WordPress HTTPS(SSL)プラグインを導入し、管理者ログインと画面をhttps通信化。
    ちゃんと管理者画面だけhttpsにリダイレクトしてくれますのでいいですね。

    https://blog.potproject.net/
    ※オレオレ証明書なので当然https通信に関する警告が(以下略
    これでこのブログもhttpsの仲間入りですね。オレオレ証明書だしまあ多分ほとんど意味ない気がしますが・・・
    Let’s Encryptの無料証明書がきたらぜひ使ってみようと思います。まあその時までこのままで。
    無料のSSLならStartSSLなんか使えるという声もありますが登録めんどそうなので・・・

    node.jsなんかでオンラインなゲームを作る(4) ルーム機能

    オンラインゲームには不可欠な存在だと思える、ルーム機能を実装していきます。
    内容は、そのままルーム機能です。チャットで個別の部屋みたいなのを実装するためのもの。
    同じ部屋同士で対戦できます。逆に同じ部屋に入っていないと対戦できません。これがちゃんと機能しないとえらいこっちゃです。

    この機能には、express,ejs,socketを利用します。
    ということで、requireで指定します。おまじないという奴です。
    var express = require('express')
    , http = require('http')//標準モジュール http
    , path = require('path') //標準モジュール path
    , fs = require('fs') //標準モジュール filesystem
    , socketio = require('socket.io')
    , mongoose = require('mongoose')
    , ejs=require('ejs');

    ルーム機能の実装には、socket.ioが不可欠です。ほぼこいつに頼りきり。
    流れとしては、

    1. form.htmlからPOSTでルーム番号を送る
    2. ルーム番号を受け取り、ejsで表示、その部屋に入る(index.ejsへ遷移)
    3. emitで通知する場合、そのルーム内だけ通知するようになる(socket.io)

    これが一連の流れとなります。
    3はsocket.ioを含む処理のため、次の記事で。1,2を実装していきましょう。

    ejsについて
    ejsはテンプレートエンジンというもので、htmlに変数を流しいれるために使うファイルみたいなものです。VIEWに当たるもの。
    書き方としては、PHPやJSPと似てます。htmlにejsタグを付けて、変数を入れていきます。
    ついでに、デフォルトでエスケープ処理をしてくれたりもします。
    [index.ejs]

    <%=room_id %>に送った変数[room_id]が挿入されます。JSPと書き方ほぼ一緒だし見分けがつかない
    これで、POSTで送った値を取得したら、ejsで流し込み、タイトルに表示・javascriptの値として登録します。

    <html>
      <head>
        <meta charset="utf-8">
        <title>RoomID:<%=room_id %></title>
        <script type="text/javascript">
        var RoomID = "<%=room_id %>";
        </script>
      </head>
      <body>
      </body>
    </html>

    [form.html]
    送信する方のPOSTはこんな感じです。特に何も考えずシンプルに実装。こっちはhtmlです。

    <!DOCTYPE html>
      <head>
        <meta charset="utf-8">
        <title>title</title>
      </head>
      <body>
      <form action="./" method="post">
        <p>部屋ID:<input type="text" name="room" size="10"></p>
          <p>
        <input type="submit" value="入室"><input type="reset" value="リセット">
          </p>
    </form>
      </body>
    </html>
    

    [app.js]
    app.jsはサーバーサイドのjavascriptとして。サーバーの処理を記述します。
    httpサーバのlisten、expressの初期設定などは省略します。
    POSTで送った値はreq.bodyに格納されているということが割と重要です。覚えていないと変なところで躓くかも。

    //入室
    app.get('/', function(req,res){ //アクセスされたら
          fs.readFile('form.html',function(err, data){ //form.html読み込んで送る
            if (err) {
                console.error("console:"+err);
                res.send(404); // エラーで404を返す
                return;
            }
            res.set('Content-Type', 'text/html');
            res.send(data);
          });
    });
    //index.htmlのGET
    app.post('/', function(req,res){ //postで送られて来たら
            if(req.body.room==null){
                res.send(500); // 値なしならエラーで500を返す
                return;
            }
            res.render('index.ejs',{room_id:req.body.room}); //ejsをレンダリングして送る
            });
    
    });

    次はsocket.ioについて理解していかないと・・・。


    githubにソースがあります。製作中。ソースは自由に。

    前:node.jsなんかでオンラインなゲームを作る(3) express設定
    次:node.jsなんかでオンラインなゲームを作る(5) ルーム機能(socket.io)

    node.jsなんかでオンラインなゲームを作る(3) フレームワークであるExpressの設定

    Expressはnode.jsで動作するフレームワークです。多分nodeの中では一番有名で、これを使うことでWebサーバの操作がぐっと楽になると思います。
    Express Fast, unopinionated, minimalist web framework for Node.js
    これがなくてもhttpサーバは立てられますが、変数を入れたりPOSTを処理したりなど複雑な操作は、コードを書いて処理しないといけません。
    そういうのを一括で解決してくれるものをフレームワークと呼びます。
    元々Androidアプリばっかり作ってたのでWebフレームワークというものをほとんど使ったことが無かった私なのですが、
    これを使うとWeb開発がめちゃくちゃ楽になり、やらないといけない作業も数段減るため、
    最近のWeb開発においてはフレームワークはほぼ必須なんだなあと使ってると思います。
    Express設定
    一部抜粋。全文はソースにて。

    var express = require('express')
      , http = require('http')
      , path = require('path')
      , socketio = require('socket.io')
      , fs = require('fs')
      , mongoose = require('mongoose')
      , ejs=require('ejs');
    var app = express();
    var server = http.createServer(app);
    var io = socketio.listen(server);
    
    //expressの設定(socket.ioは関係ないです)
    app.set('port', process.env.PORT || 8080); //portを指定(デフォルト:8080)
    app.set('view engine', 'ejs'); //ejsを使用
    app.use(express.favicon()); //標準faviconを出力
    app.use(express.logger('dev')); //logger:開発用に詳細ログが表示されるようになります
    app.use(express.json()); //bodyParser絡み
    app.use(express.urlencoded()); //bodyParser絡み
    app.use(express.methodOverride()); //methodOverride ミドルウェア
    app.use(app.router); //パス名絡み
    app.use(express.static(path.join(__dirname, 'img'))); //staticなディレクトリ
    

    expressの設定は結構いろいろあってこれはこれで覚えるところ多くて大変。
    コメントで簡単な説明を付けましたが、自分も完全な中身は知らないので各自ググってください。
    app.use(express.favicon());
    は、別にfaviconいらないし付ける必要もないのですが、これがないとコンソールさんにfaviconねーぞと怒られるので付けました。
    app.use(express.json());
    app.use(express.urlencoded());
    は、前話したbodyparser絡みの設定。これを入れておかないとpostした時とかエラー吐きますのでとりあえず入れておきましょう。
    app.use(express.static(path.join(dirname, 'img')));
    Express.staticは、指定したファイル/ディレクトリをスタティックなファイルとして公開します。
    つまり、http上でディレクトリ内の画像やjsファイルなど、誰でもアクセスが可能になります。
    ディレクトリの指定も可能です。(ディレクトリ内のファイルが全て公開されます)
    path.joinは、絶対パスで指定しなければならないために使用します。
    dirnameは、実行しているjsファイルのディレクトリパスを表します。

    この後は、アクセスされた時の処理を書いていきます。


    githubにソースがあります。製作中。ソースは自由に。

    前:node.jsなんかでオンラインなゲームを作る(2)
    次:node.jsなんかでオンラインなゲームを作る(4) ルーム機能