プログマブルFax クイックスタート

TwilioプログラマブルFaxを使うと、Webアプリケーションを使ってFAXを送受信できるようになります。今日においても、まだFAXを使った様々な業務フローがあります。プログラムを使えばこれらの業務フローをよりダイナミックなものに変化させられます。さっそく始めましょう!

はじめる

みなさんがFAXの革命へ乗り出すにあたり、まずFAX送受信用のTwilio電話番号が必要になります。Twilioコンソール(管理画面) から、(まだTwilioアカウントをお持ちではない方はこちらから サインアップ ) FAX送受信に対応した電話番号を検索します。

FAX送受信対応電話番号を探す

リストから該当の番号に表示されている Buy ボタンをクリックして電話番号を取得します。

FAX送受信対応電話番号を取得する

これでFAX送受信対応電話番号が取得できました。それでは、どのようにREST APIを使ってFAXを送信するのか見ていきましょう。

FAXの送信

FAXを送るためには、Account SIDとAuth Tokenが必要です。これらのクレデンシャル(認証情報) は、コンソール(管理画面) の ダッシュボード で確認できます。これらのクレデンシャルは、みなさんのAPIリクエストがHTTPベーシック認証を行うために利用されます。このAPIリクエストに、あと3つ、付与しなければいけないパラメータがあります。

  1. From FAX送信者番号として通知するTwilio電話番号。ご自身で取得しているFAX送受信対応Twilio電話番号のうちの1つを指定します。
  2. To FAXの送信先電話番号。
  3. MediaUrl 送信内容が保存されたPDFファイルまでの完全URL。

注意:From や To に指定する電話番号は E.164形式 で記載する必要があります。ここで紹介している curl のサンプルコードでは、電話番号の先頭に記載する「+」記号をエンコード済みの値である「%2B」と書いています。

追加メモ: Programmable Faxがベータ期間中の間は、Fax APIのご利用にはお使いの言語用のTwilioヘルパーライブラリーの"alpha"ブランチを使用することが必要です。

コードサンプルを読み込んでいます...
Language
SDKバージョン:
  • 5.x
SDKバージョン:
  • 7.x
SDKバージョン:
  • 3.x
SDKバージョン:
  • 5.x
SDKバージョン:
  • 6.x
SDKバージョン:
  • 5.x
形式:
  • JSON
// Download the Node helper library from twilio.com/docs/node/install
// These consts are your accountSid and authToken from https://www.twilio.com/console
const accountSid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
const authToken = 'your_auth_token';
const client = require('twilio')(accountSid, authToken);

client.fax.v1.faxes
  .create({
    to: '+15558675310',
    from: '+15017122661',
    mediaUrl: 'https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf',
  })
  .then(response => {
    console.log(response.sid);
  })
  .catch(err => {
    console.log(err);
  });
// Download the twilio-csharp library from twilio.com/docs/libraries/csharp
using System;
using Twilio;
using Twilio.Rest.Fax.V1;
using Twilio.Types;
using System.Collections.Generic;

class Example
{
    static void Main(string[] args)
    {
        // Find your Account Sid and Auth Token at twilio.com/console
        const string accountSid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        const string authToken = "your_auth_token";
        TwilioClient.Init(accountSid, authToken);

        var to = "+15558675310";
        var mediaUrl = new Uri(
            "https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf");

        var fax = FaxResource.Create(to, mediaUrl, from: "+15017122661");

        Console.WriteLine(fax.Sid);
    }
}
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Your Account Sid and Auth Token from twilio.com/console
$sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
$token = "your_auth_token";
$client = new Client($sid, $token);

$options = array(
  "from" => "+15017122661"
);
$fax = $client->fax->v1->faxes->create(
    "+15558675310",
    "https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf",
    $options
);

echo $fax->sid;
require 'net/http'
require 'json'

# Get your Account SID and Auth Token from twilio.com/console
account_sid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
auth_token = 'your_auth_token'

uri = URI('https://fax.twilio.com/v1/Faxes')

