I have a PHP script that generates a call file when an incoming SMS is received. All works well, with the exception if the SMS text includes special characters like new-line, line-feed or semicolon ‘;’.
My question is how do I “escape” such characters in the call file? (I have figured out that I can escape semicolon using ‘\;’)
The call file below will only pass the first line to the endpoint and then asterisk will complain:
pbx_spool.c:208 in parse_line: Syntax error at line 13
Channel: Local/12025550183@dp_entry_channel_open
CallerID: "" <12025550160>
WaitTime: 60
MaxRetries: 100
RetryTime: 300
Context: dp_entry_trunk_texting
Extension: 12025550183
Priority: 1
Archive: yes
setvar: MESSAGE(to)=12025550183
setvar: MESSAGE(from)=12025550160
setvar: MESSAGE(body)=This is the first line of the SMS
This is the second line of the SMS
This is the third line of the SMS
Yes, but with what? A simple but unsatisfactory solution is just to remove the new-lines. But what do I do if I want to keep the format of the original
message?
No. I’m suggesting that you use code in the application that you write that consumes the string, as anything done in dialplan will have the same problem, the inability to place newlines in variables.
You would need to rewrite MessaageSend itself, as MyMessageSend
Whilst is is possible that you could write a MySet that did the un-escaping, I think you would be in uncharted territory. There might even be code injection risks if you use a variable with actual newlines directly in the dialplan.
Many thanks for all the valuable insights.
I think I now have a new angle to attack this problem.
I will comeback here after i have done some experimentation.
you need to multi-line to single-line for call file.
at this time, you can use a URLEncoder.
when you send a text at dial-plan, you can use URLDecoder.
Yes, that seems to be a very good idea. I have tested that approach and it works great. I will post my solution here once I have cleaned up the code a little.
Should anyone stumble on, and find interest in this topic, I post my solution to the problem with handling the linefeed character in call files below.
The solution is based on encoding the SMS string that is used in the call file. When Asterisk pick up that call file the string is decoded before the SMS is sent to the endpoint.
php code snippet
This piece of code encodes the string to be used in the call file.
/*--------------------------------------------------------------------------
The message cannot span multiple lines in an Asterisk call file. To work
around that we encode the message (RFC3986, which supersedes RFC2396).
@param string $string to escape
@return string escaped string
*/
private function gen_body($string) {
if ($this->config['astqueue']['message_encode'] === 'rfc3986') {
return rawurlencode($string);
} else {
return $string;
}
}
call file
This is an example call file with encoded MESSAGE(body).
This is the subroutine in the dialplan (extensions.conf) that decodes the string.
;-------------------------------- sub_decode_body
; URL decode the MESSAGE(body) subroutine
; Usage: Gosub(sub_decode_body,s,1)
;
; Implementation details
; If MESSAGE_ENCODE = rfc3986 then the MESSAGE(body) is URL encoded
; (using RFC3986 which supersedes RFC2396) in the callfile, so decode it here.
;
[sub_decode_body]
exten => s,1,GotoIf($[ ${MESSAGE_ENCODE} != rfc3986 ]?return)
same => n,Verbose(3,"Original message body ${MESSAGE(body)}")
same => n,Set(MESSAGE(body)=${URIDECODE(${MESSAGE(body)})})
same => n,Verbose(3,"Updated message body ${MESSAGE(body)}")
same => n(return),Return()