Asterisk auto-dial out Chinese

Asterisk Call Files


Asterisk call files 是個純文字檔,將它移至正確的目錄裡,就能透過asterisk自動撥打。Call files 是個很便利的自動撥打方式,而不用透過其它較複雜的asterisk功能如 AGI, AMI, 和 dialplan, 這些得需要一些技術才能實現。

The Asterisk dial plan extensions.conf responds to someone calling an extension on a channel.若你要從外部應用程式來撥出一通電話,有底下幾種方式可以實現。

asterisk 要啟動自動撥號功能有4種方法
  • 使用.call檔,它是個純文字檔,必須放在正確的目錄裡才行
  • 使用 manager API 去啟動撥打。詳見 Asterisk manager dialout
  • 使用指令列 Asterisk CLI originate 這個指令
  • 使用 FollowMe 這個指令,從 Asterisk 1.4 版本起,它就有能力實現多方通話(create multiple calls) 但它可能會被濫用於外撥(譯者注:我猜是被用來盜打)

See also additional Digium documents.

New in Asterisk 1.8: A new application Originate has been introduced, that allows asynchronous call origination from the dialplan.

Call file運作方式


  • 它必須放置在 /var/spool/asterisk/outgoing/ ( 或 astspooldir 同等目錄,可定義於 asterisk.conf 此檔).
  • modules.conf 裡必須要載入此模組 pbx_spool.so, 否則 call files 無法運作.
  • 若call file裡的撥打日期有修改過,而且是未來的日期,那麼asterisk則會等到那個時間才撥打
  • asterisk會立刻注意到並執行call file,它可與現有的dial plan context整合
  • 然後asterisk會將call file 刪除 (一般在 /var/spool/asterisk/outgoing).
  • 範例: 請見 簡單的 Call File 範例Call Files 語法 章節。

Call files語法

  • 定義從哪兒撥打出去
    • Channel: <channel>: Channel to use for the call.
    • CallerID: "name" <數值> Caller ID,請注意:若你不按此格式來寫的話則無效 CallerID: "Some Name" <1234>
    • MaxRetries: <數值> 撥打失敗後的最大重撥次數(不包含第一次撥打,例:此數字設為 0 等於總共只會撥打1次). 預設是0.
    • RetryTime: <數值> 重試秒數,預設是300秒,別用來欺負那些不想接你電話的人。
    • WaitTime: <數值> 接聽前的等候秒數,預設45秒。也就是響鈴時間。
    • Account: 用於CDR的帳戶號碼。
  • 若接通了,將它轉接到此
    • Context: <context-name> extensions.conf 裡 的Context
    • Extension: <ext> 定義在 extensions.conf 裡的分機號
    • Priority: <priority> 目標優先級,如果未設,預設為1。
    • Set: 設定變數 variable 用於分機額外的邏輯判斷 (例:: file1=/tmp/to ); 在新版的Asterisk 1.0.x 以上,使用 'SetVar' 這個指令來代替 'Set'
    • Application: 指定要用哪一個Asterisk的應用程式來執行(用來代替 已指定區段(context), Extension 和 priority)
    • Data: 此選項裡的資料將會傳送給上面的應用程式 application 例:playback(audioFile)
  • New (?) in Asterisk 1.4
    • Set: Can now also write to dialplan functions like CDR()
    • AlwaysDelete: Yes/No - 若修改後的日期是在未來,則 call file 不會被刪掉
    • Archive: Yes/No - 存檔功能。它會移到子目錄 "outgoing_done" 和 "Status: value", where value can be Completed, Expired or Failed.

最少要有一個app或分機號需要指定和使用哪個頻道和撥打目地都要定義清楚

簡單的 Call File 範例


最簡單的 call file 範例,我們不做什麼,只撥個號碼和放個音檔。

hello-world.call

Channel: SIP/trunkname/18882223333
Application: Playback
Data: hello-world

↑譯者註: Data 的部份,音檔可輸入完整的路徑,但不可輸入副檔名,否則會報錯,無法撥放。

要執行這面這個 call file 你需輸入底下指令 (我們假定此檔的擁有者是 the asterisk user:


mv hello-world.call /var/spool/asterisk/outgoing/


它如何運作的?當 Asterisk 讀取了上面那個call file之後,它接下來會這麼做

  • 使用SIP協定,撥號 18882223333 出去,經由你指定的 trunkname。
  • 一旦電話被接聽,便撥放此音檔 /var/lib/asterisk/sounds/hello-world (此音檔預設就有)
  • 掛斷此通電話

如你所見,這是一個非常精簡的 call file 範例。

The 'failed' extension

若電話沒被接聽, 而且 這個分機 standard extension failed 和 priority 1 存在於同樣的區段(context)裡, 則控制流程會跳到此 (此功能在 Asterisk 1.2 or 1.4. 被引進 NOTE: This works in asterisk 1.2.14)
    • Note 1: 它只能有效於:你此通話已指定了 context, extension, 和 priority defined, 並且沒有使用 application 和日期。
    • Note 2: This is a good place to update the CDR UserField with a value of the phone number that was being dialed using the SetCDRUserfield() application. Asterisk (as of 1.2.10) does not make the dialed channel (eg. IAX2/15551234567) available anywhere, so you have to pass it to yourself using Set: field of the .call file. (Along with anything else you want pass to the channel in this same variable).
    • Note 3: The ${REASON} channel variable receives a value that represents the reason why the call failed. See more on Asterisk Reason variable.

Example

In .call file:
Set: PassedInfo=15551234567-moreinfo-evenmoreinfo

extensions.conf
exten => failed,1,Set(NumberDialed=${CUT(PassedInfo,,1)})
exten => failed,n,SetCDRUserField(${NumberDialed})





Scope of variables

  • Make sure you know what prefixing a variable with _ or __ does!
  • Especially Asterisk 1.0 and 1.2 behave differently for what concerns a) passing on variables to channels and b) global variables
  • Consider using DBGet and DBPut if you experience trouble passing variables

建立和和搬移Call Files


因為Asterisk可在任何時候獲取Call File (例:當檔案只寫到一半時), 不要直接建檔案在此目錄 /var/spool/asterisk/outgoing 底下. 請這樣操作:

  • 建 call file 在不同的目錄 - 例 /var/spool/asterisk/tmp/callfile-18882223333-01252010-104400.call
  • 若 Asterisk 是使用不同的user身份來執行的話,那麼你建檔時得跟它同一個user身份 (例: 若 Asterisk 是跑在 'asterisk'此帳號底下,但你建call file檔卻是用 'root' 身份) 那你得先改一下檔案擁有者的權限,在你將檔案弄進 Asterisk 的自動撥號目錄裡去: chown asterisk:asterisk /var/spool/asterisk/tmp/callfile-18882223333-01252010-104400.call
  • mv /var/spool/asterisk/tmp/callfile-18882223333-01252010-104400.call /var/spool/asterisk/outgoing/

這方法可行是因為 Unix 的搬移動作(mv 指令) 僅只是搬移 "inode" — 直指檔案 — 使得整個檔案能夠一次呈現與消除 ,能避免Asterisk 對還沒寫完的檔案執行撥打的動作(譯註:此段原文的英文文法較特殊,只能翻大意)(註:前面所說的情況只在檔案來源與目地都在同一個檔案系統的情況下,否則它的效果只能跟"cp" 指令一樣; 詳見下方。)

Note: 使用copy 指令 (cp) 是個不安全的方式來加檔案進自動撥號目錄裡去,因為當檔案還在copy過程當中,其它程式(特別是asterisk)就能讀取並執行撥打動作了,但因為還沒copy完,所以檔案還沒寫完,這樣就會造成讀取到的檔案不完全。若你非得要使用 CP 指令,你應在你自己的目錄裡,此目錄asterisk讀不到,也沒有權限去移除它,再來copy檔案,這樣還能幫你省去額外的備份動作。

譯者註:cp動作是一行一行的copy檔案內容的,所以會造成asterisk讀取檔案不全的可能性發生。
譯者註2:mv (移動)是一個不可分割的操作(只有當100%完成之後才生效的操作) ,本身是非常適合 .call 文件。而cp (複制),文件是逐行複制的,可能造成 Asterisk處理一個不完整的文件。

使用VB Scripts 從純文字檔來建立你的 call files 並且移檔至 asterisk spool 目錄 using pscp 指令.


首先你要建一些文字檔,並使用其中一個文字檔裡包含了所有的電話號碼,此腳本期望文字檔的格式會是每個電話號碼單獨一行。
它經由建立文字檔並在當前目錄裡另建立新的子目錄裡各含 20 電話號碼。
它使用電話號碼做為每個call file檔名。每個子目錄含 20 call files 檔名從1開始命名。
一旦 call files 被建立使用第2個腳本將它移進 spool 目錄,使用 pscp 指令。
Pscp 是個免費的檔案傳輸程式,可運作於SSH 上,在你使用此腳本前確認你使用putty儲存好一個登入你的asterisk系統的連線。


;!!!!!!!!!!!!!!!!!!!!!
;Creates call text files taking the numbers from a flat text file that has one phone number per line
;expample phonenumbers.txt
;1234567890
;2134567890
;a text file that contains the 2 lines above (without the colons) will create 2 text files one for each number
;you can copy and paste this whole code into a .vbs file in windows and then execute it.
;put the file in the same directory as the text file with the phone numbers are.

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFilePhones = objFSO.OpenTextFile("C:\calls\Phone.txt",1) ;change this line to your path
strfname=1
strcnt=1
Set objFolders=objFSO.CreateFolder(strfname)
Do While objFilePhones.AtEndOfStream = False
	If strcnt=20 then;change this number to anything else if you want more or fewer simultaneous calls.
		strfname=strfname+1

		Set objFolders=objFSO.CreateFolder(strfname)
		strcnt=1
	end if
	strLine = objFilePhones.ReadLine

	strFullName = objFSO.BuildPath(strfname, strLine)
	Set objFileCalls = objFSO.CreateTextFile(strFullName)
	objFileCalls.close
	Set objFileCalls = objFSO.OpenTextFile(strFullName,2)
	objFileCalls.Write("Channel: ");put your channel information here, add a 1 before the number if your provider requires that
	objFileCalls.WriteLine(strLine)
	objFileCalls.WriteLine("CallerID: Name <1234>");change caller id as needed
	objFileCalls.WriteLine("MaxRetries: 0");change this if you want it to retry
	objFileCalls.WriteLine("RetryTime: 3")
	objFileCalls.WriteLine("WaitTime: 30");change this if you want it to ring longer before giving up
	objFileCalls.WriteLine("Context: test");put context here
	objFileCalls.WriteLine("Extension: 800");put extension here
	objFileCalls.WriteLine("Priority: 1");put priority here
	objFileCalls.Close
	strcnt=strcnt+1
Loop
;end code for first script that creates the call files.
;the next script moves the files to the asterisk spool directory expecting pscp to be located under c:\pscp.exe and a 
;named saved session to your asterisk box in putty as asterisk.
;paste as needed
Set objFSO = CreateObject("Scripting.FileSystemObject")

strcnt=1
strfldr="C:\calls\"&strcnt

