ใช้คำสั่งพระเอกครับ SayDigits
ก๊อบปี้ Dialplan ต่อไปนี้ ไปวางไว้ในไฟล์ /etc/asterisk/extensions_override_elastix.conf เอาไว้บนสุดของไฟล์เลยก็ได้
** Dialplan นี้ปลอดภัยครับ ผมก๊อบมาจากไฟล์ /etc/asterisk/extensions_additional.conf **
- โค้ด: เลือกทั้งหมด
[macro-dial-one]
include => macro-dial-one-custom
exten => s,1,Set(DEXTEN=${ARG3})
;exten => s,n,SayDigits(${EXTEN:0})
exten => s,n,Set(DIALSTATUS_CW=)
exten => s,n,GosubIf($["${FROM_DID}"!="" & "${SCREEN}"="" & "${DB(AMPUSER/${DEXTEN}/screen)}"!=""]?screen,1)
exten => s,n,GosubIf($["${DB(CF/${DEXTEN})}"!=""]?cf,1)
exten => s,n,GotoIf($["${DEXTEN:-1}"="#" | "${DB(DND/${DEXTEN})}"=""]?skip1)
exten => s,n,Set(DEXTEN=)
exten => s,n,Set(DIALSTATUS=BUSY)
exten => s,n(skip1),GotoIf($["${DEXTEN}"=""]?nodial)
exten => s,n,GotoIf($["${DEXTEN:-1}"="#"]?continue)
exten => s,n,Set(EXTHASCW=${IF($["${CWIGNORE}"!=""]?"":${DB(CW/${DEXTEN})})})
exten => s,n,GotoIf($["${EXTHASCW}"="" | "${DB(CFB/${DEXTEN})}"!="" | "${DB(CFU/${DEXTEN})}"!=""]?next1:cwinusebusy)
exten => s,n(next1),GotoIf($["${DB(CFU/${DEXTEN})}"!="" & ("${EXTENSION_STATE(${DEXTEN})}"="UNAVAILABLE" | "${EXTENSION_STATE(${DEXTEN})}"="UNKNOWN")]?docfu:skip3)
exten => s,n(docfu),Set(DEXTEN=)
exten => s,n,Set(DIALSTATUS=NOANSWER)
exten => s,n,Goto(nodial)
exten => s,n(skip3),GotoIf($["${EXTHASCW}"="" | "${DB(CFB/${DEXTEN})}"!=""]?next2:continue)
exten => s,n(next2),GotoIf($["${EXTENSION_STATE(${DEXTEN})}"="NOT_INUSE" | "${EXTENSION_STATE(${DEXTEN})}"="UNAVAILABLE" | "${EXTENSION_STATE(${DEXTEN})}"="UNKNOWN"]?continue)
exten => s,n,ExecIf($["${DB(CFB/${DEXTEN})}"!="" & "${CFIGNORE}"=""]?Set(DIALSTATUS=BUSY))
exten => s,n,GotoIf($["${EXTHASCW}"!="" | "${DEXTEN:-1}"="#"]?cwinusebusy)
exten => s,n,Set(DEXTEN=)
exten => s,n,Set(DIALSTATUS=BUSY)
exten => s,n,Goto(nodial)
exten => s,n(cwinusebusy),GotoIf($["${EXTHASCW}"!="" & "${CWINUSEBUSY}"!=""]?next3:continue)
exten => s,n(next3),ExecIf($["${EXTENSION_STATE(${DEXTEN})}"!="UNAVAILABLE" & "${EXTENSION_STATE(${DEXTEN})}"!="NOT_INUSE" & "${EXTENSION_STATE(${DEXTEN})}"!="UNKNOWN"]?Set(DIALSTATUS_CW=BUSY))
exten => s,n(continue),GotoIf($["${DEXTEN}"=""]?nodial)
exten => s,n,GosubIf($["${DEXTEN:-1}"!="#"]?dstring,1:dlocal,1)
exten => s,n,GotoIf($[${LEN(${DSTRING})}=0]?nodial)
exten => s,n,GotoIf($["${DEXTEN:-1}"="#"]?skiptrace)
exten => s,n,GosubIf($[${REGEX("^[\+]?[0-9]+$" ${CALLERID(number)})} = 1]?ctset,1:ctclear,1)
exten => s,n(skiptrace),Set(D_OPTIONS=${IF($["${NODEST}"!="" & ${REGEX("(M[(]auto-blkvm[)])" ${ARG2})} != 1]?${ARG2}M(auto-blkvm):${ARG2})})
exten => s,n,ExecIf($["${ALERT_INFO}"!=""]?SIPAddHeader(Alert-Info: ${ALERT_INFO}))
exten => s,n,ExecIf($["${SIPADDHEADER}"!=""]?SIPAddHeader(${SIPADDHEADER}))
exten => s,n,ExecIf($["${MOHCLASS}"!=""]?Set(CHANNEL(musicclass)=${MEETME_MUSIC}))
exten => s,n,GosubIf($["${QUEUEWAIT}"!=""]?qwait,1)
exten => s,n,Set(__CWIGNORE=${CWIGNORE})
exten => s,n,Set(__KEEPCID=TRUE)
exten => s,n,SayDigits(${DSTRING})
exten => s,n,Dial(${DSTRING},${ARG1},${D_OPTIONS})
exten => s,n,ExecIf($["${DIALSTATUS_CW}"!=""]?Set(DIALSTATUS=${DIALSTATUS_CW}))
exten => s,n,GosubIf($["${SCREEN}"!=""|"${DIALSTATUS}"="ANSWER"]?s-${DIALSTATUS},1)
exten => s,n,MacroExit()
exten => s,n(nodial),ExecIf($["${DIALSTATUS}" = ""]?Set(DIALSTATUS=NOANSWER))
exten => s,n,Noop(Returned from dial-one with nothing to call and DIALSTATUS: ${DIALSTATUS})
exten => s,n,MacroExit()
exten => h,1,Macro(hangupcall,)
exten => screen,1,GotoIf($["${DB(AMPUSER/${DEXTEN}/screen)}"!="nomemory" | "${CALLERID(number)}"=""]?memory)
exten => screen,n,ExecIf($[${REGEX("^[0-9a-zA-Z ]+$" ${CALLERID(number)})} = 1]?System(rm -f ${ASTVARLIBDIR}/sounds/priv-callerintros/${CALLERID(number)}.*))
exten => screen,n(memory),Set(__SCREEN=${DB(AMPUSER/${DEXTEN}/screen)})
exten => screen,n,Set(__SCREEN_EXTEN=${DEXTEN})
exten => screen,n,Set(ARG2=${ARG2}p)
exten => screen,n,Return()
exten => cf,1,Set(CFAMPUSER=${IF($["${AMPUSER}"=""]?${CALLERID(number)}:${AMPUSER})})
exten => cf,n,ExecIf($["${DB(CF/${DEXTEN})}"="${CFAMPUSER}" | "${DB(CF/${DEXTEN})}"="${REALCALLERIDNUM}" | "${CUT(CUT(BLINDTRANSFER,-,1),/,1)}" = "${DB(CF/${DEXTEN})}" | "${DEXTEN}"="${DB(CF/${DEXTEN})}"]?Return())
exten => cf,n,Set(DEXTEN=${IF($["${CFIGNORE}"=""]?"${DB(CF/${DEXTEN})}#":"")})
exten => cf,n,ExecIf($["${DEXTEN}"!=""]?Return())
exten => cf,n,Set(DIALSTATUS=NOANSWER)
exten => cf,n,Return()
exten => qwait,1,ExecIf($["${SAVEDCIDNAME}" = ""]?Set(__SAVEDCIDNAME=${CALLERID(name)}))
exten => qwait,n,Set(ELAPSED=${MATH($[${EPOCH}+30-${QUEUEWAIT}]/60,int)})
exten => qwait,n,Set(CALLERID(name)=M${ELAPSED}:${SAVEDCIDNAME})
exten => qwait,n,Return()
exten => ctset,1,Set(DB(CALLTRACE/${DEXTEN})=${CALLERID(number)})
exten => ctset,n,Return()
exten => ctclear,1,Noop(Deleting: CALLTRACE/${DEXTEN} ${DB_DELETE(CALLTRACE/${DEXTEN})})
exten => ctclear,n,Return()
exten => dstring,1,Set(DSTRING=)
exten => dstring,n,Set(DEVICES=${DB(AMPUSER/${DEXTEN}/device)})
exten => dstring,n,ExecIf($["${DEVICES}"=""]?Return())
exten => dstring,n,ExecIf($["${DEVICES:0:1}"="&"]?Set(DEVICES=${DEVICES:1}))
exten => dstring,n,Set(LOOPCNT=${FIELDQTY(DEVICES,&)})
exten => dstring,n,Set(ITER=1)
exten => dstring,n(begin),Set(THISDIAL=${DB(DEVICE/${CUT(DEVICES,&,${ITER})}/dial)})
exten => dstring,n,GosubIf($["${ASTCHANDAHDI}" != ""]?zap2dahdi,1)
exten => dstring,n,Set(DSTRING=${DSTRING}${THISDIAL}&)
exten => dstring,n,Set(ITER=$[${ITER}+1])
exten => dstring,n,GotoIf($[${ITER}<=${LOOPCNT}]?begin)
exten => dstring,n,Set(DSTRING=${DSTRING:0:$[${LEN(${DSTRING})}-1]})
exten => dstring,n,Return()
exten => dlocal,1,Set(DSTRING=Local/${DEXTEN:0:${MATH(${LEN(${DEXTEN})}-1,int)}}@from-internal/n)
exten => dlocal,n,Return()
exten => zap2dahdi,1,ExecIf($["${THISDIAL}" = ""]?Return())
exten => zap2dahdi,n,Set(NEWDIAL=)
exten => zap2dahdi,n,Set(LOOPCNT2=${FIELDQTY(THISDIAL,&)})
exten => zap2dahdi,n,Set(ITER2=1)
exten => zap2dahdi,n(begin2),Set(THISPART2=${CUT(THISDIAL,&,${ITER2})})
exten => zap2dahdi,n,ExecIf($["${THISPART2:0:3}" = "ZAP"]?Set(THISPART2=DAHDI${THISPART2:3}))
exten => zap2dahdi,n,Set(NEWDIAL=${NEWDIAL}${THISPART2}&)
exten => zap2dahdi,n,Set(ITER2=$[${ITER2} + 1])
exten => zap2dahdi,n,GotoIf($[${ITER2} <= ${LOOPCNT2}]?begin2)
exten => zap2dahdi,n,Set(THISDIAL=${NEWDIAL:0:$[${LEN(${NEWDIAL})}-1]})
exten => zap2dahdi,n,Return()
exten => s-NOANSWER,1,Macro(vm,${SCREEN_EXTEN},BUSY,${IVR_RETVM})
exten => s-NOANSWER,n,ExecIf($["${IVR_RETVM}"!="RETURN" | "${IVR_CONTEXT}"=""]?Hangup())
exten => s-NOANSWER,n,Return()
exten => s-TORTURE,1,Goto(app-blackhole,musiconhold,1)
exten => s-TORTURE,n,Macro(hangupcall,)
exten => s-DONTCALL,1,Answer
exten => s-DONTCALL,n,Wait(1)
exten => s-DONTCALL,n,Zapateller()
exten => s-DONTCALL,n,Playback(ss-noservice)
exten => s-DONTCALL,n,Macro(hangupcall,)
; end of [macro-dial-one]
โดยใน dialplan ข้างบนผมได้แทรกบรรทัด
- โค้ด: เลือกทั้งหมด
exten => s,n,SayDigits(${DSTRING})
ไว้ก่อนบรรทัด
- โค้ด: เลือกทั้งหมด
exten => s,n,Dial(${DSTRING},${ARG1},${D_OPTIONS})
เสร็จแล้วเซฟไฟล์ แล้วรันคำสั่งนี้จาก Linux prompt
- โค้ด: เลือกทั้งหมด
asterisk -rx "dialplan reload"
แล้วลองทดสอบโทรไปเบอร์ Extension อื่นๆดู จะได้ยินเสียงบอกเบอร์ที่เรากดเรียก เป็นภาษาอังกฤษ อ่านต่อไปจะมีวิธีทำให้เป็นภาษาไทยด้วยครับ
เพิ่มเติมอีกนิด ให้มีเสียงพูดเพิ่มเติม
ถ้าอยากให้มีเสียงพูดว่า "หมายเลข" "xxxx" "กรุณาถือสายรอสักครู่" ให้เพิ่มอีก 2 บรรทัดไว้ด้านบนและด้านล่างของบรรทัดคำสั่ง SayDigits ดังนี้
exten => s,n,Playback(custom/ww_number)
exten => s,n,SayDigits(${DSTRING})
exten => s,n,Playback(custom/ww_wait2)
แล้วอัพโหลดไฟล์เสียง (อัดเองครับ) ww_number.wav (เสียงพูดว่า หมายเลข) และ ww_wait2.wav (เสียงพูดว่า กรุณาถือสายรอสักครู่) โดยใช้เมนู System Recordings
เพิ่มเติมอีกนิด เสียงตัวเลขเป็นภาษาไทย
เสียงบอกเบอร์ Extension มันยังเป็นภาษาอังกฤษ ถ้าต้องการเป็นภาษาไทยให้ทำดังนี้
1. อัดเสียงพูดตัวเลขภาษาไทย ตั้งแต่ 0 จนถึง 9 แล้วเซฟไฟล์ชื่อ 0.wav, 2.wav,..., 9.wav
2. แปลงฟอร์แม็ตให้ Asterisk เล่นได้ คือ .wav, 8000 Hz, 16 bit, mono
3. สร้างไดเร็คตอรี่เก็บไฟล์เสียงตัวเลข
- โค้ด: เลือกทั้งหมด
mkdir -p /var/lib/asterisk/sounds/th/digits
4. ใช้โปรแกรม WinSCP หรือ FileZilla อัพโหลดไฟล์เสียงไปไว้ที่ /var/lib/asterisk/sounds/th/digits
5. เข้าหน้าเว็บ Elastix แก้ไขคอนฟิกเบอร์ Extension
บรรทัด Language Code แก้ไข en ให้เป็น th
(เฉพาะเบอร์ Extension ต้นทางที่ต้องการได้ยินเป็นภาษาไทยนะครับ)
เพิ่มเติมอีกนิด ทำให้มีหลายๆภาษา
ถ้าในออฟฟิศมีชาวต่างชาติด้วยและเขาฟังเสียง "หมายเลข" และ "กรุณาถือสายรอสักครู" ไม่ออก ก็ให้อัดเสียงภาษาอังกฤษว่า "extension" และ "please wait for a moment" เซฟเป็นไฟล์ชื่อ extension_x.wav และ please_wait_x.wav แปลงไฟล์ แล้วอัพโหลดเข้าไปไว้ที่ /var/lib/asterisk/sounds/en และทำนองเดียวกันเสียงภาษาไทยด้วย อัพโหลดไปไว้ที่ /var/lib/asterisk/sounds/th
จากนั้นใน Context [macro-dial-one] ให้แก้ไข 2 บรรทัดบนและล่างบรรทัด SayDigits ให้เป็นแบบนี้
- โค้ด: เลือกทั้งหมด
exten => s,n,Playback(extension_x)
exten => s,n,SayDigits(${DSTRING})
exten => s,n,Playback(please_wait_x)
อัพโหลดไฟล์เสียงด้วย WinSCP หรือ FileZilla
จากนั้นแก้ไขบรรทัด Language code ของแต่ละ Extension ให้เป็น en หรือ th ตามคนใช้งาน
หวังว่าคงจะมีประโยชน์แก่ท่านที่อยากจะเพิ่มลูกเล่นให้ Elastix ของตัวเองหรือของลูกค้าได้บ้างนะครับ
บทความที่เกี่ยวข้อง
เทคนิคทำเสียงภาษาไทยด้วย Text to Speech
แปลงไฟล์เสียงสำหรับ Asterisk ด้วยโปรแกรม Cool Edit Pro