2017年7月6日木曜日

Raspberry Pi 3へAsteriskを構築する -- その3

前回までに、Asteriskインストールと sip.conf について書いてきました。

今回からは、実際の「振る舞い」を記述する、extensions.conf について書いてみたいと思います。

が、その前に留守電を使うための準備をします。
というのも、extensions.conf の実際例の中ではこの留守電を使うからです。

着信があったときに、一定時間内(例えば 30s)に応答しなければ、留守電にする、と言うものです。

留守電は、簡易な方法で擬似的に実現した事例が下記サイトにあります。

  http://blog.jikoman.jp/2015/05/asterisk-rusuden.html

ここでは Asteriskの機能を使用した留守電機能を構築するやり方を記述します。

また、録音された留守電をメールに添付してお知らせしてくれるようにもしたいと思います。
お知らせメールはなくてもいいのですが、留守電が入ったときに知らせてくれますから、ときどき留守電をチェックする、などとしなくてすみます。

そのために、メーラーをAsteriskにプラグインして設定をする必要があります。

メール送信パッケージをインストールします。

  # apt-get update
  # apt-get install ssmtp mailutils

次に ssmtp を設定します。

  #  leafpad /etc/ssmtp/ssmtp.conf ➡  以下をオリジナルと書き換える
   root=メールアドレス(例えば、abcdefgh@gmail.com など)
   Mailhub=smtp.gmail.com:587 ➡ 送信用ドメインのアドレス/ポート
   AuthUser=メールアカウントabcdefghです)
   AuthPass=パスワード ➡ メールパスワード
              (記号が含まれると認証エラーになる)
   AuthMethod=LOGIN
   UseSTARTTLS=Yes
   UseTLS=Yes
   hostname=gmail.com  ➡ ‘localhost’ では hylafax で DNS エラーになる

続いて asterisk.conf  を編集します。以下の箇所を変更します。

  # leafpad /etc/asterisk/asterisk.conf
   languageprefix=yes
   defaultlangeage=ja
  # 

voicemail.conf を編集します。

  # leafpad /etc/asterisk/voicemail.conf 
   [general]
   format=wav49         ; wav形式で録音
   servermail=asterisk  ; メール送信者名
   attach=yes
   maxmsg=999 ; 最大保存メッセージ
   maxsecs=180 ; 最大メッセージ長(録音時間:秒)
   skipms=3000 ; デフォルトのまま
   maxsolence=10 ; 最大無音許容時間
             (この時間内(s)に録音されなければ切断)
   silencethreshold=128 ; 無音検出のスレッショルド
   maxlogins=3 ; 最大ログイン数
   charset=UTF-8 ; 日本語メールのための文字セットをUTF-8にする
   emailsubject=[PBX]: 音声メールボックス: ${VM_MAILBOX} の $ {VM_MSGNUM} 番に新しいメッセージです
    ; メールの題名
   emailbody=電 話 番 号: ${VM_CALLERID}¥n¥nメッセージ長: ${VM_MSGNUM} 秒\n¥n${VM_DATE}¥n¥n¥t¥t--- by Asterisk Server   
   emaildateformat=着 信 日 時: %Y/%m/%d, %r 
   mailcmd=/usr/sbin/sendmail -t ; コメントアウトを外す(sendmailを指定)
   saycid=yes
   sendvoicemail=yes
   [zonemessages]
   japan=Japan|Q PHM ‘jp-ni’ ‘vm-received’
   [default]
   500 => 1111,名前,アカウント名@gmail.com,,tz=japan   ; メッセージを再生するときのパスワード、送信先名前、送信先メールアドレス、タイムゾーン
  #

留守電を記述するには、extensions.conf のエクステンションに Voicemail アプリケーションを記述します。

   exten => 250,n,Voicemail(500) ; 500番のボイスメールボックスに録音する

のように記述します。

また、再生するには VoiceMailMain アプリケーションを使います。

   exten => 260,n,VoiceMailMain(500,s) ; 500番のボイスメールボックスを再生する
  (ボックス番号の後ろの"s"は再生時にパスワード要求しない、の意味です)

   留守録されると、abcdefgh@gmail.com に留守録が添付されてメール送信される。
   また、「260」を呼び出すと、留守電の確認が音声応答でできる。
   (留守電ボックス番号は「500#」、パスワードは「1111#」)。

   留守電内容を「内線260」で確認するときのダイヤル数字のそれぞれの意味

    1: メッセージ聴取
    2: フォルダの変更
     0: 新規メッセージフォルダ
     1: 聴取済みメッセージフォルダ
     2: ワークメッセージフォルダ
     3: 家族メッセージフォルダ
     4: 友人メッセージフォルダ
     #: キャンセル
    3: アドバンスオプション
     1: 返信
     3: 録音メッセージの再生
     5: 録音
     *: メインメニューに戻る
    4: 前のメッセージを再生
    5: 現在のメッセージを繰り返す
    6: 次のメッセージを再生
    7: 現在のメッセージを削除
    8: 他のメールボックスに転送
    9: 他のフォルダに移動
    0: メールボックスオプション
     1: 不在時(呼出タイムアウトや電源未投入等)等の応答メッセージの録音
     2: 話中時の応答メッセージの録音
     3: ユーザ名の録音
     4: パスワードの変更
     *: メインメニューに戻る
    *: ヘルプ/再生中は巻き戻し
    #: 終了/再生中は早送り


実際の extensions.conf の事例を下記に示します。
コメントが記載されていますので、大体はご理解いただけると思います。

extensions.conf

[general]
autofallthrough=yes
writeprotect=no
;
;【ダイヤルプラン】
;    1. ひかり電話の外線着信で、Asterisk内線 11,12 が鳴動
;        ブラステル1 からの着信は設定要求で、次のように設定応答する
;            "#" 設定キャンセル : 設定し直さない => 何もしないで切断
;            "1" 応答          : ブラステル1 への転送設定
;            "7" 応答          : 留守電設定
;        ブラステル1 以外からの着信は、転送または内線鳴動&留守電
;    2. Asterisk内線 99 呼び出しは全員呼び出し
;    3. Asterisk内線から Asterisk内線の相互呼び出しができる
;    4. Asterisk内線から外線発信は 固定電話 (今は、ひかり電話経由で)
;        国内固定、国内携帯、フリーダイヤル、サービス番号(110, 119, 117, 104 など)
;        への発信ができる (海外発信はできない)
;    5. Asterisk内線から 100 を呼び出すと、音声追っかけ再生テストができる
;    6. ブラステル3への着信時は、内線(21--24)を入力してもらい、その番号を呼び出す
; いわゆるダイヤルイン操作。
;        21--24 の番号所有者へは、案内に従い内線(21--24) を入力してもらい、
;        指定のそれぞれの番号につなぐ。つながらないときは留守電Box:500番に録音する
;    7. 音声テスト : 内線で 100番を呼び出すと、話した内容をオウム返しに返してくれる
;    8. FAX送信はブラステル1 から行い、受信はfusionに行う
;       内線 4番への FAX は、スマホの「ひかりFAX」への送信となる
;       これはFAX送受信テストに使う (ブラステル1送信→スマホ、スマホから送信→fusion)
;
; パターンマッチングの意味
;   _1[1-3]  は    11,12,13
;             または [123]     と同じ
;   _1X       は    10--19   と同じ
;   _1Z       は    11--19   と同じ
;   _1N       は    12--19   と同じ
;   _1.        は    1XXX...XXX (X:0〜9,任意の桁数)
;
[globals]
MYNUMBER=0412345678           ; ひかり電話の番号
BRASTELNUMBER1=05023456789    ; brastel-hの番号
BRASTELNUMBER2=05034567890    ; brastel-mの番号 (現在、未設定)
BRASTELNUMBER3=05045678901    ; brastel-zの番号
FUSIONNUMBER=05056789012         ; fusionの番号
;
USEVOICEMAIL=YES
;
[default]
;**** 子機 11--12, 21--24 の呼び出し定義 (内線相互呼び出し)
exten => _1[1-2],1,Dial(SIP/${EXTEN},30)
exten => _1[1-2],n,Hangup()
;
exten => _2[1-4],1,Dial(SIP/${EXTEN},30)
exten => _2[1-4],n,Hangup()

; ボイスメールの再生 (留守電Box: 500番)
;
exten => 20,1,Goto(vm1,1)

exten => vm1,1,Answer()
exten => vm1,n,VoiceMailMain(500,s) ; sオプション : 再生時パスワード要求なし          
exten => vm1,n,Hangup() 
;
;exten => vm1,n,VoiceMailMain(${CALLERID(num)},s) ; 呼び出し番号別のボイスメール録音の場合(未使用)
;
;
;**** 全員呼び出し(30秒間呼び出す)
exten => 99,1,Dial(SIP/11&SIP/12&SIP/21&SIP/22&SIP/23&SIP/24,30)
exten => 99,n,Hangup()
;
;**** 音声再生テスト : コールすると話した内容が、追っかけ再生される
;
exten => 100,1,Answer()
exten => 100,n,Wait(1)
exten => 100,n,Playback(demo-echotest)
exten => 100,n,Playback(beep)
exten => 100,n,Echo
exten => 100,n,Playback(hello-world)
exten => 100,n,Hangup()
;
;;;
;**** ひかり電話への着信
; 発信元番号がブラステル1なら、400 に飛び、処理コード要求する
;     "#"入力時 : 設定キャンセル (設定し直さない => 何もしないで切断)
;     "1"入力時 : 転送モード設定
;     "7"入力時 : 転送モード解除 (留守電設定)
;
; 発信元番号がブラステル1以外なら処理コードに従い、転送または留守電になる

; 留守電モードのとき、留守電に入る前に30秒、子機 #11, #12が鳴動
; いずれの子機もアクティブでないときは、すぐに留守電モードになる
;
; "TRSW"は、Asteriskプロセスの環境変数 ENV(TRSW)として使用
;   環境変数に転送モード ("1")、留守電モード ("7") を外部変数扱いで設定
;   Asteriskは、呼を処理するたびに grobal変数は初期設定値に戻るため、
;   呼と呼の間で有効な外部変数が必要だった (一晩、徹夜で考えた)
;
exten => 200,1,NoOp(${CALLERID(num)})
exten => 200,n,GotoIf($[${CALLERID(num)} = ${BRASTELNUMBER1}]?400,1) ; ブラステル1 からの着信か? -->> 400

exten => 200,n,NoOp(ENV(TRSW))

exten => 200,n,GotoIf($[ENV(TRSW) =1]?300,1)   ; ブラステル1への転送か -->> 300

exten => 200,n(call-in),Dial(SIP/11&SIP/12,30) ; 子機 #11, #12鳴動
; 30秒間の子機呼び出しで無応答、またはいずれの子機もデアクティベーションのときは即時に留守電
;**** 留守電モードのとき
exten => 200,n(rec-voice),Answer() ; 着信に応答
exten => 200,n,Wait(1)                 ; 無音1秒でコーデック安定を待つ
exten => 200,n,Playback(vm-nobodyavail) ;「ただいま電話にでることができません」
exten => 200,n,Wait(1)                 ; 1秒待つ
exten => 200,n,Voicemail(500)      ; Voicemailには"vm-intro&beep"が含まれている
exten => 200,n,Hangup()              ;  「発信音の後にメッセージをお話しください。
;                                                  ;    終わりましたら電話を切るかシャープを押してください。ピーッ!」
;**** 転送モードのとき
; ブラステル3 経由でブラステル1に転送
exten => 300,1,NoOp(${CALLERID(num)})   ; デバッグ用に呼び出し元番号をCLIに表示 (CLIはAsteriskのコマンドラインインターフェース/コンソール)
exten => 300,n,NoOp(${CALLERID(name)})  ; デバッグ用に呼び出し元名前をCLIに表示
exten => 300,n,Dial(SIP/${BRASTELNUMBER1}@brastel-z,30,tT)  ; tT is "rtp via server ( rtp.conf | [general] | rtpstart=10000 | rtpend=10009 )" 訂正
exten => 300,n,Goto(200,rec-voice)             ; 呼び出し無応答は留守電
;
;**** 処理コード要求のとき : ブラステル1からの呼び出し時のみ
;
exten => 400,1,Playback(silence/1)    ; 無音1秒でコーデック安定を待つ
exten => 400,n,Set(TIMEOUT(digit)=5)
exten => 400,n,Set(TIMEOUT(response)=10)
exten => 400,n(retry-exten),Playback(tennsou-rusuden-no-settei) ;「転送は1を、留守電は7を、以前の設定のままは#を押してください」
exten => 400,n,Wait(1)                      ;
exten => 400,n,Playback(beep)          ;「ピーッ!」
exten => 400,n,Set(TRSWVAR="")      ; TRSWVAR: ローカル変数
exten => 400,n,Read(TRSWVAR,,1)    ; 1桁の番号が入力されたら、"#"なしに受け取る
exten => 400,n,GotoIf($[${LEN(${TRSWVAR})}= 0]?${EXTEN},noset-exten) ; "#" -->> no-set
exten => 400,n,GotoIf($[${TRSWVAR}= 7]?${EXTEN},reset-exten)  ; "7" -->> reset
exten => 400,n,GotoIf($[${TRSWVAR}= 1]?${EXTEN},set-exten)  ; "1" -->> set
exten => 400,n,Playback(number&jp-ga&disabled-2)  ;「番号が無効です」
exten => 400,n,Goto(retry-exten)

exten => 400,n(reset-exten),NoOp(${TRSWVAR})
exten => 400,n,Set(ENV(TRSW)=7)
exten => 400,n,Playback(rusuden-ni-settei)             ;「留守電に設定しました」
exten => 400,n,Wait(1)
exten => 400,n,Goto(exit-exten)

exten => 400,n(set-exten),NoOp(${TRSWVAR})
exten => 400,n,Set(ENV(TRSW)=1)
exten => 400,n,Playback(tennsou-ni-settei)              ;「転送に設定しました」
exten => 400,n,Wait(1)
exten => 400,n,Goto(exit-exten)

exten => 400,n(noset-exten),Wait(1)
exten => 400,n,GotoIf($[${ENV(TRSW)}= 7]?${EXTEN},pre-exit)
exten => 400,n,Playback(misettei-tennsou)  ;「設定は変更されません。現在の設定は転送です」
exten => 400,n,Goto(exit-exten)
exten => 400,n(pre-exit),Playback(misettei-rusuden) ;「設定は変更されません。現在の設定は留守電です」

exten => 400,n(exit-exten),Wait(1)
exten => 400,n,Playback(thanks)  ;「ご利用ありがとうございました」
exten => 400,n,NoOp(${ENV(TRSW)})  ; デバッグ用に環境変数(TRSW)の結果内容をCLIに表示
exten => 400,n,Hangup();

;
;**** ひかり電話からの発信
; +++ 10 桁, フリーダイヤルの 11 桁の形式が一致したら発信OK
; +++ 00 発信 (国際電話発信) 不可

exten => _0ZZX.,1,Set(CALLERID(num)=${MYNUMBER})
exten => _0ZZX.,n,Set(CALLERID(name)=${MYNUMBER})
exten => _0ZZX.,n,Dial(SIP/${EXTEN}@hikari-denwa)
exten => _0ZZX.,n,Hangup()
;
; +++ 携帯電話 (スマホ含む) の 11 桁の形式が一致したら発信OK

exten => _0N0X.,1,Set(CALLERID(num)=${MYNUMBER})
exten => _0N0X.,n,Set(CALLERID(name)=${MYNUMBER})
exten => _0N0X.,n,Dial(SIP/${EXTEN}@hikari-denwa)
exten => _0N0X.,n,Hangup()
;
; +++ 1 から始まる 3 桁番号 (警察、消防、時報など NTTのサービスダイヤルなどの形式

exten => _1XX,1,Set(CALLERID(num)=${MYNUMBER})
exten => _1XX,n,Set(CALLERID(name)=${MYNUMBER})
exten => _1XX,n,Dial(SIP/${EXTEN}@hikari-denwa)
exten => _1XX,n,Hangup()
; ***********************************************************************************
; これら以外の番号形式 (例えば海外発信) の発信は Asterisk の内線からはできない
; 海外発信は、ひかり電話本体から行う
; ***********************************************************************************
;
;
;;;;
;; ブラステル3 ダイヤルイン (21--24 振り分け)
;;
;[brastel-z]
exten => 440,1,Set(CNT=1)
exten => 440,n,Set(WHTDIAL=999)
exten => 440,n,Playback(silence/1)   ; 無音1秒でコーデック安定を待つ
exten => 440,n,Set(TIMEOUT(digit)=5)
exten => 440,n,Set(TIMEOUT(response)=10)
exten => 440,n(call-retry),Playback(yobidashitai-bangou) ;「呼び出したい人の内線番号を入力してください」
;                           ;「内線番号は、21がAさん、22がBさん、23がCさん、24がDさん、です」
exten => 440,n,Playback(beep)
exten => 440,n,Read(WHTDIAL,,2)  ; 2桁の番号が入力されたら、"#"なしに受け取る;
exten => 440,n,GotoIf($[${WHTDIAL}=999]?440,err-retry) ; 番号が 999 ならTimeout to Read
exten => 440,n,GotoIf($[${WHTDIAL}= 21]?${WHTDIAL},1)
exten => 440,n,GotoIf($[${WHTDIAL}= 22]?${WHTDIAL},1)
exten => 440,n,GotoIf($[${WHTDIAL}= 23]?${WHTDIAL},1)
exten => 440,n,GotoIf($[${WHTDIAL}= 24]?${WHTDIAL},1)
exten => 440,n(err-retry),GotoIf($[${CNT} > 1]?440,call-invalid)
exten => 440,n,Set(CNT=2)
exten => 440,n,Playback(mukou-bangou)  ;「この番号は無効です」
exten => 440,n,Wait(1)
exten => 440,n,Set(WHTDIAL=999)
exten => 440,n,Goto(440,call-retry)
exten => 440,n(call-invalid),Playback(mukou-bangou)  ;「この番号は無効です」
exten => 440,n,Playback(matigai-rusuden)  ;「内線番号を間違えていますので、留守電にします」
exten => 440,n,Voicemail(500)   ; 2回間違ったらVoicemail
exten => 440,n,Hangup()
;
;;;;
;
;**** FAX受信 : Fusion
;[fusion-fax-in]

exten => 56789012,1,Ringing
exten => 56789012,n,Answer()
exten => 56789012,n,Wait(5)
exten => 56789012,n,Dial(IAX2/iaxmodem)
exten => 56789012,n,Hangup()
;
;
;**** FAX発信 : brastel-h電話 in use
[fax-out]

exten => _0ZZX.,1,Set(CALLERID(num)=${BRASTELNUMBER1})
exten => _0ZZX.,n,Set(CALLERID(name)=${BRASTELNUMBER1})
exten => _0ZZX.,n,Dial(SIP/${EXTEN}@brastel-h)
exten => _0ZZX.,n,Hangup()
;
;
;**** FAXテスト...  ひかり電話から スマホ (内線-4)

exten => _X,1,Set(CALLERID(num)=${MYNUMBER})
exten => _X,n,Set(CALLERID(name)=${MYNUMBER})
exten => _X,n,Dial(SIP/${EXTEN}@hikari-denwa)
exten => _X,n,Hangup()
;
;::: end of extensions ::::

いかがでしょうか。

内線設定したスマホ子機からは、国際電話発信はできないようになっています。
国際電話をかける際は、ひかり電話機か、ブラステル電話機か、ブラステル設定のスマホからのいずれかになります。いまはブラステルも国際電話発信不可の設定です。

結局、フランスの娘一家には LINE で通話もしくはメッセージングしています。

我が家では、FAXも送受信できるように設定してあります。

また、転送時は発信元の電番が転送先に伝わるようにしてあります。
普通に転送だと、転送をリレーした電番(上の例ではブラステル3)が転送先に表示されます。

これらの設定は、extensions.conf だけでは実現できません。

FAXは、IAXmodem、Hylafaxというパッケージをプラグインし、設定する必要があります。
また、PCから送受信できるUIのプログラムも必要です。
(ブラステルでFAX送信の場合は、T.38パススルーの設定も必要です)

転送時の発番を転送先に表示するには、sip.conf への追記が必要です。

電話での応答に使う音声ファイルは、あらかじめ Asteriskにも用意されていますが、いくつかは、適切な音声ファイルがなかったので、作成しました。

作成方法は、次の機会にでも。


》Asterisk構築・終わり

ご質問等は、コメントください。わかる範囲でお応えします。


【修 正】
2017-07-09 転送時、ブラステル1が呼び出しに応じられないときは留守電に設定変更

























3 件のコメント:

  1. asteriskで検索し、拝見しました。参考にさせて頂き、voicemailはうまくいったのですが、iaxmodemとhylafaxの設定が悪いのか、FAXがうまく動いてくれなくて、iaxmodemとhylafaxの導入と設定方法もご教示頂けますでしょうか。よろしくお願いします。

    返信削除
    返信
    1. 高橋さま、voicemail まではうまくいったようでよかったです。iaxmodemとhylafaxの手順は結構複雑ですので、t2.tsuka@gmail.com あてにメールアドレスをご連絡いただけますでしょうか。
      メールに添付ファイルしてお送りしたいと思いますので。

      削除
    2. ご対応ありがとうございます。
      ご連絡させていただきます。

      削除