หน้า 1 จากทั้งหมด 1

เทคนิคให้พูดทวนเบอร์ Extension ที่เรากด ก่อนโทรหาเบอร์นั้น

โพสต์โพสต์แล้ว: 08 ก.ย. 2012 17:17
โดย nuiz
บทความนี้จะทำให้ Elastix บอกเบอร์ Extension ที่เรากด ก่อนจะ Dial ไปหาเบอร์ๆนั้น เช่น เมื่อเรากดเบอร์ 1100 จะมีเสียงบอกว่า one one zero zero หรือ หนึ่ง หนึ่ง ศูนย์ ศูนย์ และตอนท้ายของบทความจะมีเสียงบอกว่า หมายเลข หนึ่ง หนึ่ง ศูนย์ ศูนย์ กรุณาถือสายรอสักครู

ใช้คำสั่งพระเอกครับ 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