We've Moved! Please visit our new and improved forum over at our new portal: https://portal.plumvoice.com/hc/en-us/community/topics

SMS question

Questions and answers about IVR programming for Plum DEV

Moderators: admin, support

aghuber11
Posts: 14
Joined: Tue Jun 21, 2016 1:02 pm

SMS question

Post by aghuber11 »

Hello Plumvoice support staff,

I have a question about your sms messaging.

Would you activate a prompt to send a sms message through a subdialog? (also passing certain variables to the sms app)

I need to use the sms system to collect the email of users and post it into my database when they respond to the message.

Is this possible with the sms system?

Thank you.

support
Posts: 3632
Joined: Mon Jun 02, 2003 3:47 pm
Location: Boston, MA
Contact:

Re: SMS question

Post by support »

Hello,

The <subdialog> tag is only part of our hosting application and does not apply to SMS messaging. To send or receive SMS messages, you will need to use an SMS number from your hosting account with a separate application URL. If you do not currently have any SMS numbers for your account, you can contact provisioning to get them. For more information on SMS, you can find our inbound SMS documentation here and our outbound SMS documentation here.

Regards,
Plum Support

aghuber11
Posts: 14
Joined: Tue Jun 21, 2016 1:02 pm

Re: SMS question

Post by aghuber11 »

Thanks for the response,

I have looked through the documentation but i can't find documentation on how to call the sms script from the VXML document.

Basically I need to send a text message based on the caller id to my application <var name="callID" expr="session.callerid"/>

Passing the params over $_POST shouldnt be hard, but there does not appear to be documentation on how to invoke it from within the VXML document

I also need to send the customer "pin" number as well as the session variable so i can tell my code how to update the correct row when the user responds

Any direction would be appreciated

The only documentation seems to be a response from the server?

Code: Select all

<queue>
  <status>success</status>
  <error/>
  <result>
    <sms_messages>
      <sms_message>
        <sms_message_id>e7f41fdc813d481081ec2840d68838b5</sms_message_id>
        <to>19998881234</to>
        <from>2435678910</from>
        <body>This is a notification</body>
        <request_timestamp>1330464356</request_timestamp>
        <result_url>http://myserver.com/storesmsresults.php<result_url>
        <status>queued</status>
      </sms_message>
    </sms_messages>
  </result>
</queue>

support
Posts: 3632
Joined: Mon Jun 02, 2003 3:47 pm
Location: Boston, MA
Contact:

Re: SMS question

Post by support »

Hello,

SMS messaging uses a separate API from our VXML platform, so any calls to SMS messaging can be done through a PHP script. If you would like to queue a text message from within your VXML document, you could use a <subdialog> tag that sends a $_POST to your separate SMS PHP script. An example of a PHP script that will queue SMS calls is as follows, and more details can be found in our documentation on outbound SMS:

Code: Select all

<?php
header("Content-type: text/xml");

$params['to'] = "19998881234";
$params['from'] = "2435678910";
$params['body'] = "This is a notification.";
$params['result_url'] = "http://myserver.com/storesmsresults.php";

// initialize curl
$ch = curl_init();

// set necessary curl options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_URL, "http://hosting.plumgroup.com/ws/sms/queue.xml");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, "username:password");

echo(curl_exec($ch));

curl_close($ch);
?>
Here, you would replace the different values in $params with the number you're sending the text to, your SMS number, the body of your text, and your result URL, respectively. You would also replace the CURLOPT_USERPWD value with your hosting username and password in that format. The response from the server you are referencing in your post could then be parsed by the script referenced by your result URL. An example of a result URL script could be as follows:

Code: Select all

<?php
// make sure the log file has read/write permissions from the web server
$logfile = "logs/smsresults.log"
if (!is_readable($logfile) || !is_writable($logfile)) {
  die("Unable to write to log file.");
}