Net::HTTP.start(uri.host, uri.port,
                use_ssl: uri.scheme == 'https') do |http|

  request = Net::HTTP::Post.new uri.request_uri
  request.basic_auth account_sid, auth_token
  request.body = URI.encode_www_form(To: '+15558675310',
                                     From: '+15017122661',
                                     MediaUrl: 'https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf')

  response = http.request request

  puts JSON.parse(response.body)['sid']
end
from twilio.rest import Client

# put your own credentials here
account_sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
auth_token = "your_auth_token"

client = Client(account_sid, auth_token)

fax = client.fax.v1.faxes.create(
    from_="+15017122661",
    to="+15558675310",
    media_url="https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf"
)

print(fax.sid)
// Install the Java helper library from twilio.com/docs/libraries/java
import com.twilio.Twilio;
import com.twilio.rest.fax.v1.Fax;
import com.twilio.rest.fax.v1.FaxCreator;
import java.net.URI;
import java.net.URISyntaxException;

public class Example {
    // Find your Account Sid and Token at twilio.com/console
    public static final String ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    public static final String AUTH_TOKEN = "your_auth_token";

    public static void main(String[] args) throws URISyntaxException {
        Twilio.init(ACCOUNT_SID, AUTH_TOKEN);

        String from = "+15017122661";
        String to = "+15558675310";
        URI mediaUrl = new URI("https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf");
        FaxCreator faxCreator = Fax.creator(to, mediaUrl);
        faxCreator.setFrom(from);
        Fax fax = faxCreator.create();

        System.out.println(fax.getSid());
    }
}
curl 'https://fax.twilio.com/v1/Faxes' \
    -X POST \
    -d 'To=%2B15558675309'  \
    -d 'From=%2B15017250604'  \
    -d 'MediaUrl=https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf' \
    -u ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:your_auth_token
{
	"status": "queued",
	"direction": "outbound",
	"from": "+15017122661",
	"date_updated": "2017-04-06T06:39:15Z",
	"price": null,
	"account_sid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
	"to": "+15558675310",
	"date_created": "2017-04-06T06:39:15Z",
	"url": "https://fax.twilio.com/v1/Faxes/FX4ac3612393b5a66f11c73a148f956a5c",
	"sid": "FX4ac3612393b5a66f11c73a148f956a5c",
	"duration": null,
	"num_pages": null,
	"quality": "fine",
	"price_unit": null,
	"api_version": "v1",
	"media_url": null
}
FAXの送信

実行後すぐに、あなたのFAXは送信処理に掛かります。FAXの送信ステータスを取得する(失敗も含めて)には、 StatusCallback パラメータをAPIリクエストに含めることで、FAXのステータスが変更されるたびにTwilioは指定URLを叩きます。

FAXを受信する

FAX送受対応Twilio電話番号にFAXが着信すると、Twilioはみなさんが指定したURLへHTTPリクエストを発行します。このコールバックメカニズムは、いわゆる Webhook というものです。TwilioがみなさんのWebアプリケーションにリクエストを発行する際、Twilioはその戻りとしてXML形式のTwiMLが返ることを期待します。このTwiMLに、Twilioへ何をさせるか指示を記載するというわけです。以下は、FAXを受信するための簡単なサンプルコードです。

コードサンプルを読み込んでいます...
Language
SDKバージョン:
  • 5.x
SDKバージョン:
  • 7.x
SDKバージョン:
  • 5.x
SDKバージョン:
  • 6.x
SDKバージョン:
  • 4.x
require 'rubygems'
require 'sinatra'

# Define a handler for when the fax is initially sent
post '/fax/sent' do
  # Let's manually build some TwiML. We can choose to receive the
  # fax with <Receive>, or reject with <Reject>.
  content_type 'text/xml'

  <<-TWIML
    <Response>
        <Receive action="/fax/received"/>
    </Response>'
    TWIML
end

# Define a handler for when the fax is finished sending to us - if successful,
# We will have a URL to the contents of the fax at this point
post '/fax/received' do
  # log the URL of the PDF received in the fax
  logger.info(params['MediaUrl'])

  # Respond with empty 200/OK to Twilio
  status 200
  body ''
end
using System.Web.Mvc;

namespace TwilioFax.Web.Controllers
{
    public class FaxController : Controller
    {
        // Define a handler for when the fax is initially sent
        [HttpPost]
        public ActionResult Sent()
        {
            // Let's manually build some TwiML. We can choose to receive the
            // fax with <Receive>, or reject with <Reject>.
            const string xmlString = "<Response>" +
                                        "<Receive action =\"/fax/received\"/>" +
                                      "</Response>";

            return this.Content(xmlString, "text/xml");
        }

        // Define a handler for when the fax is finished sending to us - if successful,
        // We will have a URL to the contents of the fax at this point
        [HttpPost]
        public ActionResult Received()
        {
            // log the URL of the PDF received in the fax
            System.Diagnostics.Debug.WriteLine(Request["MediaUrl"]);

            // Respond with empty 200/OK to Twilio
            return new EmptyResult();
        }
    }
}
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class FaxController extends Controller {

    public function __construct()
    {
        parent::__construct();

        // set content-type for all requests returned by this controller
        $this->set_output->set_content_type('text/xml');
    }

    // Define a handler for when the fax is initially sent
    public function sent()
    {
        $twimlResponse = new SimpleXMLElement("<Response></Response>");
        $receiveEl = $twimlResponse->addChild('Receive');
        $receiveEl->addAttribute('action', '/fax/received');

        $this->output->set_output($twimlResponse->asXML());
    }

    // Define a handler for when the fax is finished sending to us - if successful,
    // We will have a URL to the contents of the fax at this point
    public function received()
    {
        // log the URL of the PDF received in the fax
        log_message('info', $this->input->post("MediaUrl"));

        // Respond with empty 200/OK to Twilio
        $this->set_status_header(200);
        $this->output->set_output('');
    }
}
#!/usr/bin/env python
"""Fax snippet."""

from flask.ext.script import Manager
from flask import Flask, Response, request

app = Flask(__name__)


@app.route('/fax/sent', methods=['POST'])
def fax_sent():
    """Define a handler for when the fax is initially sent."""
    # Let's manually build some TwiML. We can choose to receive the
    # fax with <Receive>, or reject with <Reject>.
    twiml = """
        <Response>
            <Receive action="/fax/received"/>
        </Response>
    """

    return Response(twiml, mimetype='text/xml')


@app.route('/fax/received', methods=['POST'])
def fax_received():
    """Define a handler for when the fax finished sending to us."""
    # We will have a URL to the contents of the fax at this point
    # log the URL of the PDF received in the fax
    print(request.form.get('MediaUrl'))

    # Respond with empty 200/OK to Twilio
    return '', 200


if __name__ == "__main__":
    Manager(app).run()
import spark.Route;

import static spark.Spark.post;

public class IndexFax {

    private static Route faxSent = (request, response) -> {
        // Let's manually build some TwiML. We can choose to receive the
        // fax with <Receive>, or reject with <Reject>.
        String twiml = "<Response>" +
                            "<Receive action=\"/fax/received\"/>" +
                        "</Response>";

        // Send Fax twiml response
        response.type("text/xml");
        return twiml;
    };

    // Define a handler for when the fax is finished sending to us - if successful,
    // We will have a URL to the contents of the fax at this point
    private static Route faxReceived  = (request, response) -> {
        // log the URL of the PDF received in the fax
        System.out.println(request.params(":mediaUrl"));

        // Respond with empty 200/OK to Twilio
        response.status(200);
        return null;
    };

    public static void main(String[] args) {
        post("/fax/sent", faxSent);

        post("/fax/received", faxReceived);
    }
}
const http = require('http');
const express = require('express');
const bodyParser = require('body-parser');

const app = express();

// Parse any incoming POST parameters
app.use(bodyParser({ extended: false }));

// Define a handler for when the fax is initially sent
app.post('/fax/sent', (req, res) => {
  // Let's manually build some TwiML. We can choose to receive the
  // fax with <Receive>, or reject with <Reject>.
  const twiml = `
  <Response>
    <Receive action="/fax/received"/>
  </Response>
  `;

  // Send Fax twiml response
  res.type('text/xml');
  res.send(twiml);
});

// Define a handler for when the fax is finished sending to us - if successful,
// We will have a URL to the contents of the fax at this point
app.post('/fax/received', (req, res) => {
  // log the URL of the PDF received in the fax
  console.log(res.body.MediaUrl);

  // Respond with empty 200/OK to Twilio
  res.status(200);
  res.send();
});

// Start the web server
http.createServer(app).listen(3000, () => {
  console.log('Express server listening on port 3000');
});
testable: false
ここで、2つのリクエストが必要になるはずです。1つは、みなさんのTwilio番号にFAXが着信した時にTwilioへ指示するためのTwiMLを戻すためのリクエスト、もう一つはそのFAXが正常に完了したときのリクエストです。
FAXを受信する

ここで、2つのリクエストが必要になるはずです。1つは、みなさんのTwilio番号にFAXが着信した時にTwilioへ指示するためのTwiMLを戻すためのリクエスト、もう一つはそのFAXが正常に完了したときのリクエストです。

開発やテスト中の方は、おそらくこのコードを localhost (LAN内)で動かしているかもしれません。残念ながら、TwilioはみなさんのLAN内にあるホストを直接呼び出すことはできません。このコードをパブリックネットワークからアクセスできるサーバーに配置するか、ngrokのように、インターネットからアクセスできるURLを使ったトンネル通信が可能な手法を取る必要があります。これから、どのようにそれをセットアップするか説明します。

TwilioからLAN内ホストにアクセスを許可する

ngrokをまだインストールされていない方は、ngrok をインストールngrok コマンドをシステムパスに追加します。以下のコマンドは、ngrok に3000番ポートを使ってグローバルから通信できるようにするものです。 3000 をご自身のWebアプリケーションで使いたいポート番号に置き換えてください。

ngrok http 3000

ngrokのターミナル出力

これでパブリックURLが持てました。このURLをご自身のアカウントのコンソールにある電話番号メニューのWebhookに設定します。電話番号を選択し、"A FAX COMES IN" の欄を  https://sadfs3423.ngrok.io/fax/sent のように、ご自身のサービスで使うURLに書き換えます。

FAX用のWebhook設定

Twilio番号へのファックス送信 - ngrokのコンソールに1ペアのHTTPリクエストが確認できるはずです。もし全てがうまくいっていれば、PDFファイルのURLに対するリクエストもロギングされています。

次のステップ

これで FAX送受信 の基本は理解できたと思います。この先は、 REST APIリファレンス をご覧いただければ、より詳しいTwiMLについての情報をはじめ、FAX受信時のHTTPリクエストのライフサイクルについても理解していただけます。Happy faxing!

ヘルプが必要ですか?

誰しもが一度は考える「コーディングって難しい」。そんな時は、お問い合わせフォームから質問してください。 または、Stack Overflow でTwilioタグのついた情報から欲しいものを探してみましょう。

コードサンプルを読み込んでいます...
SDKバージョン:
  • 5.x
SDKバージョン:
  • 7.x
SDKバージョン:
  • 3.x
SDKバージョン:
  • 5.x
SDKバージョン:
  • 6.x
SDKバージョン:
  • 5.x
形式:
  • JSON
// Download the Node helper library from twilio.com/docs/node/install
// These consts are your accountSid and authToken from https://www.twilio.com/console
const accountSid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
const authToken = 'your_auth_token';
const client = require('twilio')(accountSid, authToken);

client.fax.v1.faxes
  .create({
    to: '+15558675310',
    from: '+15017122661',
    mediaUrl: 'https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf',
  })
  .then(response => {
    console.log(response.sid);
  })
  .catch(err => {
    console.log(err);
  });
// Download the twilio-csharp library from twilio.com/docs/libraries/csharp
using System;
using Twilio;
using Twilio.Rest.Fax.V1;
using Twilio.Types;
using System.Collections.Generic;

class Example
{
    static void Main(string[] args)
    {
        // Find your Account Sid and Auth Token at twilio.com/console
        const string accountSid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        const string authToken = "your_auth_token";
        TwilioClient.Init(accountSid, authToken);

        var to = "+15558675310";
        var mediaUrl = new Uri(
            "https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf");

        var fax = FaxResource.Create(to, mediaUrl, from: "+15017122661");

        Console.WriteLine(fax.Sid);
    }
}
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;

// Your Account Sid and Auth Token from twilio.com/console
$sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
$token = "your_auth_token";
$client = new Client($sid, $token);

