ActionSMS
De Open movilforum wiki
ActionSMS es un plugin para Rails que añade a ActionMailer (el mecanismo estándar de Rails para enviar e-mail) la capacidad de enviar SMS's, en principio a través de la API de Movistar (aunque crear una libreria para utilizar otra pasarela de envío es muy sencillo).
[editar] Inicio rápido
El plugin es bastante simple de usar:
1. Instálalo:
$ script/plugin install http://action-sms.googlecode.com/svn/tags/action_sms
2. Crea el archivo config/sms.yml con el siguiente contenido:
gateway: movistar login: <tú-número-de-móvil> password: <tu-password-para-la-API>
3. ¡Ya está! Ahora, cuando envíes mensajes con ActionMailer, Rails parseará la lista de destinatarios, y lo enviará como SMS a aquellos destinatarios que consistan en un número, y como e-mail a los demás, de forma completamente transparente. La forma de generar los mensajes, configurar el sistema, escribir los tests, etc., es la estándar de Rails (puedes leer una buena descripción de todos estos aspectos en el capítulo 24 del "Agile Web Development with Rails" o en el wiki de Rails.
[editar] Enviar SMS's desde Ruby (sin Rails)
ActionSMS se divide en dos partes: la parte puramente Rails de redefinición de ActionMailer, y la clase MovistarGateway que es la que maneja el envío de los SMS. Esto es con un doble objetivo: por un lado, poder incluir en el futuro otros gateways en el plugin (el gateway activo se configura en config/sms.yml y de momento sólo acepta el valor 'movistar'), y, por otro, poder usar esa clase en scripts "pure Ruby", lo cual sería tan simple como el siguiente ejemplo:
require 'movistar_gateway'
gateway = MovistarGateway.new('<login>', '<password>')
gateway.send(['66666666', '777777777'], 'Texto del mensaje')
[editar] El ejemplo completo
Vamos a crear una agenda de contactos en la que cada vez que añadimos un contacto, le avise con un email y un SMS. Haremos uso intensivo de los generadores de Rails.
Lo primero, creamos el esqueleto de la aplicación:
$ rails agenda -d sqlite3
create
create app/controllers
create app/helpers
create app/models
create app/views/layouts
create config/environments
create config/initializers
create db
create doc
create lib
create lib/tasks
create log
create public/images
create public/javascripts
create public/stylesheets
create script/performance
create script/process
create test/fixtures
create test/functional
create test/integration
create test/mocks/development
create test/mocks/test
create test/unit
create vendor
create vendor/plugins
create tmp/sessions
create tmp/sockets
create tmp/cache
create tmp/pids
create Rakefile
create README
create app/controllers/application.rb
create app/helpers/application_helper.rb
create test/test_helper.rb
create config/database.yml
create config/routes.rb
create public/.htaccess
create config/initializers/inflections.rb
create config/initializers/mime_types.rb
create config/boot.rb
create config/environment.rb
create config/environments/production.rb
create config/environments/development.rb
create config/environments/test.rb
create script/about
create script/console
create script/destroy
create script/generate
create script/performance/benchmarker
create script/performance/profiler
create script/process/reaper
create script/process/spawner
create script/process/inspector
create script/runner
create script/server
create script/plugin
create public/dispatch.rb
create public/dispatch.cgi
create public/dispatch.fcgi
create public/404.html
create public/500.html
create public/index.html
create public/favicon.ico
create public/robots.txt
create public/images/rails.png
create public/javascripts/prototype.js
create public/javascripts/effects.js
create public/javascripts/dragdrop.js
create public/javascripts/controls.js
create public/javascripts/application.js
create doc/README_FOR_APP
create log/server.log
create log/production.log
create log/development.log
create log/test.log
La opción -d sqlite3 es para usar una base de datos SQLite, opción siempre cómoda para el entorno de desarrollo, pero puedes usar la que quieras.
El siguiente paso es entrar al directorio de la aplicación y generar el scaffold para los contactos:
$ script/generate scaffold Contact name:string email:string mobile:string
create app/models/
exists app/controllers/
exists app/helpers/
create app/views/contacts
create test/functional/
create test/unit/
create app/views/contacts/index.html.erb
create app/views/contacts/show.html.erb
create app/views/contacts/new.html.erb
create app/views/contacts/edit.html.erb
create app/views/layouts/contacts.html.erb
create public/stylesheets/scaffold.css
dependency model
exists app/models/
exists test/unit/
create test/fixtures/
create app/models/contact.rb
create test/unit/contact_test.rb
create test/fixtures/contacts.yml
exists db/migrate
create db/migrate/001_create_contacts.rb
create app/controllers/contacts_controller.rb
create test/functional/contacts_controller_test.rb
create app/helpers/contacts_helper.rb
route map.resources :contacts
Para crear la tabla correspondiente en la base de datos hay que ejecutar las migraciones:
$ rake db:migrate
== 1 CreateContacts: migrating ================================================
-- create_table(:contacts)
-> 0.0057s
== 1 CreateContacts: migrated (0.0061s) =======================================
Ya podemos arrancar el servidor:
$ script/server
Y probar nuestra flamante aplicación introduciendo esta URL en el navegador: http://0.0.0.0:3000/contacts
Puedes probar a añadir, borrar y modificar algunos contactos.
Ahora vamos a añadir la capacidad de avisar a los nuevos contactos por email. Lo primero será generar el mailer:
$ script/generate mailer Notifier add
exists app/models/
create app/views/notifier
exists test/unit/
create test/fixtures/notifier
create app/models/notifier.rb
create test/unit/notifier_test.rb
create app/views/notifier/add.erb
create test/fixtures/notifier/add
Si abrimos app/models/notifier.rb veremos que ya se ha creado el método add, que es el que usaremos para enviar el email:
class Notifier < ActionMailer::Base
def add(sent_at = Time.now)
@subject = 'Notifier#add'
@body = {}
@recipients =
@from =
@sent_on = sent_at
@headers = {}
end
end
Lo modificaremos ligeramente para que nos acepte como parámetro el contacto añadido, tenga un asunto más descriptivo, y alguna cosa más, para que quede así:
class Notifier < ActionMailer::Base
def add(contact)
@subject = 'Te han añadido como contacto'
@body = {:contact => contact}
@recipients = contact.email
@from = 'miaplicacion@example.com'
@sent_on = Time.now
@headers = {}
end
end
Y por último editaremos la vista, que está en app/views/notifier/add.erb, con algo como esto:
Hola, <%= @contact.name %>: ¡Te han añadido como contacto!
Lo único que nos falta es hacer que al crear un contacto se envíe el correo, lo cual haremos mediante un callback en el modelo Contact (app/models/contact.rb). Antento que aquí está el meollo de la cuestión:
class Contact < ActiveRecord::Base
after_create :send_message
def send_message
Notifier.deliver_add(self)
end
end
Al definir send_message como callback after_create, este método se ejecutará cada vez que se cree un contacto. El método, usando el mailer Notifier, enviará el mail add (que creamos hace un momento), pasándole como parámetro el propio usuario creado. No estaría de más, antes de hacerlo, comprobar que se ha introducido realmente un email válido, por ejemplo mediante validaciones, pero te dejaremos eso como ejercicio =;-)
Añádete a tí mismo como contacto y verás como te llega el email. Si tienes algún problema con la configuración del correo puedes consultar, como dijimos antes, el capítulo 24 del "Agile Web Development with Rails" o en el wiki de Rails.
Ahora vamos a hacer que la aplicación también notifique por SMS. Lo primero será instalar el plugin:
$ script/plugin install http://action-sms.googlecode.com/svn/tags/action_sms + ./action_sms/MIT-LICENSE + ./action_sms/README + ./action_sms/Rakefile + ./action_sms/init.rb + ./action_sms/install.rb + ./action_sms/lib/action_sms.rb + ./action_sms/lib/movistar_gateway.rb + ./action_sms/tasks/action_sms_tasks.rake + ./action_sms/test/action_sms_test.rb + ./action_sms/uninstall.rb
Y configurarlo, creando el archivo config/sms.yml con el siguiente contenido:
gateway: movistar login: <tu-numero> password: <tu-password>
Y ya, simplemente con hacer que el mailer añada como destinatario el número de móvil, se enviará el mensaje por las dos vías. Como recordarás, haremos eso editando app/models/notifier.rb y modificando la linea de los recipients:
class Notifier < ActionMailer::Base
def add(contact)
@subject = 'Te han añadido como contacto'
@body = {:contact => contact}
@recipients = [ contact.email, contact.mobile ]
@from = 'miaplicacion@example.com'
@sent_on = Time.now
@headers = {}
end
end
Prueba, prueba ;-)
