Twilio+slackでfaxを受信する

# 注意事項

https://jp.twilio.com/docs/fax/twiml/receive#action-callback
MediaUrl：`URLは2時間で有効期限が切れることに注意してください。`

# お値段
- Twilio
    - https://www.twilio.com/fax/pricing
- slack
    - https://app.slack.com/plans/T03E2KJ21/?geocode=ja-jp
    - 無料プランもあるハズ

# Slackでやること

1. channelを作る
2. `Incoming Webhook の設定`を参照しながら、Webhook用URLを取得する
    - https://slack.com/intl/ja-jp/help/articles/115005265063-Slack-%E3%81%A7%E3%81%AE-Incoming-Webhook-%E3%81%AE%E5%88%A9%E7%94%A8

# Twilioでやること

※GUIでやったので、所々フワッとしてる

## Functionの作成
### 環境変数の設定
1. メニューから「Functions」を選択
2. Functionsのメニューの「設定」を選択
    - Environment Variablesに以下を設定
       `SLACK_INCOMING_WEBHOOK`:slackのWebhook用URL
3. 「Save」

### Functionの作成
1. Functionsのメニューの「管理」を選択
2. 「＋」マークで新規作成
3. FUNCTION NAME：適当
4. PATH：適当
5. ACCESS CONTROL：`Check for valid Twilio signature`にチェック
6. EVENT：`Select...`
7. CODE：

    ```
    const url = require('url');
    const https = require('https');
    
    exports.handler = function(context, event, callback) {
        const text = `
            FAXを受信しました。
            <${event['MediaUrl']}|here>
            
            From: ${event['From']}
            To: ${event['To']}`.replace(/^\s+/mg, '');
        const message = {
            text: text
        }
    
        const body = JSON.stringify(message);
        const options = url.parse(context.SLACK_INCOMING_WEBHOOK);
        options.method = 'POST';
        options.headers = {
                'Content-Type': 'application/json',
                'Content-Length': Buffer.byteLength(body),
        };
    
        const postReq = https.request(options, (res) => {
                const chunks = [];
                res.setEncoding('utf8');
                res.on('data', (chunk) => chunks.push(chunk));
                res.on('end', (callback) => {
                    var response = {
                        statusCode: 200,
                        headers: {},
                        body: ""
                    };
                    if (res.statusCode >= 400) {
                            response.statusCode = res.statusCode;
                            response.body = `Error posting message to Slack API: ${res.statusCode} - ${res.statusMessage} - ${chunks.join('')}`;
                    }
                    callback(null, response);
                });
                return res;
        });
    
        postReq.on('error', (e) => {
            console.error(`Problem with request: ${e.message}`);
        });

        postReq.write(body);
        postReq.end(callback);
    }
    ```
8. 「Create」
9. 編集画面に戻って、Properties->PATHをCopyしておく

## TwiML Binの作成
1. メニューから「TwiML Bins」を選択
2. 「＋」マークで新規作成
3. TwiML Bin作成画面にて、
    - FRIENDLY NAME：適当。日本語可
    - TWIML：

    ```
    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Receive action="Functionの作成の9.でコピーしたURLをペースト" method="POST"/>
    </Response>
    ```
4. 「Create」

## Programmable Voice

1. メニューから「Phone Numbers」を選択
2. 「＋」マークで電話番号を新規購入
    - COUNTRY：`Japan`
    - 機能：`Fax`にチェック
3. 電話番号から設定画面を開き、必要な設定を行う
    - ACCEPT INCOMING：`Faxes`
    - CONFIGURE WITH：`Webhooks, TwiML Bins, Functions, Studio, or Proxy`
    - A FAX COMES IN：`TwiML Bin`
        - TwiML Binの作成の3.にて設定したFRIENDLY NAMEを選択
4. 「Save」

# 動作確認
1. slackに以下のようなメッセージが投稿されること

    ```
    FAXを受信しました。
    here
    From: +81ぺけぺけ
    To: +8150ぺけぺけ
    ```
2. hereがリンクになっており、FAX内容がPDF参照できること

# 蛇足と言うか、補足
- 肝はTwilioのFunction機能を使うところなので、ここをうまい具合に実装すれば、メール転送するとかストレージにダウンロードするとか、できるのだろう。きっと。
- NTTボイスワープ for FAX
    - http://faq.web116.jp/faq/show/3211?category_id=949
    - 未検証