Extension道場

提供: VoIP-Info.jp
2017年11月18日 (土) 17:52時点におけるSysop (トーク)による版 (「Extension道場」の保護を解除しました)
移動先: 案内検索

頼もう!

extensions.confでタメになる書き方を公開しよう!
ページの編集に慣れていない方はヘルプをみるか、他の人のを真似しましょう。

パターンマッチによるダイアル(行数節約)

サンプル設定ファイルでは各SIPの内線番号をいちいち記述していますが、例えば200~209をSIPに割り当て、それぞれのピア名を200~209にしておけば、extensions.confには以下のように書くだけです。

exten => _20X,1,Dial(SIP/${EXTEN},60,tT)
exten => _20X,2,Answer()
exten => _20X,3,Voicemail(${EXTEN})
exten => _20X,4,Hangup
exten => _20X,102,Answer()
exten => _20X,103,Voicemail(${EXTEN})
exten => _20X,104,Hangup

これで_20Xは200~209にマッチするので、この範囲内のSIPピアに接続できるようになります。 さらにボイスメール録音用の番号も以下のようにすることができます。

exten => _20X*1,1,Answer()
exten => _20X*1,2,Voicemail(${EXTEN:0:3})
exten => _20X*1,3,Hangup

パターンマッチによるダイアル・その2

こんな書き方もできるようです。*1

exten => _200,      1,Dial(${ALL})
exten => _20[1345], 1,Dial(IAX2/${EXTEN})
exten => _20[2678], 1,Dial(SIP/${EXTEN})
exten => _299,      1,MP3Player(...)
exten => _2XX,      2,Hangup1 は個別で、2 は共通。

(小西)

ポップアップ

着信したら、指定した Windows マシン XXXX へポップアップする。

exten => s,1,System(echo "${CALLERID}" | smbclient -M XXXX -U Asterisk)

同様に、指定アドレスにメールをしたり、いろいろと応用できそうです。
ただ、SQL インジェクションと同じことができそうなのは、怖いところです。
(小西)

ISDNでRING

ISDN回線からの着呼、ボイスメールがいきなり出ちゃうと何なので・・・という場合、ZapチャンネルならばWaitすれば鳴りっぱなしになりますがISDN回線ではそうはいきません。着呼に応答してやらないとエラーで話中になってしまいます。そういう場合に使うのがRinging。

exten => 0312345678,1,Ringing()
exten => 0312345678,2,Wait(10)
exten => 0312345678,3,Voicemail(1234)

これでISDN回線側には『着信しないで』Call Progressされます。
(たかはし)

Extensionパターンのマッチ順

ひかり電話と050IP電話が使える状態で、050番号へダイヤルした時だけ050IP電話経由で発信する、ということをしたいなんて時に、

exten => _050.,1....050でDial
exten => _0.,1....ひかり電話でDial

と書いても_0.の方にマッチしてしまい、すべて後者でDialされてしまうと思います。Asteriskは内部で勝手にソートを行うので、必ずしもextensions.confに書いた順ではマッチしないようです。CLIで

show dialplan [コンテクスト名]

とすると当該コンテクスト内でのマッチ適用順が表示されるます。
こういう場合、

exten => _050.,1,...
exten => _050.,2,...
include => ntttel

[ntttel]
exten => _0.,1,...
exten => _0.,2,...

のようにします。つまり、後からマッチさせたい部分を別コンテクストに書き出し、それをメインのコンテクストでincludeするワケです。こうするとincludeした部分の優先順位が下がるようです。試した感じではincludeの位置はどこでも良さそうです。また複数includeした場合はその順になると書かれていました。
(古田@道具眼)

ダイアル先による分岐

ダイアルする電話番号によって使う基盤や回線を切り替えたい場合のアイデアのひとつです。
TO_DIALにダイアル先をセットしてジャンプさせます。

exten => 9500,1,GotoIf($[${TO_DIAL::2} = 03]?9600,1)
exten => 9500,2,GotoIf($[${TO_DIAL::3} = 050]?9600,1)
exten => 9500,3,GotoIf($[${TO_DIAL::4} = 0120]?9600,1)
exten => 9500,4,Goto(9700,1)

exten => 9600,1,... アナログ回線で発信

exten => 9700,1,... VoIP回線で発信

Asterisk 1.x系では上記の方法で動くのですが、1.2系になると効かなくなりました。どうも::2という省略時解釈が使えないようで、以下のように記述すると1.x系でも1.2系でも動作します。

