目地:根據不同Caller ID(來電顯示) 給予不同的 IVR 語音
Caller ID(來電顯示,大陸稱為主叫號碼) 下文簡稱 CID
使用 asterisk 內建語言 AGI 寫一個 shell script 來根據不同的 CID 而給予不同的 IVR
首先是在 dial plan 裡要做如此的設定
vim /etc/asterisk/extensions.conf
[my-phones]
;若需改cid 號碼可參考底下這行
;exten => s,1,Set(CALLERID(num)=12345678)
exten => s,1,Answer
exten => s,2,AGI(cid.sh,${CALLERID(number)})
exten => s,3,Noop(RESULT ${ACTION})
exten => s,4,GotoIf($[ "${ACTION}" = "IVR" ]?ivr-6,s,1)
;若頻道變數為 CALLBACK 則執行回撥功能
exten => s,5,GotoIf($[ "${ACTION}" = "CALLBACK" ]?8)
;若頻道變數為 GOOUT 則去 ivr-7
exten => s,6,GotoIf($[ "${ACTION}" = "GOOUT" ]?ivr-7,s,1)
exten => s,7,Noop(RESULT ${ACTION})
exten => s,8,System(/var/lib/asterisk/bin/callbacknew1 ${NUM} ivr-6.s.1 10 ${NUM} &)
exten => s,n,Hangup()
dial plan 簡要說明:根據頻道變數 ${ACTION} 的結果,送至不同的IVR或執行回撥功能
接下來我們要寫一個 cid.sh 來做 CID 的判斷
由於上方的 dial plan 在呼叫 cid.sh 時,後方有帶一個參數,此參數為 CID 的號碼
#!/bin/bash
#檢查 來電顯示 是否有在檔案清單之中,主要比對 /tmp 底下的 .txt 檔
#本檔使用語法: cid.sh 電話號碼
#AGI指令: set variable 語法: set variable 變數名稱 "變數數值"
#由於它本身的語法就帶有"雙引號了,所以 echo 在使用它時,必須在雙引號前加 \" 倒斜線符號來規避此特殊字元
CID="$1"
if grep $CID /tmp/Caller.txt ; then
#找到資料給予變數 IVR
echo "set variable ACTION \"IVR\""
elif grep $CID /tmp/CallBack.txt ; then
#找到資料給予變數 CALLBACK
echo "set variable ACTION \"CALLBACK\""
else
#當以上兩個檔案都沒沒找到資料時,給予變數 GOOUT
echo "set variable ACTION \"GOOUT\""
fi
cid.sh 此檔必須放在 agi-bin 此資料夾內
在 debian 版本是 agi-bin是位於 /usr/share/asterisk/agi-bin
參考資料:[Asterisk-Users]AGI script sample using bash shell script
參考程式碼:
#!/bin/bash
declare -a array
while read -e ARG && [ "$ARG" ] ; do
array=(` echo $ARG | sed -e 's/://'`)
export ${array[0]}=${array[1]}
done
# following variables are available from asterisk
echo $agi_request >&2
echo $agi_channel >&2
echo $agi_language >&2
echo $agi_type >&2
echo $agi_uniqueid >&2
echo $agi_callerid >&2
echo $agi_dnid >&2
echo $agi_rdnis >&2
echo $agi_context >&2
echo $agi_extension >&2
echo $agi_priority >&2
echo $agi_enhanced >&2
checkresults() {
while read line
do
case ${line:0:4} in
"200 " ) echo $line >&2
return;;
"510 " ) echo $line >&2
return;;
"520 " ) echo $line >&2
return;;
* ) echo $line >&2;; #keep on reading those Invlid command
#command syntax until "520 End ..."
esac
done
}
echo "1. Testing 'sendfile' ..." >&2
echo "STREAM FILE beep \"\""
checkresults
echo "2. Testing 'sendtext' ..." >&2
echo "SEND TEXT \"hello world\""
checkresults
echo "3. Testing 'sendmage' ..." >&2
echo "SEND IMAGE asterisk-image"
checkresults
echo "4. Testing 'saynumber' ..." >&2
echo "SAY NUMBER 192837465 \"\""
checkresults
echo "5. Testing 'waitdtmf' ..." >&2
echo "WAIT FOR DIGIT 1000"
checkresults
echo "6. Testing 'record' ..." >&2
echo "RECORD FILE testagi gsm 1234 3000"
checkresults
echo "6a. Testing 'record' playback" >&2
echo "STREAM FILE testagi \"\" "
checkresults
echo "=================== Complete ====================" >&2
進階版:多重判斷
上述範例只判斷了3個情況 IVR、callback、GOOUT 若我們要判斷的情況更多的話該怎麼做?
範例:依不同來電,劃分不同群組,給予不同的IVR
首先是 cid.sh 的改寫
#!/bin/bash
#本檔使用語法: cid.sh 電話號碼
#本檔功能:檢查 來電顯示 是否有在檔案清單之中。
#它會依次比對 /tmp 底下的 group1.txt 檔找不到時,才會去找 group2.txt,再找不到才會依次找下去。
#AGI指令: set variable 語法: set variable 變數名稱 "變數數值"
#由於它本身的語法就帶有"雙引號了,所以 echo 在使用它時,必須在雙引號前加 \" 倒斜線符號來規避此特殊字元
CID="$1"
if [ "$1" = "" ] ;then
#不帶來電顯示號碼者,給予變數 CIDempty 後直接跳出此程式
echo "set variable ACTION \"CIDempty\""
exit
fi
if grep $CID /tmp/group1.txt ; then
#找到資料給予變數 group1
echo "set variable ACTION \"group1\""
elif grep $CID /tmp/group2.txt ; then
#找到資料給予變數 group2
echo "set variable ACTION \"group2\""
elif grep $CID /tmp/group3.txt ; then
#找到資料給予變數 group3
echo "set variable ACTION \"group3\""
elif grep $CID /tmp/group4.txt ; then
#找到資料給予變數 group4
echo "set variable ACTION \"group4\""
elif grep $CID /tmp/group5.txt ; then
#找到資料給予變數 group5
echo "set variable ACTION \"group5\""
else
#當以上檔案都沒沒找到資料時,給予變數 GOOUT
echo "set variable ACTION \"GOOUT\""
fi
接下來就是 extensions.conf 的改寫
[my-phones]
exten => s,1,Answer
exten => s,2,AGI(cid.sh,${CALLERID(number)})
exten => s,3,Noop(RESULT ${ACTION})
exten => s,4,GotoIf($[ "${ACTION}" = "group1" ]?ivr-group1,s,1)
exten => s,n,GotoIf($[ "${ACTION}" = "group2" ]?ivr-group2,s,1)
exten => s,n,GotoIf($[ "${ACTION}" = "group3" ]?ivr-group3,s,1)
exten => s,n,GotoIf($[ "${ACTION}" = "group4" ]?ivr-group4,s,1)
exten => s,n,GotoIf($[ "${ACTION}" = "group5" ]?ivr-group5,s,1)
exten => s,n,GotoIf($[ "${ACTION}" = "GOOUT" ]?ivr-goout,s,1)
exten => s,n,GotoIf($[ "${ACTION}" = "CIDempty" ]?ivr-CIDempty,s,1)
exten => s,n,Hangup()
[ivr-group1]
exten => s,1,Answer
.......
[ivr-group2]
exten => s,1,Answer
.......
[ivr-group3]
exten => s,1,Answer
.......
[ivr-group4]
exten => s,1,Answer
.......
[ivr-group5]
exten => s,1,Answer
.......
[ivr-goout]
exten => s,1,PlaybackPlayback(custom/NumNotAvailable)
;撥放語音:對不起此號碼無法接通
exten => s,n,Hangup()
自動引用通知: Asterisk 相關資料 | oo7 の Blog