for i=1 to 1000 ;assuming that you don't have more than 1000 folders or 20000 files, if you do change this number
If objFSO.FolderExists(strfldr) Then
	strfldr="C:\calls\"&strcnt ;change path as needed
	Set objShell = CreateObject("WScript.Shell")
	strcmd="C:\pscp -pw passwordhere c:\calls\"&strcnt&"\* root@asterisk:/var/spool/asterisk/outgoing"
        ;change username and password as needed, as well as path to pscp and call files
	objShell.Run strcmd
	strcnt=strcnt+1

else
	exit for
End If

wscript.sleep(36000)
;change time interval between every folder it moves, when I created it I was dealing with recordings of 
;15-20 seconds and 30 second wait time to answer the call, since I didn't want more than 20 calls 
;simultaneous this worked for me. change as you like

next
;end second file, paste this to a new .vbs file under the same directory then execute it.
;end code


Examples

Example 1

Filename: 1.call


Channel: Zap/1/1XXXXXXXXXXXX
MaxRetries: 2
RetryTime: 60
WaitTime: 30
Context: callme
Extension: 800
Priority: 2



This will hook up to priority 2 of extension 800 in context callme in extensions.conf.

Example 2


To create a call to 14109850123 on an analog channel in group 2 and then connect it to the hypothetical extension 84 (which would map to 84,1,Dial(SIP/84) ) inside your network, here's the file you'd create in /var/spool/asterisk/outgoing:

  1. Create the call on group 2 dial lines and set up
  2. some re-try timers
Channel: Zap/g2/14109850123
MaxRetries: 2
RetryTime: 60
WaitTime: 30
  1. Assuming that your local extensions are kept in the
  2. context called [extensions]
Context: extensions
Extension: 84
Priority: 1



The above examples are good if you want to automatically play some recorded message, or something automatic that must start when the other party picks up the phone. In fact if you use the above for a conversation, you will have the outgoing phone ring, and when the other person picks up his phone, only then your extension starts to ring, so you miss the initial "hello" and maybe some more words!
If you have outgoing calls in your dialplan defined in the [outgoing] context, to call 14109850123 do this:

Example 3


To create a call to 14109850123 on a SIP phones called bt101, here's the file you'd create in /var/spool/asterisk/outgoing (whatever name is good, of course must be accessible and deletable by asterisk GNU/Linux user):

Channel: SIP/bt101
MaxRetries: 1
RetryTime: 60
WaitTime: 30
  1. Assuming that your outgoing call logic is kept in the
  2. context called [outgoing]
Context: outgoing
Extension: 14109850123
Priority: 1



Example 4


自動撥號並撥放預錄訊息,允許重聽,訊息收到確認。
請見: Auto-dial and Deliver Message

Example 5


To create a call to an internal or external extension connected to an AGI

Channel: Local/1000@from-internal
MaxRetries: 0
RetryTime: 15
WaitTime: 15
Application: AGI
Data: myagi.agi


