Murayama blog.

プログラミングと、その次の話

Parse - Cloud Code - Custom Webhooks

Custom Webhooks

フレキシブルなフォーマットのデータを処理するカスタムWebフックを構築するためにCloud Code上でExpressを利用できます。これにより、あなたの記述したWebフックを他のWebサービスから呼び出すことができます。非JSON形式のデータのやりとりが必要な場合やParseのREST APIヘッダをサポートしないエンドポイントを呼び出す場合は、Cloudファンクションの代用として利用できます。記述したロジックはCloud Code上で動作しているので、カスタムWebフック処理内でもParse JavaScript SDKを利用できます。

カスタムWebフックでは、リクエストヘッダやボディを直接操作します。JSON、form-encoded、raw bytesなどのデータを受け取り、任意のパーサーで解析します。またHTTPのBasic認証によって、Webフックを保護することもできます。次のサンプルはメッセージをParse Cloud上に保存する例です。

var express = require('express');
var app = express();
 
// Global app configuration section
app.use(express.bodyParser());  // Populate req.body
 
app.post('/notify_message', 
         express.basicAuth('YOUR_USERNAME', 'YOUR_PASSWORD'),
         function(req, res) {
  // Use Parse JavaScript SDK to create a new message and save it.
  var Message = Parse.Object.extend("Message");
  var message = new Message();
  message.save({ text: req.body.text }).then(function(message) {
    res.send('Success');
  }, function(error) {
    res.status(500);
    res.send('Error');
  });
});
 
app.listen();

上記のコードでは、リクエストボディを解析するためにexpress.bodyParserミドルウェアを使用しています。app.use(express.basicAuth(…))をグローバルなコンフィギュレーションセクションに記述していないことに気をつけてください。 これはHTTPのBasic認証をエンドポイントにだけ適用したいからです。アプリケーション内の他のエンドポイントは、publicなアクセスを受け付けることになります。

カスタムエンドポイントをテストするために、次のコマンドを実行します。form-encodedボディを含むリクエストを送信します*1

$ curl -X POST \
    -H 'Content-Type: application/x-www-form-urlencoded' \
    -d 'text=hi'
    http://YOUR_USERNAME:YOUR_PASSWORD@example.parseapp.com/notify_message

リクエストボディのraw bytesにアクセスしたいなら、express.bodyParserではなく、parseExpressRawBodyミドルウェアを利用できます。JSONやwww-form-encodedをサポートしつつraw bytesも扱いたいなら、両方のミドルウェアをインクルードすることもできます。

var express = require('express');
var parseExpressRawBody = require('parse-express-raw-body');
var app = express();
 
// Global app configuration section
app.use(express.bodyParser());
app.use(parseExpressRawBody());
 
app.post('/receive_raw_data', 
         express.basicAuth('YOUR_USERNAME', 'YOUR_PASSWORD'),
         function(req, res) {
  // If you send this endpoint JSON or www-form-encoded data, then 
  // express.bodyParser will fill req.body with the corresponding data.
  // Otherwise, parseExpressRawBody will fill req.body with a Buffer 
  // object containing the request body.  You can also convert this 
  // Buffer to a string using req.body.toString().
});
 
app.listen();

*1:URLに/notify_messageを追加しました。