if (isset($_POST['sms_message_id'], $_POST['status'])) {
  if ($fp = fopen($logfile, 'a+')) {
    $date = date("r");
    $message_id = $_POST['sms_message_id'];
    $status = $_POST['status'];
    fwrite($fp, "$date $message_id $status\n");
    fclose($fp);
  }
}
?>
Regards,
Plum Support

aghuber11
Posts: 14
Joined: Tue Jun 21, 2016 1:02 pm

Re: SMS question

Post by aghuber11 »

Great,

Thank you for the response. All i needed was how to call to it from the VXML document.

I really appreciate the thorough answer on how it all works

aghuber11
Posts: 14
Joined: Tue Jun 21, 2016 1:02 pm

Re: SMS question

Post by aghuber11 »

Hello,

So i'm having a small amount of difficulty getting this script to accept post parameters.

I need it to be able to catch the caller ID of the user so that the script knows who to send the text to.

In the page before im catching the variable here like this.

Code: Select all

<var name="callID" expr="session.callerid"/>
Sending it in the sub-dialog like this

Code: Select all

<form id="mobile">
        <subdialog src="smsscript.php" namelist="pin_number callID" name="sendtext">
        </subdialog>
        <goto next="#skip"></goto>
        </form>
And catching it in the cURL like this.

Code: Select all

$pinnum = $_POST['pin_number'];
$params['to'] = $_POST['callID'];
$params['from'] = "16172075679";
$params['body'] = "Please Respond To This Text Message With Your Email Address So We Can Better Serve You.";
$params['result_url'] = "http://hubenterprises.com.mx/ParseSMSresponse.php";
This is the server response

failureInvalid "to" phone number


What am i missing here?

on a side note here is the full source code so if needed you can reference it.

start.php

Code: Select all

<?php
  header("Content-type: text/xml");
  echo "<?xml version=\"1.0\"?>\n";
?>
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml">
  <var name="pin_number"/>
  <var name="first"/>
  <var name="last"/>
  <!--<var name="mobileNum"/>-->
  <var name="M_Income"/>
  <var name="credit_score"/>
  <var name="callID" expr="session.callerid"/>
  <log expr="callID"/>
      <form>
        <field name="pin" type="digits">
          <prompt>Thank you for calling abc.com. Please enter your pin using your keypad.
          </prompt>
          <filled>
            <assign name="pin_number" expr="pin"/>
          </filled>
        </field>
       <subdialog name="result" src="subdialog.php" namelist="pin_number">
         <filled>
           Thank you.
          <assign name="first" expr="result.first"/>
          <assign name="last" expr="result.last"/>
          <goto next="#mainmenu"></goto>
         </filled>
       </subdialog>
       </form>
       <menu id="mainmenu">
       <prompt>
         if this is a mobile phone press 1

         if this is a lan line press 2
       </prompt>
       <choice dtmf="1" next="#mobile">
        Sales</choice>
       <choice dtmf="2" next="#skip">
        Tech Support</choice>
       </menu>
      <form id="mobile">
        <subdialog src="smsscript.php" namelist="callID" name="sendtext"/>
        <block>
          thank you
          <goto next="#skip"/>
        </block>

        </form>
      <form id="skip">
       <field name="income" type="digits" id="income">
         <prompt>
           Please use your keypad to input your monthly income.
         </prompt>
         <filled>
           <assign name="M_Income" expr="income"/>
         </filled>
       </field>
    <field name="credit" value="dtmf" type="digits?maxlength=3">
      <prompt>
        Please use your keypad to input your credit rating.
      </prompt>
      <filled>
        <assign name="credit_score" expr="credit"/>
        <log expr="pin_number"/>
        <!--<log expr="mobileNum"/>-->
        <log expr="M_Income"/>
        <log expr="first"/>
        <log expr="last"/>
        <log expr="credit_score"/>
        <log expr="callID"/>
        <submit next="process_request.php" method="post" namelist="pin_number M_Income credit_score callID" fetchtimeout="60s" enctype="multipart/form-data"/>
      </filled>
    </field>
    </form>
  </vxml>
