search
top

SMS

Hace un poco de tiempo, por alli en el 2003, vi un programa para enviar sms en Guatemala desarrollado por Oscar Bonilla y desde entonces he tratado de mantener el programa con pequeños cambios para que permanezca funcional. Desde aquel entonces han cambiado muchas cosas y tal vez una de las mas importantes es que agregaron un CAPTCHA, y tambien un manejo de sesiones y cookies. El codigo original estaba desarrollado en perl y decidi seguir asi durante buena parte del tiempo hasta hace poco que se me hizo una buena idea migrarlo a ruby y hacer un frontend web con rails. El funcionamiento se basa en requisiciones POST y GET de HTTP a las paginas de los operadores y para resolver lo de los CAPTCHA usamos un OCR.

Que necesitamos

  • Ruby (duh!), Ruby Gems y la gema de Mechanize(para las requisiciones)
  • Ocrad (un ocr bueno, bonito y barato libre)
  • Imagemagick (una herramienta para manipulacion de imagenes)

Por ultimo, para determinar el carrier utilice los rangos publicados por la SIT para no molestar al usuario preguntando a que empresa pertenece el telefono. A continuacion el codigo del programa:

#!/usr/bin/ruby
require 'rubygems'
require 'mechanize'

URLS = {
  "claro" => "http://mensajes.claro.com.gt/mensaje.php",
  "tigo" => "http://interactivo.mensajito.com/client.php",
  "movistar" =>
    "http://www.corporativo.telefonica.com.gt/EnviarSMSGT/faces/EnviarSMS.jsp"
};

CONTENT = {
  "claro" => "nombre=**smsSENDER**&msg=**smsMESSAGE**&telefono=**smsNUMBER**",
  "tigo" => "orden=3&**smsSESSIONID**&nick=**smsSENDER**&mensaje=**smsMESSAGE**",
  "movistar" => "form1:edtDe=**smsSENDER**&form1:edtMsj=**smsMESSAGE** form1:edtPara=**smsNUMBER**&form1:edtDisp=**smsCOUNT**&form1:btnEnviar=Enviar&form1=form1"
};

SUCCESS = {
  "claro" => "Exitosamente",
  "movistar" => "sido enviado",
  "tigo" => ""
};

def checkCarrier(smsNumber)
  movistar = [5020,5029,5070,5109,5140,5144,5210,5299,5312,5313,5390,5409,
                   5500,5509,5518,5519,5540,5542,5545,5549,5600,5609,5640,5689,
                   5790,5799,5915,5917];
  tigo = [5819,4000,4027,5000,5009,5030,5069,5150,5209,5300,5309,5314,5389,
            5521,5529,5550,5553,5580,5581,5700,5709,5719,5789,5800,5809,5880,
            5909,5918,5919,5990,5999];
  claro = [5010,5019,5110,5132,5310,5311,5410,5499,5510,5517,5530,5539,
              5543,5544,5554,5579,5582,5599,5610,5639,5690,5699,5710,5718,5810,
              5818,5820,5879,5910,5914,5920,5989];
  i = 0
  while i < claro.length-1
   return "claro" if (smsNumber >= claro[i] && smsNumber <= claro[i+1])
   i+=2;
  end
  i = 0
  while i < movistar.length-1
   return "movistar" if (smsNumber >= movistar[i] && smsNumber <= movistar[i+1])
   i+=2;
  end
  i = 1
  while i < tigo.length-1
   return "tigo" if (smsNumber >= tigo[i] && smsNumber <= tigo[i+1])
   i+=2;
  end
  return "tigo" if (smsNumber == tigo[0])
  "error en el carrier"
end