On a trixbox/freepbx system this will dial internal extension 1000 (or you can put even an outside # here and it will follow outbound rules) and connect it to an AGI program. Note that unlike in extensions.conf where you can specify AGI(file.agi), here it must be separated. I use one agi to detect an incoming call to a special extension#, record the caller id, and then create the .call file to call back that number and connect it to a second agi.

Example 6: 使用 Asterisk 作為 PA system 來發佈緊急通知


你的 Asterisk PABX 可很簡單的就能立即通傳送語音訊息給所有的電話 (或群組)。

很簡單的設定,首先你要錄兩個語音提示訊息:

pa-welcome.wav

請在嗶聲後錄下你的廣播訊息,結束請按井號鍵(hash key)

pa-confirm.wav

按 1 傳送你的訊息至所有電話,按 0 取消。

In your dialplan you create a context called [pa-system] and you Goto that context if the user dials 911 (or any other extension you find appropriate).


exten => 911,1,Goto(pa-system,s,1)

[pa-system]
exten => s,1,Answer
exten => s,n,Wait(2)
exten => s,n,Playback(pa-welcome)
exten => s,n,Wait(1)
exten => s,n,Record(pa-message.wav)
exten => s,n,Wait(1)
exten => s,n,Background(pa-confirm)
exten => s,n,WaitExten(10)
exten => s,n,Hangup()
exten => 1,1,System(cp /etc/asterisk/pa-system/*.call /tmp/)
exten => 1,n,System(mv /tmp/*.call /var/spool/asterisk/outgoing/)
exten => 0,1, Hangup()


上面這段意思是, copy你事先準備好的 call files 進 asterisk 外撥等候隊列的目錄裡。為避免時間的問題,我們先 copy 檔案至暫存目錄裡再將它搬至外撥隊列裡(queue).
此 call file 的副檔名為 .call ,而主檔名最好為分機號。例:

Filename: 218.call


Channel: SIP/218
Callerid: 911
MaxRetries: 10
RetryTime: 5
WaitTime: 20
Context: pa-call-file
Extension: 10


So all call files in the directory /etc/asterisk/pa-system have the same content, except for the first line where you put the channel (like Zap/1 of SIP/218)
The Context line refers to the context that will be executed. You have to create that context in you extensions.conf too:


[pa-call-file]
exten => 10,1,Answer()
exten => 10,n,Wait(1)
exten => 10,n,Playback(pa-message)
exten => 10,n,Wait(1)
exten => 10,n,Hangup()


And you have a functional PA system!

One more feature you can add:
If you use (SIP) phones that support a distinctive ringtone, you can program these phones to ring differently when Callerid 911 calls (to indicate it's an emergency).




How to schedule a Call in the Future

Files with a modified date in the future are ignored until that time arrives. Create the file in /var/spool/asterisk/tmp, modify the mtime using "touch", and then move it...


$ date
Mon Mar 19 13:52:30 EDT 2007
$ touch -d 20080101 /var/spool/asterisk/tmp/blah
$ mv /var/spool/asterisk/tmp/blah .
$ ls -l blah
-rw-r--r-- 1 andrew users 0 Jan 1 00:00 blah




Bash example: to schedule a call in 100 s :

  1. gives you the current time in seconds since dawn of UNIX
NOW=`date +%s`
  1. add 100 seconds
let NOW=$NOW+100
  1. create a timestamp used by 'touch -t' (no space between %M. %S, but the Wiki wants a space at this place)
TOUCH_TMSP=`date -d "1970-01-01 $NOW sec GMT" +%Y%m%d%H%M. %S`
  1. and do the touch
touch -t $TOUCH_TMSP blah



Edit: many modern `touch´ binaries support all -d options of `date´. You can schedule a call in the future before moving it to /var/spool/asterisk/outgoing with

touch -d "1 week 2 days 4 hours 49 minutes 11 seconds" my_call_file_name


Tip提示 管理同時外撥的數量

你可限制一個同時外撥的數量,藉由管理放在此 outbound directory外撥目錄 (/var/spool/asterisk/outgoing)裡的檔案數量。例,若要限制 Asterisk 同一時間只能有 10 通外撥數量,只要限制外撥目錄裡一次只能有10個call檔案。當此數量減少時,你再搬額外的call檔案進此目錄,以維持你想要的同時外撥數量。

注意: 有不同的使用者反應 Asterisk 的壅塞狀況 (即不執行某些 .call files) 當太多檔案同時被移進外撥目錄時。 因此較明智的做法是將檔案一個個的移進去(step-by-step)並伴隨著輕微的延遲(with a slight delay)。
然而,當 Asterisk 仍發生 '忘了' 去執行一個 call file 時(seen e.g. in 1.0.9). 可能的解法:
  • 1. 找出發生的原因並修正它在原始碼裡,
  • 2. 使用管理API,只能希望它不會再現此問題,
  • 3. 設計一個應用程式來應付此問題,例如計算機查現存的 CDR 資料,比對你的 .call file 細節 (撥打時間,目地,帳號碼等等)。

更多範例



Callfiles 的撥打記錄(Call Detail Records)

  • 避免遺失 CDR 記錄: 方案有二,擇一用之 a) 使用 Context/Extension/Priority 取代 Application/Data 在call file中, b) 使用 Local channel 來取代你想要直接撥打的頻道。 另外 Asterisk will bypass the process that tracks the call and 不會有帳單 CDR record 產生。 當使用了 Context/Extension/Priority, 你真的使用了 Goto 這類的功能,它會將通話放置正確的dialplan區段裡, and to it is the same as if the caller had dialed the call manually and so the call is logged.
  • The phone number you are dialling will not be stored in the CDR by * - if you need this information for CDR processing you can set the CallerID in the call file to this number and it will be stored. However, this will present the person you are calling their own phone number, which doesn't make much sense. A better solution might be to put the number you are dialing in the Set: channel variable in the .call file and later put it into the UserField of the CDR. See example above in the first section.

Tips and hints

  • Create the call file elsewhere, and move it (better not use copy, see above) into the directory after you're done creating it. Asterisk is very aggressive in grabbing these files, and if you're still creating it when it grabs the file, you'll get errors, so best to create first and then copy in to the outgoing directory all at once.
  • The call file must be owned by the user asterisk runs as, so asterisk can utime() it, or you will get permission errors.
  • If you are using POTS (Plain Old Telephone System) lines attached to a channel bank with FXO cards, it's likely that you will run into problems sensing when your callee picks up their phone - especially to cell phones. Once Asterisk hands off a call to an FXO line (ie, it starts to ring), the system counts the call as 'answered', and continues its merry way. This means that your voice prompts get played to a ring tone, and your users are presented with a silent call.
Some things to try:
    • In zapata.conf, try adding callprogress=yes above your channel => n definition for the FXO lines. (remember that settings set above the channel flow down, and that you need to clear this setting with a callprogress=no for any channels you might not want this to affect!)
      • This is experimental, only sometimes works, and only for North American tones.
      • On my system, this setting failed miserably, to the point that I could no longer make outgoing calls, and calls were dropped.
    • Another option (At least in example 3), is to repeat your message. Note the ResponseTimeout(2), to set the pause between repeats to 2 seconds, and the GoTo(s|1), to repeat the prompts.
    • Yet another option is to use an application like "WaitForSilence" that will wait for a certain amount of silence before beginning to play the message. See bugs.digium.com #2467 for this app, which will probably soon appear in CVS.
  • Try app_machinedetect.c application for detection of answering machines. This works best with PRI, VoIP, or a POTS with callprogress enabled. (This will cause a 'dead-air' silent pause at the beginning of all calls and with well-chosen settings will not provide better than 80-90% accuracy.)
  • Be advised that, if you create a new .call file and move it into the outgoing Asterisk directory for processing AND it has the same file name as a .call file which was just processed, Asterisk will throw the new file in the bit bucket.


A Few Ideas

What Can You Do With This Interface?

  • Setup a cron job to dial out at specific times.
  • Stress test your server for call load.
  • Prank call your friends with pre-recorded messages.
  • War dialing.
  • Auto-dialing / telemarketing.
  • Create an alarm program to wake you up in the mornings.
  • Create auto-callback functionality from your extensions.
  • Connect calls between your extension and a number using a web interface / other application.

The possibilities are endless!

Programming Libraries For Creating / Using CallFiles

There are several programming libraries which abstract file operations and simplify the call file process.

  • http://pycall.org|pycall - A flexible python library for creating and using Asterisk callfiles.



See also



Go back to Asterisk

Asterisk Call Files


Asterisk call files 是個純文字檔,將它移至正確的目錄裡,就能透過asterisk自動撥打。Call files 是個很便利的自動撥打方式,而不用透過其它較複雜的asterisk功能如 AGI, AMI, 和 dialplan, 這些得需要一些技術才能實現。

The Asterisk dial plan extensions.conf responds to someone calling an extension on a channel.若你要從外部應用程式來撥出一通電話,有底下幾種方式可以實現。

asterisk 要啟動自動撥號功能有4種方法
  • 使用.call檔,它是個純文字檔,必須放在正確的目錄裡才行
  • 使用 manager API 去啟動撥打。詳見 Asterisk manager dialout
  • 使用指令列 Asterisk CLI originate 這個指令
  • 使用 FollowMe 這個指令,從 Asterisk 1.4 版本起,它就有能力實現多方通話(create multiple calls) 但它可能會被濫用於外撥(譯者注:我猜是被用來盜打)

See also additional Digium documents.

New in Asterisk 1.8: A new application Originate has been introduced, that allows asynchronous call origination from the dialplan.

Call file運作方式


  • 它必須放置在 /var/spool/asterisk/outgoing/ ( 或 astspooldir 同等目錄,可定義於 asterisk.conf 此檔).
  • modules.conf 裡必須要載入此模組 pbx_spool.so, 否則 call files 無法運作.
  • 若call file裡的撥打日期有修改過,而且是未來的日期,那麼asterisk則會等到那個時間才撥打
  • asterisk會立刻注意到並執行call file,它可與現有的dial plan context整合
  • 然後asterisk會將call file 刪除 (一般在 /var/spool/asterisk/outgoing).
  • 範例: 請見 簡單的 Call File 範例Call Files 語法 章節。

Call files語法

  • 定義從哪兒撥打出去
    • Channel: <channel>: Channel to use for the call.
    • CallerID: "name" <數值> Caller ID,請注意:若你不按此格式來寫的話則無效 CallerID: "Some Name" <1234>
    • MaxRetries: <數值> 撥打失敗後的最大重撥次數(不包含第一次撥打,例:此數字設為 0 等於總共只會撥打1次). 預設是0.
    • RetryTime: <數值> 重試秒數,預設是300秒,別用來欺負那些不想接你電話的人。
    • WaitTime: <數值> 接聽前的等候秒數,預設45秒。也就是響鈴時間。
    • Account: 用於CDR的帳戶號碼。
  • 若接通了,將它轉接到此
    • Context: <context-name> extensions.conf 裡 的Context
    • Extension: <ext> 定義在 extensions.conf 裡的分機號
    • Priority: <priority> 目標優先級,如果未設,預設為1。
    • Set: 設定變數 variable 用於分機額外的邏輯判斷 (例:: file1=/tmp/to ); 在新版的Asterisk 1.0.x 以上,使用 'SetVar' 這個指令來代替 'Set'
    • Application: 指定要用哪一個Asterisk的應用程式來執行(用來代替 已指定區段(context), Extension 和 priority)
    • Data: 此選項裡的資料將會傳送給上面的應用程式 application 例:playback(audioFile)
  • New (?) in Asterisk 1.4
    • Set: Can now also write to dialplan functions like CDR()
    • AlwaysDelete: Yes/No - 若修改後的日期是在未來,則 call file 不會被刪掉
    • Archive: Yes/No - 存檔功能。它會移到子目錄 "outgoing_done" 和 "Status: value", where value can be Completed, Expired or Failed.

最少要有一個app或分機號需要指定和使用哪個頻道和撥打目地都要定義清楚

簡單的 Call File 範例


最簡單的 call file 範例,我們不做什麼,只撥個號碼和放個音檔。

hello-world.call

Channel: SIP/trunkname/18882223333
Application: Playback
Data: hello-world

↑譯者註: Data 的部份,音檔可輸入完整的路徑,但不可輸入副檔名,否則會報錯,無法撥放。

要執行這面這個 call file 你需輸入底下指令 (我們假定此檔的擁有者是 the asterisk user:


mv hello-world.call /var/spool/asterisk/outgoing/


它如何運作的?當 Asterisk 讀取了上面那個call file之後,它接下來會這麼做

  • 使用SIP協定,撥號 18882223333 出去,經由你指定的 trunkname。
  • 一旦電話被接聽,便撥放此音檔 /var/lib/asterisk/sounds/hello-world (此音檔預設就有)
  • 掛斷此通電話

如你所見,這是一個非常精簡的 call file 範例。

The 'failed' extension

若電話沒被接聽, 而且 這個分機 standard extension failed 和 priority 1 存在於同樣的區段(context)裡, 則控制流程會跳到此 (此功能在 Asterisk 1.2 or 1.4. 被引進 NOTE: This works in asterisk 1.2.14)
    • Note 1: 它只能有效於:你此通話已指定了 context, extension, 和 priority defined, 並且沒有使用 application 和日期。
    • Note 2: This is a good place to update the CDR UserField with a value of the phone number that was being dialed using the SetCDRUserfield() application. Asterisk (as of 1.2.10) does not make the dialed channel (eg. IAX2/15551234567) available anywhere, so you have to pass it to yourself using Set: field of the .call file. (Along with anything else you want pass to the channel in this same variable).
    • Note 3: The ${REASON} channel variable receives a value that represents the reason why the call failed. See more on Asterisk Reason variable.

Example

In .call file:
Set: PassedInfo=15551234567-moreinfo-evenmoreinfo

extensions.conf
exten => failed,1,Set(NumberDialed=${CUT(PassedInfo,,1)})
exten => failed,n,SetCDRUserField(${NumberDialed})





Scope of variables

  • Make sure you know what prefixing a variable with _ or __ does!
  • Especially Asterisk 1.0 and 1.2 behave differently for what concerns a) passing on variables to channels and b) global variables
  • Consider using DBGet and DBPut if you experience trouble passing variables

建立和和搬移Call Files


因為Asterisk可在任何時候獲取Call File (例:當檔案只寫到一半時), 不要直接建檔案在此目錄 /var/spool/asterisk/outgoing 底下. 請這樣操作:

  • 建 call file 在不同的目錄 - 例 /var/spool/asterisk/tmp/callfile-18882223333-01252010-104400.call
  • 若 Asterisk 是使用不同的user身份來執行的話,那麼你建檔時得跟它同一個user身份 (例: 若 Asterisk 是跑在 'asterisk'此帳號底下,但你建call file檔卻是用 'root' 身份) 那你得先改一下檔案擁有者的權限,在你將檔案弄進 Asterisk 的自動撥號目錄裡去: chown asterisk:asterisk /var/spool/asterisk/tmp/callfile-18882223333-01252010-104400.call
  • mv /var/spool/asterisk/tmp/callfile-18882223333-01252010-104400.call /var/spool/asterisk/outgoing/

這方法可行是因為 Unix 的搬移動作(mv 指令) 僅只是搬移 "inode" — 直指檔案 — 使得整個檔案能夠一次呈現與消除 ,能避免Asterisk 對還沒寫完的檔案執行撥打的動作(譯註:此段原文的英文文法較特殊,只能翻大意)(註:前面所說的情況只在檔案來源與目地都在同一個檔案系統的情況下,否則它的效果只能跟"cp" 指令一樣; 詳見下方。)

Note: 使用copy 指令 (cp) 是個不安全的方式來加檔案進自動撥號目錄裡去,因為當檔案還在copy過程當中,其它程式(特別是asterisk)就能讀取並執行撥打動作了,但因為還沒copy完,所以檔案還沒寫完,這樣就會造成讀取到的檔案不完全。若你非得要使用 CP 指令,你應在你自己的目錄裡,此目錄asterisk讀不到,也沒有權限去移除它,再來copy檔案,這樣還能幫你省去額外的備份動作。

譯者註:cp動作是一行一行的copy檔案內容的,所以會造成asterisk讀取檔案不全的可能性發生。
譯者註2:mv (移動)是一個不可分割的操作(只有當100%完成之後才生效的操作) ,本身是非常適合 .call 文件。而cp (複制),文件是逐行複制的,可能造成 Asterisk處理一個不完整的文件。

使用VB Scripts 從純文字檔來建立你的 call files 並且移檔至 asterisk spool 目錄 using pscp 指令.


首先你要建一些文字檔,並使用其中一個文字檔裡包含了所有的電話號碼,此腳本期望文字檔的格式會是每個電話號碼單獨一行。
它經由建立文字檔並在當前目錄裡另建立新的子目錄裡各含 20 電話號碼。
它使用電話號碼做為每個call file檔名。每個子目錄含 20 call files 檔名從1開始命名。
一旦 call files 被建立使用第2個腳本將它移進 spool 目錄,使用 pscp 指令。
Pscp 是個免費的檔案傳輸程式,可運作於SSH 上,在你使用此腳本前確認你使用putty儲存好一個登入你的asterisk系統的連線。


;!!!!!!!!!!!!!!!!!!!!!
;Creates call text files taking the numbers from a flat text file that has one phone number per line
;expample phonenumbers.txt
;1234567890
;2134567890
;a text file that contains the 2 lines above (without the colons) will create 2 text files one for each number
;you can copy and paste this whole code into a .vbs file in windows and then execute it.
;put the file in the same directory as the text file with the phone numbers are.

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFilePhones = objFSO.OpenTextFile("C:\calls\Phone.txt",1) ;change this line to your path
strfname=1
strcnt=1
Set objFolders=objFSO.CreateFolder(strfname)
Do While objFilePhones.AtEndOfStream = False
	If strcnt=20 then;change this number to anything else if you want more or fewer simultaneous calls.
		strfname=strfname+1

		Set objFolders=objFSO.CreateFolder(strfname)
		strcnt=1
	end if
	strLine = objFilePhones.ReadLine

	strFullName = objFSO.BuildPath(strfname, strLine)
	Set objFileCalls = objFSO.CreateTextFile(strFullName)
	objFileCalls.close
	Set objFileCalls = objFSO.OpenTextFile(strFullName,2)
	objFileCalls.Write("Channel: ");put your channel information here, add a 1 before the number if your provider requires that
	objFileCalls.WriteLine(strLine)
	objFileCalls.WriteLine("CallerID: Name <1234>");change caller id as needed
	objFileCalls.WriteLine("MaxRetries: 0");change this if you want it to retry
	objFileCalls.WriteLine("RetryTime: 3")
	objFileCalls.WriteLine("WaitTime: 30");change this if you want it to ring longer before giving up
	objFileCalls.WriteLine("Context: test");put context here
	objFileCalls.WriteLine("Extension: 800");put extension here
	objFileCalls.WriteLine("Priority: 1");put priority here
	objFileCalls.Close
	strcnt=strcnt+1
Loop
;end code for first script that creates the call files.
;the next script moves the files to the asterisk spool directory expecting pscp to be located under c:\pscp.exe and a 
;named saved session to your asterisk box in putty as asterisk.
;paste as needed
Set objFSO = CreateObject("Scripting.FileSystemObject")

strcnt=1
strfldr="C:\calls\"&strcnt

for i=1 to 1000 ;assuming that you don't have more than 1000 folders or 20000 files, if you do change this number
If objFSO.FolderExists(strfldr) Then
	strfldr="C:\calls\"&strcnt ;change path as needed
	Set objShell = CreateObject("WScript.Shell")
	strcmd="C:\pscp -pw passwordhere c:\calls\"&strcnt&"\* root@asterisk:/var/spool/asterisk/outgoing"
        ;change username and password as needed, as well as path to pscp and call files
	objShell.Run strcmd
	strcnt=strcnt+1

else
	exit for
End If

wscript.sleep(36000)
;change time interval between every folder it moves, when I created it I was dealing with recordings of 
;15-20 seconds and 30 second wait time to answer the call, since I didn't want more than 20 calls 
;simultaneous this worked for me. change as you like

next
;end second file, paste this to a new .vbs file under the same directory then execute it.
;end code


Examples

Example 1

Filename: 1.call


Channel: Zap/1/1XXXXXXXXXXXX
MaxRetries: 2
RetryTime: 60
WaitTime: 30
Context: callme
Extension: 800
Priority: 2



This will hook up to priority 2 of extension 800 in context callme in extensions.conf.

Example 2


To create a call to 14109850123 on an analog channel in group 2 and then connect it to the hypothetical extension 84 (which would map to 84,1,Dial(SIP/84) ) inside your network, here's the file you'd create in /var/spool/asterisk/outgoing:

  1. Create the call on group 2 dial lines and set up
  2. some re-try timers
Channel: Zap/g2/14109850123
MaxRetries: 2
RetryTime: 60
WaitTime: 30
  1. Assuming that your local extensions are kept in the
  2. context called [extensions]
Context: extensions
Extension: 84
Priority: 1



The above examples are good if you want to automatically play some recorded message, or something automatic that must start when the other party picks up the phone. In fact if you use the above for a conversation, you will have the outgoing phone ring, and when the other person picks up his phone, only then your extension starts to ring, so you miss the initial "hello" and maybe some more words!
If you have outgoing calls in your dialplan defined in the [outgoing] context, to call 14109850123 do this:

Example 3


To create a call to 14109850123 on a SIP phones called bt101, here's the file you'd create in /var/spool/asterisk/outgoing (whatever name is good, of course must be accessible and deletable by asterisk GNU/Linux user):

Channel: SIP/bt101
MaxRetries: 1
RetryTime: 60
WaitTime: 30
  1. Assuming that your outgoing call logic is kept in the
  2. context called [outgoing]
Context: outgoing
Extension: 14109850123
Priority: 1



Example 4


自動撥號並撥放預錄訊息,允許重聽,訊息收到確認。
請見: Auto-dial and Deliver Message

Example 5


To create a call to an internal or external extension connected to an AGI

Channel: Local/1000@from-internal
MaxRetries: 0
RetryTime: 15
WaitTime: 15
Application: AGI
Data: myagi.agi


On a trixbox/freepbx system this will dial internal extension 1000 (or you can put even an outside # here and it will follow outbound rules) and connect it to an AGI program. Note that unlike in extensions.conf where you can specify AGI(file.agi), here it must be separated. I use one agi to detect an incoming call to a special extension#, record the caller id, and then create the .call file to call back that number and connect it to a second agi.

Example 6: 使用 Asterisk 作為 PA system 來發佈緊急通知


你的 Asterisk PABX 可很簡單的就能立即通傳送語音訊息給所有的電話 (或群組)。

很簡單的設定,首先你要錄兩個語音提示訊息:

pa-welcome.wav

請在嗶聲後錄下你的廣播訊息,結束請按井號鍵(hash key)

pa-confirm.wav

按 1 傳送你的訊息至所有電話,按 0 取消。

In your dialplan you create a context called [pa-system] and you Goto that context if the user dials 911 (or any other extension you find appropriate).


exten => 911,1,Goto(pa-system,s,1)

[pa-system]
exten => s,1,Answer
exten => s,n,Wait(2)
exten => s,n,Playback(pa-welcome)
exten => s,n,Wait(1)
exten => s,n,Record(pa-message.wav)
exten => s,n,Wait(1)
exten => s,n,Background(pa-confirm)
exten => s,n,WaitExten(10)
exten => s,n,Hangup()
exten => 1,1,System(cp /etc/asterisk/pa-system/*.call /tmp/)
exten => 1,n,System(mv /tmp/*.call /var/spool/asterisk/outgoing/)
exten => 0,1, Hangup()


上面這段意思是, copy你事先準備好的 call files 進 asterisk 外撥等候隊列的目錄裡。為避免時間的問題,我們先 copy 檔案至暫存目錄裡再將它搬至外撥隊列裡(queue).
此 call file 的副檔名為 .call ,而主檔名最好為分機號。例:

Filename: 218.call


Channel: SIP/218
Callerid: 911
MaxRetries: 10
RetryTime: 5
WaitTime: 20
Context: pa-call-file
Extension: 10


So all call files in the directory /etc/asterisk/pa-system have the same content, except for the first line where you put the channel (like Zap/1 of SIP/218)
The Context line refers to the context that will be executed. You have to create that context in you extensions.conf too:


[pa-call-file]
exten => 10,1,Answer()
exten => 10,n,Wait(1)
exten => 10,n,Playback(pa-message)
exten => 10,n,Wait(1)
exten => 10,n,Hangup()


And you have a functional PA system!

One more feature you can add:
If you use (SIP) phones that support a distinctive ringtone, you can program these phones to ring differently when Callerid 911 calls (to indicate it's an emergency).




How to schedule a Call in the Future

Files with a modified date in the future are ignored until that time arrives. Create the file in /var/spool/asterisk/tmp, modify the mtime using "touch", and then move it...


$ date
Mon Mar 19 13:52:30 EDT 2007
$ touch -d 20080101 /var/spool/asterisk/tmp/blah
$ mv /var/spool/asterisk/tmp/blah .
$ ls -l blah
-rw-r--r-- 1 andrew users 0 Jan 1 00:00 blah




Bash example: to schedule a call in 100 s :

  1. gives you the current time in seconds since dawn of UNIX
NOW=`date +%s`
  1. add 100 seconds
let NOW=$NOW+100
  1. create a timestamp used by 'touch -t' (no space between %M. %S, but the Wiki wants a space at this place)
TOUCH_TMSP=`date -d "1970-01-01 $NOW sec GMT" +%Y%m%d%H%M. %S`
  1. and do the touch
touch -t $TOUCH_TMSP blah



Edit: many modern `touch´ binaries support all -d options of `date´. You can schedule a call in the future before moving it to /var/spool/asterisk/outgoing with

touch -d "1 week 2 days 4 hours 49 minutes 11 seconds" my_call_file_name


Tip提示 管理同時外撥的數量

你可限制一個同時外撥的數量,藉由管理放在此 outbound directory外撥目錄 (/var/spool/asterisk/outgoing)裡的檔案數量。例,若要限制 Asterisk 同一時間只能有 10 通外撥數量,只要限制外撥目錄裡一次只能有10個call檔案。當此數量減少時,你再搬額外的call檔案進此目錄,以維持你想要的同時外撥數量。

注意: 有不同的使用者反應 Asterisk 的壅塞狀況 (即不執行某些 .call files) 當太多檔案同時被移進外撥目錄時。 因此較明智的做法是將檔案一個個的移進去(step-by-step)並伴隨著輕微的延遲(with a slight delay)。
然而,當 Asterisk 仍發生 '忘了' 去執行一個 call file 時(seen e.g. in 1.0.9). 可能的解法:
  • 1. 找出發生的原因並修正它在原始碼裡,
  • 2. 使用管理API,只能希望它不會再現此問題,
  • 3. 設計一個應用程式來應付此問題,例如計算機查現存的 CDR 資料,比對你的 .call file 細節 (撥打時間,目地,帳號碼等等)。

更多範例



Callfiles 的撥打記錄(Call Detail Records)

  • 避免遺失 CDR 記錄: 方案有二,擇一用之 a) 使用 Context/Extension/Priority 取代 Application/Data 在call file中, b) 使用 Local channel 來取代你想要直接撥打的頻道。 另外 Asterisk will bypass the process that tracks the call and 不會有帳單 CDR record 產生。 當使用了 Context/Extension/Priority, 你真的使用了 Goto 這類的功能,它會將通話放置正確的dialplan區段裡, and to it is the same as if the caller had dialed the call manually and so the call is logged.
  • The phone number you are dialling will not be stored in the CDR by * - if you need this information for CDR processing you can set the CallerID in the call file to this number and it will be stored. However, this will present the person you are calling their own phone number, which doesn't make much sense. A better solution might be to put the number you are dialing in the Set: channel variable in the .call file and later put it into the UserField of the CDR. See example above in the first section.

Tips and hints

  • Create the call file elsewhere, and move it (better not use copy, see above) into the directory after you're done creating it. Asterisk is very aggressive in grabbing these files, and if you're still creating it when it grabs the file, you'll get errors, so best to create first and then copy in to the outgoing directory all at once.
  • The call file must be owned by the user asterisk runs as, so asterisk can utime() it, or you will get permission errors.
  • If you are using POTS (Plain Old Telephone System) lines attached to a channel bank with FXO cards, it's likely that you will run into problems sensing when your callee picks up their phone - especially to cell phones. Once Asterisk hands off a call to an FXO line (ie, it starts to ring), the system counts the call as 'answered', and continues its merry way. This means that your voice prompts get played to a ring tone, and your users are presented with a silent call.
Some things to try:
    • In zapata.conf, try adding callprogress=yes above your channel => n definition for the FXO lines. (remember that settings set above the channel flow down, and that you need to clear this setting with a callprogress=no for any channels you might not want this to affect!)
      • This is experimental, only sometimes works, and only for North American tones.
      • On my system, this setting failed miserably, to the point that I could no longer make outgoing calls, and calls were dropped.
    • Another option (At least in example 3), is to repeat your message. Note the ResponseTimeout(2), to set the pause between repeats to 2 seconds, and the GoTo(s|1), to repeat the prompts.
    • Yet another option is to use an application like "WaitForSilence" that will wait for a certain amount of silence before beginning to play the message. See bugs.digium.com #2467 for this app, which will probably soon appear in CVS.
  • Try app_machinedetect.c application for detection of answering machines. This works best with PRI, VoIP, or a POTS with callprogress enabled. (This will cause a 'dead-air' silent pause at the beginning of all calls and with well-chosen settings will not provide better than 80-90% accuracy.)
  • Be advised that, if you create a new .call file and move it into the outgoing Asterisk directory for processing AND it has the same file name as a .call file which was just processed, Asterisk will throw the new file in the bit bucket.


A Few Ideas

What Can You Do With This Interface?

  • Setup a cron job to dial out at specific times.
  • Stress test your server for call load.
  • Prank call your friends with pre-recorded messages.
  • War dialing.
  • Auto-dialing / telemarketing.
  • Create an alarm program to wake you up in the mornings.
  • Create auto-callback functionality from your extensions.
  • Connect calls between your extension and a number using a web interface / other application.

The possibilities are endless!

Programming Libraries For Creating / Using CallFiles

There are several programming libraries which abstract file operations and simplify the call file process.

  • http://pycall.org|pycall - A flexible python library for creating and using Asterisk callfiles.



See also



Go back to Asterisk
Created by: dominic16y, Last modification: Mon 20 of Jul, 2015 (06:24 UTC)
Please update this page with new information, just login and click on the "Edit" or "Discussion" tab. Get a free login here: Register Thanks! - Find us on Google+