smsscript.php

Code: Select all

<?php
header("Content-type: text/xml");
echo("<?xml version=\"1.0\"?>\n");
?>
<?
$caller = $_POST['callID'];
$params['to'] = "18159856396";
$params['from'] = "16172075679";
$params['body'] = "Please Respond To This Text Message With Your Email Address So We Can Better Serve You.";
$params['result_url'] = "http://hubenterprises.com.mx/ParseSMSresponse.php";


// initialize curl
$ch = curl_init();

// set necessary curl options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_URL, "http://hosting.plumgroup.com/ws/sms/queue.xml");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, "username:password");

echo(curl_exec($ch));

curl_close($ch);
?>
<vxml version="2.0">
  <form>
      <block>
          Ok. We are about to send you a text message. Please respond to it after the call so we can better collect your information.
        <return />
     </block>
  </form>
</vxml>

support
Posts: 3632
Joined: Mon Jun 02, 2003 3:47 pm
Location: Boston, MA
Contact:

Re: SMS question

Post by support »

Hello,

When using the <subdialog> tag, the default request method is "get". To change it to "post", you should alter it as follows:

Code: Select all

<subdialog src="smsscript.php" namelist="pin_number callID" name="sendtext" method="post">
Regards,
Plum Support

aghuber11
Posts: 14
Joined: Tue Jun 21, 2016 1:02 pm

Re: SMS question

Post by aghuber11 »

I appreciate the response,

The real question i need answered however is am i catching it correctly in the script that sends sms?

I need it to be sent to whoever is calling in. This should work. But it doesn't register the $_POST parameter to send the test message to.

Also i keep getting a parse error when attempting to use the sms messaging system.

As i stated earlier.. this is the script that should be catching it.

Code: Select all

<?php
header("Content-type: text/xml");

$CALLER = $_POST['callID'];
$params['to'] = $CALLER;
$params['from'] = "16172075679";
$params['body'] = "Please Respond To This Text Message With Your Email Address So We Can Better Serve You.";
$params['result_url'] = "http://hubenterprises.com.mx/ParseSMSresponse.php";


// initialize curl
$ch = curl_init();

// set necessary curl options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_URL, "http://hosting.plumgroup.com/ws/sms/queue.xml");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, "username:password");

echo(curl_exec($ch));

curl_close($ch);
?>

support
Posts: 3632
Joined: Mon Jun 02, 2003 3:47 pm
Location: Boston, MA
Contact:

Re: SMS question

Post by support »

Hi,

From our understanding, you were having problems with obtaining your $_POST variable "callID" in your smsscript.php script. One reason for this could be because you are not specifying that you would like to use the "post" method when using your subdialog tag. Your parse error when using the SMS system may also be because you are not obtaining the "callID" $_POST variable and are trying to use it as your "to" phone number. If you add the attribute method="post" to your subdialog tag, that should help with obtaining the $_POST variable in your PHP script. If we are misunderstanding your questions, please let us know.

Regards,
Plum Support

aghuber11
Posts: 14
Joined: Tue Jun 21, 2016 1:02 pm

Re: SMS question

Post by aghuber11 »

Nope sir,

I added the proper post format to the subdialog.

I'm still getting a badfetch error when i attempt to invoke the subdialog. And further strangeness, the VXML validator doesn't even show that my first page start.php is valid VXML but when i test it the application runs fine up until i try to invoke the subdialog.

Help!

Start.php

Code: Select all

<?php
  header("Content-type: text/xml");
  echo "<?xml version=\"1.0\"?>\n";