$options = array(
  "from" => "+15017122661"
);
$fax = $client->fax->v1->faxes->create(
    "+15558675310",
    "https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf",
    $options
);

echo $fax->sid;
require 'net/http'
require 'json'

# Get your Account SID and Auth Token from twilio.com/console
account_sid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
auth_token = 'your_auth_token'

uri = URI('https://fax.twilio.com/v1/Faxes')

Net::HTTP.start(uri.host, uri.port,
                use_ssl: uri.scheme == 'https') do |http|

  request = Net::HTTP::Post.new uri.request_uri
  request.basic_auth account_sid, auth_token
  request.body = URI.encode_www_form(To: '+15558675310',
                                     From: '+15017122661',
                                     MediaUrl: 'https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf')

  response = http.request request

  puts JSON.parse(response.body)['sid']
end
from twilio.rest import Client

# put your own credentials here
account_sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
auth_token = "your_auth_token"

client = Client(account_sid, auth_token)

fax = client.fax.v1.faxes.create(
    from_="+15017122661",
    to="+15558675310",
    media_url="https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf"
)

print(fax.sid)
// Install the Java helper library from twilio.com/docs/libraries/java
import com.twilio.Twilio;
import com.twilio.rest.fax.v1.Fax;
import com.twilio.rest.fax.v1.FaxCreator;
import java.net.URI;
import java.net.URISyntaxException;

public class Example {
    // Find your Account Sid and Token at twilio.com/console
    public static final String ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    public static final String AUTH_TOKEN = "your_auth_token";

    public static void main(String[] args) throws URISyntaxException {
        Twilio.init(ACCOUNT_SID, AUTH_TOKEN);

        String from = "+15017122661";
        String to = "+15558675310";
        URI mediaUrl = new URI("https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf");
        FaxCreator faxCreator = Fax.creator(to, mediaUrl);
        faxCreator.setFrom(from);
        Fax fax = faxCreator.create();

        System.out.println(fax.getSid());
    }
}
curl 'https://fax.twilio.com/v1/Faxes' \
    -X POST \
    -d 'To=%2B15558675309'  \
    -d 'From=%2B15017250604'  \
    -d 'MediaUrl=https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf' \
    -u ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:your_auth_token
{
	"status": "queued",
	"direction": "outbound",
	"from": "+15017122661",
	"date_updated": "2017-04-06T06:39:15Z",
	"price": null,
	"account_sid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
	"to": "+15558675310",
	"date_created": "2017-04-06T06:39:15Z",
	"url": "https://fax.twilio.com/v1/Faxes/FX4ac3612393b5a66f11c73a148f956a5c",
	"sid": "FX4ac3612393b5a66f11c73a148f956a5c",
	"duration": null,
	"num_pages": null,
	"quality": "fine",
	"price_unit": null,
	"api_version": "v1",
	"media_url": null
}
SDKバージョン:
  • 5.x
SDKバージョン:
  • 7.x
SDKバージョン:
  • 5.x
SDKバージョン:
  • 6.x
SDKバージョン:
  • 4.x
require 'rubygems'
require 'sinatra'

# Define a handler for when the fax is initially sent
post '/fax/sent' do
  # Let's manually build some TwiML. We can choose to receive the
  # fax with <Receive>, or reject with <Reject>.
  content_type 'text/xml'

  <<-TWIML
    <Response>
        <Receive action="/fax/received"/>
    </Response>'
    TWIML
end

# Define a handler for when the fax is finished sending to us - if successful,
# We will have a URL to the contents of the fax at this point
post '/fax/received' do
  # log the URL of the PDF received in the fax
  logger.info(params['MediaUrl'])

  # Respond with empty 200/OK to Twilio
  status 200
  body ''
end
using System.Web.Mvc;

namespace TwilioFax.Web.Controllers
{
    public class FaxController : Controller
    {
        // Define a handler for when the fax is initially sent
        [HttpPost]
        public ActionResult Sent()
        {
            // Let's manually build some TwiML. We can choose to receive the
            // fax with <Receive>, or reject with <Reject>.
            const string xmlString = "<Response>" +
                                        "<Receive action =\"/fax/received\"/>" +
                                      "</Response>";

            return this.Content(xmlString, "text/xml");
        }