exten => 9500,1,GotoIf($[${TO_DIAL:0:2} = 03]?9600,1)
exten => 9500,2,GotoIf($[${TO_DIAL:0:3} = 050]?9600,1)
exten => 9500,3,GotoIf($[${TO_DIAL:0:4} = 0120]?9600,1)
exten => 9500,4,Goto(9700,1)

exten => 9600,1,... アナログ回線で発信

exten => 9700,1,... VoIP回線で発信

extensionsの優先順位でよくわからなくなった場合に、明示的に自分で処理するので、わかりやすいです。AELで書けばもっと簡単に処理できるはず(?)です。
(たかはし)

Asterisk 1.2での便利な記述方法

Asterisk 1.2系ではextensions.confのプライオリティを自動インクリメントする機能があります。またラベルも使用できます(質問があったので追加)。

exten => 201,1,Dial(SIP/201)
exten => 201,n,Goto(test)
exten => 201,n,NoOp
exten => 201,n,NoOp
exten => 201,n(test),NoOp
exten => 201,n,NoOp

この例は次のように展開されます。

*CLI> show dialplan
[ Context 'default' created by 'pbx_config' ]
  '201' =>          1. Dial(SIP/201)                              [pbx_config]
                    2. Goto(test)                                 [pbx_config]
                    3. NoOp()                                     [pbx_config]
                    4. NoOp()                                     [pbx_config]
     [test]         5. NoOp()                                     [pbx_config]
                    6. NoOp()                                     [pbx_config]

この方法を使えば途中に行を挿入してもプライオリティをいちいち書き直す必要はありません。

簡単IVR

ラウンジで公開をお約束したもの。一旦Asteriskで受けておいて内線番号をダイアルすると、その番号に繋ぐのは以下の例のようにしてできます。
Asterisk 1.0と1.2の最初の方では以下で動作したのですが・・・

[some-context]

exten => s,1,Answer()
exten => s,2,wait(1)
exten => s,n,Set(LANGUAGE()=jp)
exten => s,n,Playback(silence/1)
exten => s,n,ResponseTimeout(30)
exten => s,n,Background(vm-enter-num-to-call)
exten => s,n,Background(silence/10)
exten => s,n,Background(silence/10)
exten => s,n,Goto(s,2)

exten => t,1,HangUp

exten => i,1,Playback(pbx-invalid)
exten => i,2,Goto(s,2)

exten => 201,1,Dial(SIP/201)

exten => 202,1,Dial(SIP/202)

Asterisk 1.2後期からは以下を使用してください。

[some-context]

exten => s,1,Answer()
exten => s,2,wait(1)
exten => s,n,Set(LANGUAGE()=jp)
exten => s,n,ResponseTimeout(30)
exten => s,n,Background(vm-enter-num-to-call)
exten => s,n,WaitExten(20)
exten => s,n,Goto(s,2)

exten => t,1,HangUp

exten => i,1,Playback(pbx-invalid)
exten => i,2,Goto(s,2)

exten => 201,1,Dial(SIP/201)

exten => 202,1,Dial(SIP/202)

この例では201または202がダイアルされると、それぞれextenの201と202が実行されます。

パターンマッチの罠に注意

_0.などで0番プレフィックスを指定したつもりでも、GoToを使うと番号が途中で置換されてしまうので注意します。

exten => _0.,1,Set(CALLERID(num)=03xxxxxxxx)
exten => _0.,n,Set(CALLERID(name)=03xxxxxxxx)
exten => _0.,n,NoOp(${EXTEN})
exten => _0.,n,GoTo(,_0.,200)

exten => _0.,200,NoOp(${EXTEN})

こんな感じでextensionsを書いた場合、GoToで同一extenの別プライオリティに飛ばすと、次のような結果になります。

-- Executing Set("SIP/201-09c8a168", "CALLERID(num)=03xxxxxxxx") in new stack
-- Executing Set("SIP/201-09c8a168", "CALLERID(name)=03xxxxxxxx") in new stack
-- Executing NoOp("SIP/201-09c8a168", "0312345678") in new stack  <---これが
-- Executing Goto("SIP/201-09c8a168", "|_0.|200") in new stack
-- Goto (default,_0.,200)
-- Executing NoOp("SIP/201-09c8a168", "_0.") in new stack         <---こうなる

CALLERIDをチェックしてダイアルアウトさせるかどうかを分岐させたい場合に注意しましょう。このような場合にはダイアルアウト先の番号を一旦、変数にセットしておいてからGoToすると解決できます。