?>
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml">
  <var name="pin_number"/>
  <var name="first"/>
  <var name="last"/>
  <!--<var name="mobileNum"/>-->
  <var name="M_Income"/>
  <var name="credit_score"/>
  <var name="callID" expr="session.callerid"/>
  <!--<log expr="callID"/>-->

      <form>
        <field name="pin" type="digits">
          <prompt>Thank you for calling abc.com. Please enter your pin using your keypad.
          </prompt>
          <filled>
            <assign name="pin_number" expr="pin"/>
          </filled>
        </field>
       <subdialog name="result" src="subdialog.php" namelist="pin_number">
         <filled>
           Thank you.
          <assign name="first" expr="result.first"/>
          <assign name="last" expr="result.last"/>
          <goto next="#mainmenu"></goto>
         </filled>
       </subdialog>
       </form>

       <menu id="mainmenu">
       <prompt>
         if this is a mobile phone press 1

         if this is a lan line press 2
       </prompt>
       <choice dtmf="1" next="#mobile">
        Sales</choice>
       <choice dtmf="2" next="#skip">
        Tech Support</choice>
       </menu>

       <form id="mobile">
        <subdialog src="smsscript.php" namelist="callID" name="sendtext" method="post"/>
        <block>
          thank you
          <goto next="#skip"/>
        </block>
        </form>

      <form id="skip">
       <field name="income" type="digits">
         <prompt>
           Please use your keypad to input your monthly income.
         </prompt>
         <filled>
           <assign name="M_Income" expr="income"/>
         </filled>
       </field>

    <field name="credit" type="digits?maxlength=3">
      <prompt>
        Please use your keypad to input your credit rating.
      </prompt>
      <filled>
        <assign name="credit_score" expr="credit"/>
        <!--<log expr="pin_number"/>
        <log expr="mobileNum"/>
        <log expr="M_Income"/>
        <log expr="first"/>
        <log expr="last"/>
        <log expr="credit_score"/>
        <log expr="callID"/>-->
        <submit next="process_request.php" method="post" namelist="pin_number M_Income credit_score callID" fetchtimeout="60s" enctype="multipart/form-data"/>
      </filled>
     </field>
    </form>
  </vxml>
This is the subdialog i am referring to.

Code: Select all

 
<form id="mobile">
        <subdialog src="smsscript.php" namelist="callID" name="sendtext" method="post"/>
        <block>
          thank you
          <goto next="#skip"/>
        </block>
        </form>
smsscript.php

Code: Select all

<?php
header("Content-type: text/xml");

$CALLER = $_POST['callID'];
$params['to'] = $CALLER;
$params['from'] = "16172075679";
$params['body'] = "Please Respond To This Text Message With Your Email Address So We Can Better Serve You.";
$params['result_url'] = "http://hubenterprises.com.mx/ParseSMSresponse.php";


// initialize curl
$ch = curl_init();

// set necessary curl options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_URL, "http://hosting.plumgroup.com/ws/sms/queue.xml");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, "username:password");

echo(curl_exec($ch));

curl_close($ch);
?>
also since i'm asking in the sms script, where would i put the return tag? below the php like this?

<vxml>
<form>
<block>
<return />
</block>
</form>
</vxml>

support
Posts: 3632
Joined: Mon Jun 02, 2003 3:47 pm
Location: Boston, MA
Contact:

Re: SMS question

Post by support »

Hi,

The badfetch error you are seeing is because your subdialog is not returning VXML. You should add something like this below the PHP in smsscript.php:

Code: Select all

<vxml version="2.0">
  <form>
    <block>
      <return namelist=""/>
    </block>
  </form>
</vxml>
Regards,
Plum Support

support
Posts: 3632
Joined: Mon Jun 02, 2003 3:47 pm
Location: Boston, MA
Contact:

Re: SMS question

Post by support »

Hi,

We've modified your script to only execute the part you were having issues with, but this should be working now.

Start.php

Code: Select all

<?php
  header("Content-type: text/xml");
  echo "<?xml version=\"1.0\"?>\n";
