依不同Caller ID給予不同IVR

目地:根據不同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()
本篇發表於 voip。將永久鏈結加入書籤。

1 則回應給 依不同Caller ID給予不同IVR

  1. 引用通告: Asterisk 相關資料 | oo7 の Blog

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *