AsteriskのVoicemailで録音電話通知機能を付ける

## 目的

AsteriskのVoicemailでは、メッセージが録音された際にメールで通知する機能がありますが、
電話で通知する機能はありません。

そのため、一工夫して電話で通知が出来るような機能を追加します。

## 環境

- FreeBSD 12.0R
- Asterisk 16.5.1
    - 日本語ガイダンスが入っていることを前提とします。

## 設定

Asteriskの基本的な設定は出来ている前提とします。
ざっくり書くので、細かい部分はケースバイケースで。

```voicemail.conf
[general]
format=wav49|wav

externnotify=/root/asterisk-vm-notify.sh

tz=japan
locale=ja_JP.UTF-8
; メッセージの再生前に発信者の発番号を読み上げるか
saycid=yes
; ボイスメールの応答メッセージ再生中に「0」ダイヤルで、別処理するか
; 今回の設定だと、VoicemailMainに飛ぶようにしています。(外出先からの用件確認を想定)
operator=yes

[zonemessages]
japan=Asia/Tokyo|Q PHM 'jp-ni' 'vm-received'

[default]
2000 => 1234
```

```extensions.conf
[default]
;; 次のオリジナルガイダンスを追加しています。
; prompt-input-notify-number :  通知先電話番号の設定を行います。
; prompt-read-notify-number : 通知先の電話番号の確認を行います。
; input-mailbox-number : メールボックス番号と＃をダイヤルしてください。
; input-notify-number : 通知先の電話番号を市外局番から入力し、最後に＃を田尾UR
; check : 確認します。
; input-check : よろしければ1を、そうで無い場合は0をダイヤルしてください。

; 510で通知先の電話番号を登録
exten => 510,1,Ringing()
same => n,Wait(1)
same => n,Read(MAILBOX,prompt-input-notify-number&input-mailbox-number,11)
same => n,Playback(check)
same => n,SayDigits(${MAILBOX})
same => n(input),Read(NOTIFY_NUMBER,input-notify-number)
same => n,Playback(check)
same => n,SayDigits(${NOTIFY_NUMBER})
same => n,Read(CHECK,input-check,1)
same => n,GotoIf($[${CHECK} == 1]?:input)
same => n,Set(DB(vm-notify-number/${MAILBOX})=${NOTIFY_NUMBER})
same => n,Playback(privacy-thankyou)
same => n,Hangup()

; 511で通知先の電話番号を確認
exten => 511,1,Ringing()
same => n,Wait(1)
same => n,Read(MAILBOX,prompt-read-notify-number&input-mailbox-number,11)
same => n,Set(NOTIFY_NUMBER=${DB(vm-notify-number/${MAILBOX})})
same => n,SayDigits(${NOTIFY_NUMBER}))
same => n,Hangup()

; 52-2000でボイスメールの確認
exten => 522000,VoicemailMain(2000)
; 59-2000でボイスメール応答
exten => 592000,1,Gosub(vm-incoming,s,1(2000))

[vm-incoming]
exten => s,1,Ringing()
same => n,Wait(2)
same => n,Voicemail(${ARG1},su)
same => n,Hangup()

; Operator Mode
; ボイスメールで応答メッセージ再生中に飛んでくるExtensionです。
; 今回は、外出先からの用件確認を想定し、VoicemailMainに飛ばしています。
exten => o,1,VoicemailMain(${ARG1})
same => n,Hangup()

[vm-notify]
; Voicemail Notify Extension
; ボイスメールの通知時に、接続されるExtensionです。

exten => _X.,1,Ringing()
same => n,Wait(2)
; No Password Check
same => n,VoicemailMain(${EXTEN},s)
same => n,Hangup()
```

```/root/asterisk-vm-notify.sh
#!/bin/sh

# FreeBSDで使っているので、Linuxでは変更必要だと思います。

## args:default [MailBox] [NewMessageCount] 0 0
# DEBUG
#echo $@ >> /tmp/vm

if [ $# -ne 5 ]; then
        echo 'params error'
        exit
fi

if [ $3 -eq 0 ]; then
        echo 'no new message'
        exit
fi

OUTGOING=/var/spool/asterisk/outgoing/

FAMILY=vm-notify-number
KEY=$2
CMD="asterisk -r -x 'database get ${FAMILY} ${KEY}' | sed 's/^Value: //'"

NOTIFY_DIAL=$(eval $CMD)
# DEBUG
#echo $FAMILY
#echo $KEY
#echo "NOTIFY DIAL:$NOTIFY_DIAL"

if [ "$NOTIFY_DIAL" = "Database entry not found." ]; then
        echo 'no notify dial'
        exit
fi

# 0始まりの番号の場合は、先頭に0付加(0発信想定)
FIRST_DIAL=`echo $NOTIFY_DIAL | cut -c 1`
echo $FIRST_DIAL
if [ "${FIRST_DIAL}" = "0" ]; then
        NOTIFY_DIAL=0${NOTIFY_DIAL}
fi

TMP=/tmp/vm$$.tmp
cat <<EOS > $TMP
Channel: PJSIP/$NOTIFY_DIAL@trunk
CallerID: "XXXXXXXXXX" <XXXXXXXXXX>
MaxRetries: 3
RetryTime: 180
WaitTime: 60
Context: vm-notify
Extension: $2
Priority: 1
EOS

#cat $TMP
mv $TMP $OUTGOING
```