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? && "Fallo") || "Enviado"
puts msg
Popularity: 100% [?]


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.
Busca algo que haga requisiciones HTTP, tal vez te sirve esto http://www.example-code.com/vb/http.asp
Ese es todo el codigo? fijate que no me funciona, talvez me hechas unas luces, no lo tienes en algun lado funcionando?
saludos
Muy interesante el post se ve que programas un monton .
Gracias por el aporte quienes enpezamos recien.
Saludos