def sms (smsNumber, smsSender, smsMsg)
  smsCarrier = checkCarrier((smsNumber[0,4]).to_i)
  smsUrl = URLS[smsCarrier]
  smsContent = CONTENT[smsCarrier]
  smsSuccess = SUCCESS[smsCarrier]
  smsContent = smsContent.gsub("\*\*smsSENDER\*\*",smsSender);
  smsContent = smsContent.gsub("\*\*smsMESSAGE\*\*",smsMsg);
  smsContent = smsContent.gsub("\*\*smsNUMBER\*\*",smsNumber);

  if (smsCarrier.eql? "movistar")
      smsLen = smsMsg.length + smsSender.length
      if (smsLen > 120)
        maxMsgLen = 120 - smsSender;
        smsMsg = smsMsg[0,maxMsgLen]
        smsLen = 0;
      else
        smsLen = 120 -  smsLen;
      end
      smsContent = smsContent.gsub("\*\*smsCOUNT\*\*",smsLen.to_s)
  end

  if (smsCarrier.eql? "claro")
    sesIdName = "PHPSESSID"
    sesId = "(PHPSESSID=)([0-9a-zA-Z]+)"
    smsCaptchaUrl = "http://mensajes.claro.com.gt/captcha.php"
    smsInitialUrl = "http://mensajes.claro.com.gt/mensaje_claro.php"
  elsif (smsCarrier.eql? "movistar")
    smsInitialUrl = smsUrl
    sesIdName = "JSESSIONID";
    sesId = "(JSESSIONID=)([!-~]+)";
    smsCaptchaUrl = smsUrl + "?vrClientId=form1:imageEx1";
  end

  smsRequest = WWW::Mechanize.new { |agent|
   agent.user_agent = 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092510'
  }
  if ((smsCarrier.eql? "claro") || (smsCarrier.eql? "movistar"))
    #hago un get inicial para obtener el session id
    smsResponse = smsRequest.get(smsInitialUrl)
    smsCookieJar = smsRequest.cookies()
    smsCookieJar.to_s.match(sesId)
    smsSessionId = $2

    #obtengo la imagen del captcha
    WWW::Mechanize::Cookie.parse(URI.parse(smsCaptchaUrl),
                  smsCookieJar.to_s, nil){
                     |c|
                     smsRequest.cookie_jar.add(URI.parse(smsCaptchaUrl), c)
                  }
    smsResponse = smsRequest.get(smsCaptchaUrl)
    smsCookieJar = smsRequest.cookies()
    File.open("c.gif", 'w') {
          |f| f.write(smsResponse.body)
                                 } if smsCarrier.eql? "claro"
    File.open("c.png", 'w') {
          |f| f.write(smsResponse.body)
                                } if smsCarrier.eql? "movistar"
    text = `convert -size 200x200 c.gif -resize 400x400 -negate c.gif;convert c.gif c.pbm;rm -rf c.gif` if smsCarrier.eql? "claro"
    text = `convert -size 200x200 c.png -resize 400x400 c.png;convert c.png c.pbm;rm -rf c.png` if smsCarrier.eql? "movistar"
    text = `ocrad c.pbm;`;

    #una serie de chapuces feos que a veces funcionan :p
    text = text.gsub(/( |\n)+/,"")
    text = text.gsub("_","7")
    text = text.gsub("{","f")
    text = text.gsub("\|","l")
    smsContent = smsContent+"&tmptxt2="+text if smsCarrier.eql? "claro"
    smsContent = smsContent+"&form1:edtCodigo="+text if smsCarrier.eql? "movistar"

    query = {}
    smsContent.split("&").each { |e| line = e.split("=")
                                     query[line[0]] = line [1] }

    WWW::Mechanize::Cookie.parse(URI.parse(smsUrl),
                  smsCookieJar.to_s, nil){
                     |c|
                     smsRequest.cookie_jar.add(URI.parse(smsUrl), c)
                  } 

    smsResponse = smsRequest.post(smsUrl,query)
    smsResult = 1 if smsResponse.body.match(smsSuccess)
  elsif (smsCarrier.eql? "tigo")
    #abro la sesion (aqui viene el session_id
    smsNumber = "502" + smsNumber;
    smsRequestUrl = smsUrl+"?orden=1&nick="+smsSender+"&foo=" + rand(30000).to_s
    smsResponse = smsRequest.get(smsRequestUrl)
    smsSessionId = smsResponse.body

    #agrego el telefono
    smsRequestUrl = smsUrl + "?orden=2&" + smsSessionId
                            + "&nick=" + smsSender + "&dstphone="
                            + smsNumber + "&foo="
                            + rand(30000).to_s + "&pin=512";
    smsResponse = smsRequest.get(smsRequestUrl)  

    #mando el mensaje
    smsContent = smsContent.gsub("\*\*smsSESSIONID\*\*",smsSessionId);
    smsRequestUrl = smsUrl + "?" + smsContent + "&foo=" + rand(30000).to_s
    smsResponse = smsRequest.get(smsRequestUrl)

    #cierro la sesion
    smsRequestUrl = smsUrl + "?orden=6&" + smsSessionId + "&foo="
                            + rand(30000).to_s
    smsResponse = smsRequest.get(smsRequestUrl)
    smsResult = 1
  end
end

#las variables numero,quienenvia,mensaje deben recibir un valor
msg = (sms(numero,quienenvia,mensaje).nil? &amp;&amp; "Fallo") || "Enviado"
puts msg

Popularity: 100% [?]

Para compartir
  • Facebook
  • Twitter
  • Identi.ca

4 Responses to “SMS”

  1. Skull118 says:

    Viejo una pregunta, yo ando buscando, como hacer el “#$#$% programa (en Visual) que haga los request necesarios, pero que solo jale el chapta, pero no logro hacer eso, podrias ayudarme.

  2. ykro says:

    Busca algo que haga requisiciones HTTP, tal vez te sirve esto http://www.example-code.com/vb/http.asp

  3. Keneth says:

    Ese es todo el codigo? fijate que no me funciona, talvez me hechas unas luces, no lo tienes en algun lado funcionando?

    saludos

  4. Muy interesante el post se ve que programas un monton .

    Gracias por el aporte quienes enpezamos recien.

    Saludos

Leave a Reply

top