Open11

令和にもなって VoIP 電話網を作ろうとしているお前らへ

ピン留めされたアイテム
KusaReMKNKusaReMKN

注意

このスクラップの内容は、後に修正・更新されて記事として投稿されるかもしれません。

投稿者へのお願い

このスクラップの内容を記事にする場合、元となったスクラップの投稿を削除しないでください。 該当するスクラップの冒頭部分に message 構文で記事として公開された旨を記述し、スクラップのうち記事として公開された部分を details 構文で折り畳むか、あるいはスクラップそのものを非表示にしてください。 元の投稿を削除した場合、その投稿を参照していた読者がいた場合に混乱を招きます。

<!-- 以下を追加する -->
:::message
このスクラップは記事[○○の解説](https://example.com/hogehoge)として公開されました。
:::

<!-- details で折り畳むには以下のように記述する -->
:::details もともとのスクラップの内容
<!-- ここにスクラップの内容 -->
:::
Hidden comment
yudeyude

カンファレンスルームや Echo-back service などを外線から受け付けられるようにする

  • カンファレンスルームについては、作成時に内線番号 / 直通番号 (DID) を割り当てるため、着信ルールでこれを受け付けるようにします。

  • Echo-back service などのアプリケーションを受け付けるには、着信ルールでどの内線番号 / 直通番号 (DID) を受け取ったらそのアプリケーションへルーティングするかを定義します。

優先度設定において、上記の例外的な番号をまずフィルターするようにし、最後に、リアルな宛先 (ユーザー) が存在する内線番号 / 直通番号 (DID) へルーティングするようにします。
KusaReMKN 氏の環境では、直通番号へルーティングするためのルールを新しく作成していますが、以下のように「着信デフォルトルート」として定義することもできます。

Hidden comment
KusaReMKNKusaReMKN

Linux 用 FAX ユーティリティ

ハードウェアモデムなどが接続されている場合、efax が便利です。GUI のフロントエンドを持つ efax-gtk はもっと便利です。これは USB モデムの上で動作することを確認しました。シリアルケーブル越しの物理外付けモデムではうまく動かないようです(たぶんコマンドが異なる?)

Hidden comment
Hidden comment
Hidden comment
yudeyude

Discord の音声チャンネルと MikoPBX (Asterisk) のカンファレンスをブリッジする

用意するもの

  • Microsoft Windows の VM
    • 検証環境では Proxmox VE 上に Windows の VM を用意しています
  • MikoPBX
    • ブリッジに使用するカンファレンス
    • ブリッジに使用する内線番号 (内線アカウント)
  • あなたが管理者権限を持っている Discord サーバ
    • このブリッジに使用する音声チャンネルを事前に作成してください
  • Discord ボットのトークン
    • https://discord.com/developers から取得できます
    • Discord ボットは、ブリッジに使用する音声チャンネルが作成されている Discord サーバに参加させてください

手順

  1. Windows に以下のアプリケーションをインストールします

VB-Audio Virtual Audio Cable, VB-Audio VoiceMeeter 両方のインストールが完了したら、一度 Windows を再起動してください。

  1. Discord Audio Stream Bot を設定する

Discord Audio Stream Bot は、Windows のサウンド デバイスを介して他のアプリケーションと音声を送受信し、Discord の音声チャンネルにブリッジするものです。

  • Settings タブ
    • General
      • Bot token: Discord から取得したボットのトークンを入力します
      • Auto login: オン
    • Audio
      • Mute/Unmute: マイクとスピーカーが、どちらもミュートされていない状態にします。
      • Input device: VoiceMeeter Output (VB-Audio Vo
      • Output device: CABLE Input (VB-Audio Virtual Cable)
    • Voice activity: オフ
    • Speak threshold: 変更しない (この値は使用されない)
  1. MicroSIP を設定する

MicroSIP は、Windows 向け SIP (VoIP) クライアント アプリケーションです。

  • 設定
    • スピーカー: VoiceMeeter Input (VB-Audio Voi
    • マイク: Cable Output (VB-Audio Virtual
    • システム起動時に実行: オン
  • アカウントの追加
    • アカウント名: ブリッジに使用する内線番号 (内線アカウント)
    • SIP サーバ: MikoPBX の IP アドレス / ホスト名
    • ユーザ名: ブリッジに使用する内線番号 (内線アカウント)
    • ドメイン: MikoPBX の IP アドレス / ホスト名
    • ログイン: ブリッジに使用する内線番号 (内線アカウント)
    • パスワード: ブリッジに使用する内線番号 (内線アカウント) のパスワード
  1. MikoPBX からカンファレンスの番号をコールする
  2. Discord Audio Stream Bot を起動する
    • Home タブの 電源 ボタンを押下する。
    • Discord サーバ内で、以下のボット コマンドを実行する
      • /autojoin <op: set> <channel: ブリッジに使用する音声チャンネル>
      • /join <channel: ブリッジに使用する音声チャンネル> <public: True>
JiminyJiminy

DIALSの卵

DIALS

概要

このダイアルプランアプリケーションのコードは、MikoPBX環境で通話中にユーザーが入力したDTMF(プッシュボタンの数字)を受け取り、「**#」が押されたら終了し、入力内容を一桁ずつ音声で再生する処理を行います。音声が再生されない場合は、MikoPBX環境にて音声ファイルが適切に配置されているか確認してください。

コード

<?php
    require_once 'Globals.php';
    
    use \MikoPBX\Core\Asterisk\AGI;
    $agi = new AGI();
    
    $agi->answer();
    
    $agi->exec('Playback', 'beep');

    // DTMF入力を待機(タイムアウト: 10秒)
    $digits = '';
    $end_sequence = '**#'; // 終了シーケンス
    $end_sequence_length = strlen($end_sequence);
    while (true) {
        $result = $agi->wait_for_digit(-1); // -1 無制限に繰り返し
        if ($result['result'] == -1) {
            // タイムアウトまたはエラー
            $agi->verbose("エラーが発生");
            break;
        } else {
            // 入力されたキーASCIIで取得
            $digit = chr($result['result']);
            $agi->verbose("押したキー: $digits");
            
            // 入力されたキーを保存
            $digits .= $digit;
            
            // 保存された入力が終了シーケンスで終わるか確認
            if (substr($digits, -$end_sequence_length) === $end_sequence) {
                $agi->verbose("終了シーケンス '$end_sequence' が入力されました。");
                // 終了シーケンスが入力された場合、ループを終了
                break;
            }
        }
    }
    
    // 入力されたDTMF全体をログに記録
    $agi->verbose("DTMF: $digits");   
    
    // ここに計算するようにしてほしいな
    // もし、外部のコードを実行するなら
    // $agi->exec("AGI", '外部コードパス,$digits');
    // でできるはず(わからない時は聞いて一緒に考えるよ)。

    // 入力された各DTMFを一桁ずつ再生
    for ($i = 0; $i < strlen($digits); $i++) {
        $digit = $digits[$i];
        if ($digit == '#') {
            $agi->exec("Playback", 'digits/pound');
        } elseif ($digit == '*') {
            $agi->exec("Playback", 'digits/star');
        } else {
            $agi->exec('SayNumber', $digit);
        }
    }
    
    // 通話を終了
    $agi->hangup();
?>

その他

MikoPBX環境では、デフォルトで「**」が内部転送の処理呼び出しに使用されています。そのため、「**#」と競合し、終了操作を行おうとすると転送が実行されてしまいます。この問題を回避するためには、MikoPBXの設定を変更する必要があります。WEB UIの「General settings」にある「Call Transfers」セクションで、以下の2つの設定を変更してください。(これ以外もあるかもしれません)

  • 「This key combination activates an attended transfer」(アテンド転送を起動するキー)
  • 「This key combination activates a blind transfer」(ブラインド転送を起動するキー)

設定例として、「####」や「##**」などのキー組み合わせを指定できます。以下に設定画面の例を示します。

参考

https://docs.asterisk.org/Asterisk_18_Documentation/API_Documentation/AGI_Commands/wait_for_digit/