        // Define a handler for when the fax is finished sending to us - if successful,
        // We will have a URL to the contents of the fax at this point
        [HttpPost]
        public ActionResult Received()
        {
            // log the URL of the PDF received in the fax
            System.Diagnostics.Debug.WriteLine(Request["MediaUrl"]);

            // Respond with empty 200/OK to Twilio
            return new EmptyResult();
        }
    }
}
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class FaxController extends Controller {

    public function __construct()
    {
        parent::__construct();

        // set content-type for all requests returned by this controller
        $this->set_output->set_content_type('text/xml');
    }

    // Define a handler for when the fax is initially sent
    public function sent()
    {
        $twimlResponse = new SimpleXMLElement("<Response></Response>");
        $receiveEl = $twimlResponse->addChild('Receive');
        $receiveEl->addAttribute('action', '/fax/received');

        $this->output->set_output($twimlResponse->asXML());
    }

    // Define a handler for when the fax is finished sending to us - if successful,
    // We will have a URL to the contents of the fax at this point
    public function received()
    {
        // log the URL of the PDF received in the fax
        log_message('info', $this->input->post("MediaUrl"));

        // Respond with empty 200/OK to Twilio
        $this->set_status_header(200);
        $this->output->set_output('');
    }
}
#!/usr/bin/env python
"""Fax snippet."""

from flask.ext.script import Manager
from flask import Flask, Response, request

app = Flask(__name__)


@app.route('/fax/sent', methods=['POST'])
def fax_sent():
    """Define a handler for when the fax is initially sent."""
    # Let's manually build some TwiML. We can choose to receive the
    # fax with <Receive>, or reject with <Reject>.
    twiml = """
        <Response>
            <Receive action="/fax/received"/>
        </Response>
    """

    return Response(twiml, mimetype='text/xml')


@app.route('/fax/received', methods=['POST'])
def fax_received():
    """Define a handler for when the fax finished sending to us."""
    # We will have a URL to the contents of the fax at this point
    # log the URL of the PDF received in the fax
    print(request.form.get('MediaUrl'))

    # Respond with empty 200/OK to Twilio
    return '', 200


if __name__ == "__main__":
    Manager(app).run()
import spark.Route;

import static spark.Spark.post;

public class IndexFax {

    private static Route faxSent = (request, response) -> {
        // Let's manually build some TwiML. We can choose to receive the
        // fax with <Receive>, or reject with <Reject>.
        String twiml = "<Response>" +
                            "<Receive action=\"/fax/received\"/>" +
                        "</Response>";

        // Send Fax twiml response
        response.type("text/xml");
        return twiml;
    };

    // Define a handler for when the fax is finished sending to us - if successful,
    // We will have a URL to the contents of the fax at this point
    private static Route faxReceived  = (request, response) -> {
        // log the URL of the PDF received in the fax
        System.out.println(request.params(":mediaUrl"));

        // Respond with empty 200/OK to Twilio
        response.status(200);
        return null;
    };

    public static void main(String[] args) {
        post("/fax/sent", faxSent);

        post("/fax/received", faxReceived);
    }
}
const http = require('http');
const express = require('express');
const bodyParser = require('body-parser');

const app = express();

// Parse any incoming POST parameters
app.use(bodyParser({ extended: false }));

// Define a handler for when the fax is initially sent
app.post('/fax/sent', (req, res) => {
  // Let's manually build some TwiML. We can choose to receive the
  // fax with <Receive>, or reject with <Reject>.
  const twiml = `
  <Response>
    <Receive action="/fax/received"/>
  </Response>
  `;

  // Send Fax twiml response
  res.type('text/xml');
  res.send(twiml);
});

// Define a handler for when the fax is finished sending to us - if successful,
// We will have a URL to the contents of the fax at this point
app.post('/fax/received', (req, res) => {
  // log the URL of the PDF received in the fax
  console.log(res.body.MediaUrl);

  // Respond with empty 200/OK to Twilio
  res.status(200);
  res.send();
});

// Start the web server
http.createServer(app).listen(3000, () => {
  console.log('Express server listening on port 3000');
});
testable: false