?>
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml">
  <var name="pin_number"/>
  <var name="first"/>
  <var name="last"/>
  <!--<var name="mobileNum"/>-->
  <var name="M_Income"/>
  <var name="credit_score"/>
  <var name="callID" expr="session.telephone.ani"/>
  <!--<log expr="callID"/>-->

      <form>
        <field name="pin" type="digits">
          <prompt>Thank you for calling abc.com. Please enter your pin using your keypad.
          </prompt>
          <filled>
            <assign name="pin_number" expr="pin"/>
            <goto next="#mainmenu"></goto>
          </filled>
        </field>
       </form>

       <menu id="mainmenu">
       <prompt>
         if this is a mobile phone press 1

         if this is a lan line press 2
       </prompt>
       <choice dtmf="1" next="#mobile">
        Sales</choice>
       <choice dtmf="2" next="#skip">
        Tech Support</choice>
       </menu>

       <form id="mobile">
        <subdialog src="smsscript.php" namelist="callID" name="sendtext" method="post"/>
        <block>
          thank you
          <goto next="#skip"/>
        </block>
        </form>

      <form id="skip">
       <field name="income" type="digits">
         <prompt>
           Please use your keypad to input your monthly income.
         </prompt>
         <filled>
           <assign name="M_Income" expr="income"/>
         </filled>
       </field>

    <field name="credit" type="digits?maxlength=3">
      <prompt>
        Please use your keypad to input your credit rating.
      </prompt>
      <filled>
        <assign name="credit_score" expr="credit"/>
        <!--<log expr="pin_number"/>
        <log expr="mobileNum"/>
        <log expr="M_Income"/>
        <log expr="first"/>
        <log expr="last"/>
        <log expr="credit_score"/>
        <log expr="callID"/>-->
        <submit next="process_request.php" method="post" namelist="pin_number M_Income credit_score callID" fetchtimeout="60s" enctype="multipart/form-data"/>
      </filled>
     </field>
    </form>
  </vxml>
smsscript.php

Code: Select all

<?php
header("Content-type: text/xml");

$CALLER = $_POST['callID'];
$params['to'] = $CALLER;
$params['from'] = "16172075679";
$params['body'] = "Please Respond To This Text Message With Your Email Address So We Can Better Serve You.";
$params['result_url'] = "http://hubenterprises.com.mx/ParseSMSresponse.php";


// initialize curl
$ch = curl_init();

// set necessary curl options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_URL, "http://hosting.plumgroup.com/ws/sms/queue.xml");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, "username:password");

//echo(curl_exec($ch));

curl_close($ch);
?>
<vxml version="2.0">
  <form>
    <block>
      <return namelist=""/>
    </block>
  </form>
</vxml>
There were two minor issues here. Firstly, the session variable you were using to access the caller id did not exist, hence getting an empty string in your subdialog. You should be using:

Code: Select all

<var name="callID" expr="session.telephone.ani"/>
To capture the caller id of the caller.

Also, in smsscript.php, you still need to return valid vxml, so we've added an empty return form below your php. We've also commented out the echo(curl_exec($ch)); line, as any xml spurted out before the vxml in your script will likely cause a bad fetch erorr, as the interpreter is going to attempt to execute it first. If you want to log this information just for debugging purposes, you could wrap it in an html comment.

We did see the callID post paratmeter come through to your subdialog and the subdialog executed and returned to start.php without issue. Hopefully this helps, but please let us know if you have any further questions.

Regards,
Plum Support

aghuber11
Posts: 14
Joined: Tue Jun 21, 2016 1:02 pm

Re: SMS question

Post by aghuber11 »

Dear support staff,

I developed a script just purely to test if the text messages could be sent based on caller ID and so far i have had zero luck.

i CANNOT for the life of me get it to send the call ID as a post param so your system knows who to text.

This is my test code. Is it possible that callID doesn't want to be sent as a post parameter to the php script because it's a session variable. Can you send session var's the same way as normal variables? Or could i just declare the session variable in the subdialog as a php variable that sends the text message?

