Se ha publicado un interesante artículo en phpkitchen.com, escrito por Farheen Rehman sobre el envío de SMS (mensajes de texto) vía HTTP, el cual aparece traducido a continuación.
SMS (también conocidos como mensajes de texto) se ha conevrtido en un método de comunicación muy común. Este sistema funciona en Europa y Asia desde principios de los noventa y su utilización se ha ido extendiendo rápidamente en la misma medida en Estados Unidos.
SMS es el acrónimo de “Short Message Service” (Servicio de Mensajes Cortos) y utiliza los teléfonos móviles para transmitir (sorpresa, sorpresa) mensajes cortos hacia y desde teléfonos móviles, mientras muchos de nosotros posiblemente no conozcamos el siguiente hecho, que se pueden enviar mensajes SMS desde un sitio web o un fragmento de código.
Existen un gran número de razones por el que uno podría querer utilizar su sitio web para envíar mensajes SMS. Podría añadir un botón “enviar por SMS” a los titulares, por ejemplo, o alguien podría montar un servicio de soporte técnico 24/7 en el cual tu técnico recibe las notificaciones vía SMS, o simplemente desea proporcionar a los visitantes del sitio un servicio gratuíto SMS para atraer más tráfico.
Aunque también es posible enviar SMS a través del e-mail, este tutorial te enseñará cómo enviar SMS utilizando los métodos POST y GET en PHP (ya que es el lenguaje que yo domino -pienso que en Perl tampoco existiría problema alguno-).
Para muchos de nosotros que no conocen esto, utilizar HTTP, básicamente significa la utilización de formularios, como un formulario de contacto, con la diferencia de que estos serán enviados de forma automática en vez de manualmente.
A pesar de que este tutorial es aplicable a cualquier puerta que proporciona acceso vía HTTP, se basa en SMS TM4B Gateway porque A) es el único “gateway” que conozco que tiene el modo simulación para los scripts, B) no tienen ningún coste en el alta del servicio, C) los precios son bajos, D) son fiables y E) yo los uso.
Comprendiendo los Requerimientos del “Gateway”
Los detalles sobre como conectarse al TMB4 están disponible en la página del API SMS. Fudamentalmente requiere que se envíen seis parámetros:
username: our username
password: our password
msg: our SMS message(s)
to: the recipient(s) of our message
from: our sender id
route: the route of the message (i.e. first class or business class)
Y añadiremos un sétimo, que es el “sim”. Este parámetro identifica a nuestro mensaje como un mensaje de simulación de forma que no será cargado en nuestra cuenta y los mensajes no serán enviados.
Preparando la Petición
El proceso de envío del mensaje lo gestiona el “gateway”. Todo lo que precisa de nosotros es que le pasemos los detalles del/los mensaje/s según la sintaxis de una petición HTTP, algo como esto:
http://www.tm4b.com/client/api/send.php? username=abcdef&password=12345&msg=This+is+sample+message.& to=447768254545%7C447956219273%7C447771514662& from=MyCompany&route=frst&sim=yes
Se puede testar el ejemplo anterior (que utiliza el método GET) introduciendo directamente la dirección en la barra de dirección del navegador. Deberíamos obtener una respuesta diciendo que el nombre de usuario no es válido, lo cual es normal porque es simplemente una demonstración.
El primer paso consiste en guardar nuestros datos en variables y después convertirlas en una petición HTTP. Existen varias formas para hacer esto, pero la siguiente forma es una nueva manera además de útil:
$request = ""; //initialize the request variable $param["username"] = "abcdef"; //this is the username of our TM4B account $param["password"] = "12345"; //this is the password of our TM4B account $param["msg"] = "This is sample message."; //this is the message that we want to send $param["to"] = "447768254545|447956219273|447771514662"; //these are the recipients of the message $param["from"] = "MyCompany";//this is our sender $param["route"] = "frst";//we want to send the message via first class $param["sim"] = "yes";//we are only simulating a broadcast foreach($param as $key=>$val) //traverse through each member of the param array { $request.= $key."=".urlencode($val); //we have to urlencode the values $request.= "&"; //append the ampersand (&) sign after each paramter/value pair } //remove the final ampersand sign from the request $request = substr($request, 0, strlen($request)-1);
Asignamos nuestras credenciales y la información de conexión y destino en la matriz $param. Fijémonos en que pueden seleccionarse varios destinatarios separándolos por “pipes” (|). El valor de cada parámetro necesita estar “urlencodeado” y los pares parámetro-valor estarán separados por el carácter “&”. Dejar un ampersand al final no debería causar problemas, aunque en el código utilizamos substr para dejar una petición limpia.
El script construirá la siguiente petición que puede ser utilizada para lanzarla al SMS “gateway”:
username=abcdef&password=12345&msg=This+is+sample+message.& to=447768254545%7C447956219273%7C447771514662& from=MyCompany&route=frst&sim=yes
Enviando la petición con CURL
Anteriormente, habíamos visto que la petición se podía realizar pegando la dirección directamente en la barra de dirección del navegador. Pero lo que realmente queremos es que esto quede oculto y tenga lugar en servidor. El siguiente código es que lo hace utilizando CURL.
CURL es una importante librería que permite conectar y comunicar con distintos tipos de servidores con diferentes protocolos. Se puede encontrar más información en el manual de PHP.
Este código abre la conexión con el “gateway”, envía el o los mensajes SMS y recoge sus IDs que aparecen en la cabecera de la respuesta.
$url = "http://www.tm4b.com/client/api/send.php"; //this is the url of the gateway's interface $ch = curl_init; //initialize curl handle curl_setopt($ch, CURLOPT_URL, $url); //set the url curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); //return as a variable curl_setopt($ch, CURLOPT_POST, 1); //set POST method curl_setopt($ch, CURLOPT_POSTFIELDS, $request); //set the POST variables $response = curl_exec($ch); //run the whole process and return the response curl_close($ch); //close the curl handle //print $response; //show the result onscreen for debugging
Primero, inicializamos una nueva sesión de CURL. Después fijamos las opciones que precisamos; esto incluye fijar CURLOPT_POST ya que el API TM4B SMS precisa que el envío de varios mensajes sea vía POST. Finalmente, ejecutamos la llamada y cerramos el manejador.
Enviando la petición con Sockets
Las funciones de CURL dependen de una librería externa y que PHP se haya compilado con la opción –with-curl. Mientras CURL es muy flexible y útil, podría no estar disponible con la instalación de PHP que tengamos. Si este es el caso, aún podemos realizar la comunicación vía sockets.
//First prepare the info that relates to the connection $host = "tm4b.com"; $script = "/client/api/send.php"; $request_length = strlen($request); $method = "POST"; // must be POST if sending multiple messages if ($method == "GET") { $script .= "?$request"; } //Now comes the header which we are going to post. $header = "$method $script HTTP/1.1\r\n"; $header .= "Host: $host\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: $request_length\r\n"; $header .= "Connection: close\r\n\r\n"; $header .= "$request\r\n"; //Now we open up the connection $socket = @fsockopen($host, 80, $errno, $errstr); if ($socket) //if its open, then... { fputs($socket, $header); // send the details over while(!feof($socket)) { $output[] = fgets($socket); //get the results } fclose($socket); } /* the message id's will be kept in one of the $output values print "pre"; print_r($output); print "/pre"; */
Primero antes de mostrar la salida, necesitamos construir las cabeceras de la petición y enviar el mensaje. Se establece una conexión utilizando fsockopen. La información es enviada y recibida de la forma en que PHP leería y escribiría en un fichero. Después de que nuestra transferencia se ha completado, esperamos la respuesta, la capturamos en la matriz $output y finalmente cerramos la conexión.
Concusión
Aunque comenta que le costó bastante tiempo encontrar CURL, piensa que es la mejor opción (cosa que comparto), la más limpia y rápida si la versión que tenemos de PHP la soporta. Más aún, mientras tanto fsockopen y CURL pueden enviar miles de mensajes en una sola conexión, fosockopen puede presentar problemas a la hora de analizar respuestas largas ya que las respuestas se transmiten en trozos.
Según nos cuenta, lo que hemos expuesto antes le llevó año, y espera que esto nos ahorre tiempo.