「SIPメッセージング」の版間の差分
(→Asteriskでの実装) |
|||
(同じ利用者による、間の6版が非表示) | |||
1行目: | 1行目: | ||
SIPメッセージで電話機等でメッセージを交換する方法。ブラウザ等を使えばチャット用にも使える。要するにSMSみたいなもん。 | SIPメッセージで電話機等でメッセージを交換する方法。ブラウザ等を使えばチャット用にも使える。要するにSMSみたいなもん。 | ||
=Asteriskでの実装= | =Asteriskでの実装= | ||
− | + | Asteriskは音声通話のみならずSIPメッセージの『交換』にも使えます。実はextensionsの記述でテキストメッセージの配送や処理も行えるのです。 | |
+ | |||
+ | =SIP MESSAGE= | ||
+ | MESSAGE sip:1000@192.168.254.234 SIP/2.0 | ||
+ | Via: SIP/2.0/WSS 192.0.2.191;received=192.168.254.30;branch=z9hG4bK1314248 | ||
+ | To: <sip:1000@192.168.254.234> | ||
+ | From: "TAKAHASHI,Takao" <sip:phone33@192.168.254.234>;tag=7m8l4i50nj | ||
+ | CSeq: 1 MESSAGE | ||
+ | Call-ID: glia153j7er66kd35o0s | ||
+ | Max-Forwards: 70 | ||
+ | Supported: outbound | ||
+ | User-Agent: Browser Phone 0.3.27 (SIPJS - 0.20.0) Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 | ||
+ | Safari/537.36 | ||
+ | Content-Type: text/plain | ||
+ | Content-Length: 7 | ||
+ | Content-Type: text/plain | ||
+ | Content-Length: 7 | ||
+ | |||
+ | hoge | ||
+ | SIPのMESSAGEによるメッセージ例。 | ||
==チャネル== | ==チャネル== | ||
基本的にエンドポイント同士は通常のPJSIP/phone123のような形式で認識される。ただし接続した際のチャネルが異なり、音声パスではなく ast_message_queue となる。 | 基本的にエンドポイント同士は通常のPJSIP/phone123のような形式で認識される。ただし接続した際のチャネルが異なり、音声パスではなく ast_message_queue となる。 | ||
16行目: | 35行目: | ||
MESSAGE(custom_data) w/o | MESSAGE(custom_data) w/o | ||
mark_all_outbound または clear_all_outbound を指定 | mark_all_outbound または clear_all_outbound を指定 | ||
+ | =応用= | ||
+ | 役に立つのか立たないのかわかりませんが、SIPメッセージで受信した内容に応じて処理する例。ブラウザフォン等のメッセージでの問い合わせに応答させる例。 | ||
+ | ==内線として実装する== | ||
+ | まず、この応答処理を内線として定義します。音声で呼ばれた場合は応答して切りますが、自分宛てのSIPメッセージだった場合にはメッセージ処理へ飛びます。 | ||
+ | exten => 1000,1,NoOp | ||
+ | exten => 1000,n,Set(MTARGET=${EXTEN}) | ||
+ | exten => 1000,n,GotoIf($["${CHANNEL(name)}"="Message/ast_msg_queue"]?msgdispatch,s,1) | ||
+ | exten => 1000,n,Answer | ||
+ | exten => 1000,n,Morsecode(S) | ||
+ | exten => 1000,n,Hangup | ||
+ | ==メッセージ処理== | ||
+ | メッセージ本体(body)の最初の項目をサービス名、残りを引数と解釈するディスパッチャを用意します。あわせてメッセージの打ち返し先も組み立てておきます。各サービスからの返値は変数、RETVに入っているものとします。 | ||
+ | [msgdispatch] | ||
+ | ;サービス毎に分岐させ返値を送り返す | ||
+ | exten => s,1,NoOp | ||
+ | ;送り先(戻し先)をfromから取得 | ||
+ | exten => s,n,Set(SBACK=${CUT(MESSAGE(from),@,1)}) | ||
+ | exten => s,n,Set(SBACK=${CUT(SBACK,:,2)}) | ||
+ | ;ドメインを送り元から取得 | ||
+ | exten => s,n,Set(SDOM=${CUT(MESSAGE(from),@,2)}) | ||
+ | exten => s,n,Set(SDOM=${CUT(SDOM,>,1)}) | ||
+ | ;メッセージ本体の頭の部分をサービス名として取得 | ||
+ | exten => s,n,Set(SVC=${CUT(MESSAGE(body), ,1)}) | ||
+ | exten => s,n,Set(SVC=${TOLOWER(${SVC})}) | ||
+ | ;サービスに渡す内容はスペースの後ろ | ||
+ | exten => s,n,Set(CONTENT=${CUT(MESSAGE(body), ,2-)}) | ||
+ | ;サービスに応じてサブルーチンコール | ||
+ | exten => s,n,Gosub(sub-msg-${SVC},s,1) | ||
+ | ;返値をメッセージの本体にする | ||
+ | exten => s,n,Set(MESSAGE(body)=${RETV}) | ||
+ | ;メッセージを打ち返す | ||
+ | exten => s,n,MessageSend(pjsip:${SBACK},${MTARGET},sip:${SBACK}@${SDOM}) | ||
+ | exten => s,n,Hangup | ||
+ | ==各サービス処理== | ||
+ | 各サービスは sub-msg-サービス名 というかたちでコールされるので必要な処理を用意します。<br> | ||
+ | 以下の例ではAsteriskのMATH()、コマンドのuptimeとexprを定義しています。 | ||
+ | [sub-msg-math] | ||
+ | exten => s,1,NoOp(MATH) | ||
+ | exten => s,n,Set(RETV=${MATH(${CONTENT},int)}) | ||
+ | exten => s,n,Return | ||
+ | |||
+ | [sub-msg-uptime] | ||
+ | exten => s,1,NoOp(UPTIME) | ||
+ | exten => s,n,Set(RETV=${SHELL(uptime)}) | ||
+ | exten => s,n,Return | ||
+ | |||
+ | [sub-msg-expr] | ||
+ | exten => s,1,NoOp(EXPR) | ||
+ | exten => s,n,Set(RETV=${SHELL(expr ${CONTENT})}) | ||
+ | exten => s,n,Return | ||
+ | ==使い方== | ||
+ | ブラウザフォン等のSIPメッセージで uptime を送るとuptmeの結果が送られてきます。math 1+1 を送るとAsteriskのMATH()で計算されて2が送られてきます。<br> | ||
+ | [[画像:BP SIP MSG241030.png | 640px]]<br> | ||
+ | こんな感じで、Asteriskを使ってメッセージ処理をすることができます。 |
2024年10月30日 (水) 17:41時点における最新版
SIPメッセージで電話機等でメッセージを交換する方法。ブラウザ等を使えばチャット用にも使える。要するにSMSみたいなもん。
目次
Asteriskでの実装
Asteriskは音声通話のみならずSIPメッセージの『交換』にも使えます。実はextensionsの記述でテキストメッセージの配送や処理も行えるのです。
SIP MESSAGE
MESSAGE sip:1000@192.168.254.234 SIP/2.0 Via: SIP/2.0/WSS 192.0.2.191;received=192.168.254.30;branch=z9hG4bK1314248 To: <sip:1000@192.168.254.234> From: "TAKAHASHI,Takao" <sip:phone33@192.168.254.234>;tag=7m8l4i50nj CSeq: 1 MESSAGE Call-ID: glia153j7er66kd35o0s Max-Forwards: 70 Supported: outbound User-Agent: Browser Phone 0.3.27 (SIPJS - 0.20.0) Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Content-Type: text/plain Content-Length: 7 Content-Type: text/plain Content-Length: 7 hoge
SIPのMESSAGEによるメッセージ例。
チャネル
基本的にエンドポイント同士は通常のPJSIP/phone123のような形式で認識される。ただし接続した際のチャネルが異なり、音声パスではなく ast_message_queue となる。
${CHANNEL(name)} = Message/ast_msg_queue
SIPでメッセージを受け取ると上記のようなチャネル名となるので、これを判断することで音声通話ではなくSIPメッセージあると判断できる。
メッセージ本体
ファンクションMESSAGE()がメッセージ自体のハンドリングを行う。
MESSAGE(from) r/w
送信元
MESSAGE(to) r/w
送信先
MESSAGE(body) r/w
メッセージの実体
MESSAGE(custom_data) w/o
mark_all_outbound または clear_all_outbound を指定
応用
役に立つのか立たないのかわかりませんが、SIPメッセージで受信した内容に応じて処理する例。ブラウザフォン等のメッセージでの問い合わせに応答させる例。
内線として実装する
まず、この応答処理を内線として定義します。音声で呼ばれた場合は応答して切りますが、自分宛てのSIPメッセージだった場合にはメッセージ処理へ飛びます。
exten => 1000,1,NoOp exten => 1000,n,Set(MTARGET=${EXTEN}) exten => 1000,n,GotoIf($["${CHANNEL(name)}"="Message/ast_msg_queue"]?msgdispatch,s,1) exten => 1000,n,Answer exten => 1000,n,Morsecode(S) exten => 1000,n,Hangup
メッセージ処理
メッセージ本体(body)の最初の項目をサービス名、残りを引数と解釈するディスパッチャを用意します。あわせてメッセージの打ち返し先も組み立てておきます。各サービスからの返値は変数、RETVに入っているものとします。
[msgdispatch] ;サービス毎に分岐させ返値を送り返す exten => s,1,NoOp ;送り先(戻し先)をfromから取得 exten => s,n,Set(SBACK=${CUT(MESSAGE(from),@,1)}) exten => s,n,Set(SBACK=${CUT(SBACK,:,2)}) ;ドメインを送り元から取得 exten => s,n,Set(SDOM=${CUT(MESSAGE(from),@,2)}) exten => s,n,Set(SDOM=${CUT(SDOM,>,1)}) ;メッセージ本体の頭の部分をサービス名として取得 exten => s,n,Set(SVC=${CUT(MESSAGE(body), ,1)}) exten => s,n,Set(SVC=${TOLOWER(${SVC})}) ;サービスに渡す内容はスペースの後ろ exten => s,n,Set(CONTENT=${CUT(MESSAGE(body), ,2-)}) ;サービスに応じてサブルーチンコール exten => s,n,Gosub(sub-msg-${SVC},s,1) ;返値をメッセージの本体にする exten => s,n,Set(MESSAGE(body)=${RETV}) ;メッセージを打ち返す exten => s,n,MessageSend(pjsip:${SBACK},${MTARGET},sip:${SBACK}@${SDOM}) exten => s,n,Hangup
各サービス処理
各サービスは sub-msg-サービス名 というかたちでコールされるので必要な処理を用意します。
以下の例ではAsteriskのMATH()、コマンドのuptimeとexprを定義しています。
[sub-msg-math] exten => s,1,NoOp(MATH) exten => s,n,Set(RETV=${MATH(${CONTENT},int)}) exten => s,n,Return [sub-msg-uptime] exten => s,1,NoOp(UPTIME) exten => s,n,Set(RETV=${SHELL(uptime)}) exten => s,n,Return [sub-msg-expr] exten => s,1,NoOp(EXPR) exten => s,n,Set(RETV=${SHELL(expr ${CONTENT})}) exten => s,n,Return
使い方
ブラウザフォン等のSIPメッセージで uptime を送るとuptmeの結果が送られてきます。math 1+1 を送るとAsteriskのMATH()で計算されて2が送られてきます。
こんな感じで、Asteriskを使ってメッセージ処理をすることができます。