Code: Select all

<?xml version="1.0"?>
<vxml version="2.1">
<var name="callID" expr="session.telephone.ani"/>
  <form>
    <subdialog namelist="callID" src="smsscript.php"/>
    <block>
      Good One
    </block>
  </form>
</vxml>

Code: Select all

<?php
header("Content-type: text/xml");

$CALLER = $_POST['callID'];
$params['to'] = $CALLER;
$params['from'] = "16172075679";
$params['body'] = "Please Respond To This Text Message With Your Email Address So We Can Better Serve You.";
$params['result_url'] = "http://hubenterprises.com.mx/ParseSMSresponse.php";


// initialize curl
$ch = curl_init();

// set necessary curl options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_URL, "http://hosting.plumgroup.com/ws/sms/queue.xml");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, "username:password");

//echo(curl_exec($ch));

curl_close($ch);
?>
<vxml version="2.0">
  <form>
    <block>
      hello  <value expr="callID"/>
      <return namelist=""/>
    </block>
  </form>
</vxml>
Last edited by aghuber11 on Tue Aug 23, 2016 12:24 pm, edited 1 time in total.

support
Posts: 3632
Joined: Mon Jun 02, 2003 3:47 pm
Location: Boston, MA
Contact:

Re: SMS question

Post by support »

Hello,

We have updated and tested your test script as follows with success:

start.xml:

Code: Select all

<?xml version="1.0"?>
<vxml version="2.1">
<var name="callID" expr="session.telephone.ani"/>
  <form>
    <subdialog namelist="callID" src="smsscript.php" method="post"/>
    <block>
      Good One
    </block>
  </form>
</vxml>
smsscript.php:

Code: Select all

<?php
    header("Content-type: text/xml");
    echo("<?xml version=\"1.0\"?>\n");

$CALLER = 1 . $_POST['callID'];
$params['to'] = $CALLER;
$params['from'] = "16172075679";
$params['body'] = "Please Respond To This Text Message With Your Email Address So We Can Better Serve You.";
$params['result_url'] = "http://hubenterprises.com.mx/ParseSMSresponse.php";

//initialize curl
$ch = curl_init();

// set necessary curl options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_URL, "http://hosting.plumgroup.com/ws/sms/queue.xml");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, "username:password");

//echo(curl_exec($ch));

curl_close($ch);
?>
<vxml version="2.0">
  <form>
    <block>
        <log><? print_r($params) ?></log>
        hello  <value expr="'<? echo($CALLER) ?>'"/>
      <return namelist=""/>
    </block>
  </form>
</vxml>
You may have been unable to get your "callID" variable from your VXML script because you did not include "method="post"" in your initial subdialog tag. We also added a 1 to the beginning of the caller ID since you must include a 1 at the beginning of the phone number you are trying to send a text to, and we added a <log> tag in smsscript.php to log your $params array in your call logs to help give you further debugging information.

Regards,
Plum Support

aghuber11
Posts: 14
Joined: Tue Jun 21, 2016 1:02 pm

Re: SMS question

Post by aghuber11 »

interestingly enough..

The response i receive with that code is this.

Code: Select all

<?xml version="1.0"?>
<vxml version="2.0">
  <form>
    <block>
        <log>Array
(
    [to] => 1
    [from] => 16172075679
    [body] => Please Respond To This Text Message With Your Email Address So We Can Better Serve You.
    [result_url] => http://hubenterprises.com.mx/ParseSMSresponse.php
)
</log>
        hello  <value expr="'1'"/>
      <return namelist=""/>
    </block>
  </form>
</vxml>
The script runs completely but the $_POST variable still doesn't get caught. Even when i test it with this query string

is it possible that the issue is that the application is hosted on my server?

http://hubenterprises.com.mx/test_scrip ... 8159856396
Last edited by aghuber11 on Tue Aug 23, 2016 1:44 pm, edited 1 time in total.

Post Reply