Software Guru Conference & Expo 2014

Envio de mail con citas a microsoft office Outlook

Hola Soy nuevo en este tema, Estoy desarrollandobn un CRM en la empresa en la que estoy uno de los requerimientos es que envie desde mi aplicacion( Con Spring frameworks 2.5 como base) citas al calendario de Microsoft Office Ouylook , no se si alguien ya realizo algo parecio para que me de una apoyo tecnico para su realizacion.
Le estoy hechando un vistazo a el JavaMail pero es mas estandar
y al Apache POI pero aun no tengo nada concreto.
Saludos.

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

JavaMailSender

Si estás usando Spring, utiliza el JavaMailSender en vez de JavaMail solito. JavaMailSender tiene facilidades para enviar mensajes de correo con archivos anexos, con la clase MimeMailMessage. Y la cita para el Outlook no es otra cosa que un archivito anexo en un correo, con una extensión y tipo MIME que Outlook reconoce. Y ese archivito seguro está en texto, pero desconozco el formato. Puedes buscar documentación en algún sitio en Microsoft o investigar por fuera si es que sigue algún estándar o hay algún software que maneje ese formato.

Algo muy simple es que generes una cita para Outlook usando el mismo Outlook y en la cuenta del destinatario revises el correo que llega, en "crudo" o sea sin codificar nada (si es que es posible verlo así en outlook), algo como "ver fuente" del correo. O envia una cita a una cuenta que puedas ver en Thunderbird o algún otro cliente de correo donde sí puedas ver el mensaje de texto plano sin codificar, para que veas el archivo anexo cómo viene.

Imagen de Shadonwk

Tip

para revisar el correo en "crudo" como dice @Zamudio utiliza el webmail de tu cuenta de corre electronico, generalmente "SquirrelMail", "RoundCube" o "Horde", estos clientes de correo son tan chafas que apenas y reconocen el formato HTML jaja, ademas te dan la opción de descargar el código en un archivo "txt"

Imagen de avefenix_x

Avances.

Gracias por los comentarios.
Ya realice la configuracion de envio de correo por medio SimpleMailMessage con Spring para probar y me funciono corectamente ya recibi mi primer correo desde mi aplicacion. Estoy investigando como anexar la cita al correo.
Gracias por el Tips. Lo voy a checar ahorita cuando encuentre la solucion les comento como lo resolvi (Espero hacerlo).
Saludos

Imagen de avefenix_x

Archivo Vcalendar

El archivo que se envia es de tipo texto con espesificacion Vcalendar se puede hacer manualmente o con alguna implementacion(Solo me falta saber cual es esa implementacion) lo lleva en zip. me imagino que el outlook se da cuenta que hay un archivo adjunto verifica el tipo y ya te manda si se Quiere adjuntar el evento a su calendario. Hasta ahi voy. aun me falta :)

Imagen de ezamudio

MimeMailMessage

Usa MimeMailMessage en vez de SimpleMailMessage para enviar correos con archivos anexos.

Si el archivo es en texto no te compliques mucho y créalo tú mismo. Para comprimirlo usa las clases de java.util.zip, puedes por ejemplo comprimir datos como si fuera un archivo, directo en memoria:

ByteArrayOutputStream buf = new ByteArrayOutputStream();
ZipOutputStream zip = new ZipOutputStream(buf);
ZipEntry file = new ZipEntry("unarchivo.vcal");
zip.putNextEntry(file);
zip.write("Aqui va el contenido del archivo vcal".getBytes());
zip.closeEntry();
zip.close();
//En buf ahora tienes los datos comprimidos como si fuera un archivo de ZIP
//Suponte que ya tienes un MimeMessageHelper llamado "mime"
mime.addAttachment("cita.zip", new ByteArrayResource(buf.toByteArray()), "tipo/subtipo");

"tipo/subtipo" debe ser el tipo MIME apropiado; si ya pudiste ver un correo enviado desde otra aplicación ahí puedes ver el tipo MIME del anexo, tal vez application/x-zip o algo así, o tal vez diga un tipo MIME correspondiente al vcal...

Imagen de avefenix_x

Envio mail Vcalendar

Ya logre formar mi correo con el el archivo vcalendar incluido y enviarlo, el evento llega muy bien pero como le hago para ejecutarlo automaticamente al abrir el correo.
Le envio el codigo que tengo de envio de correo.

mimeMessage.addHeaderLine("method=REQUEST");
mimeMessage.addHeaderLine("charset=UTF-8");
mimeMessage.addHeaderLine("component=VEVENT");

mimeMessage.setFrom(new InternetAddress(templateMessage.getFrom()));
mimeMessage.setRecipient(Message.RecipientType.TO,new InternetAddress(correo));
mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(templateMessage.getFrom()));
mimeMessage.setSubject(templateMessage.getSubject());
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setHeader("Content-Class", "urn:content-classes:calendarmessage");
messageBodyPart.setHeader("Content-ID","calendar_message");
//El archivo lo genero en otro metodo y se lo proporciono como String al metodo.
messageBodyPart.setDataHandler(new DataHandler( new ByteArrayDataSource(textoArchivoIcla4j, "text/calendar")));
Multipart multipart = new MimeMultipart("alternative");
multipart.addBodyPart(messageBodyPart);
mimeMessage.setContent(multipart);

Es este codigo envia un correo bien, pero cuando lo abre el usuario se tienen que ejecutar manualmente el archivo que va como Attachment (.ics) para agregar el vento.
Como Hacer que el archivo se abra cuando se abre el mail ?
Es lo ultimo que me falta para concluir con esto
Saludos

Imagen de ezamudio

se puede hacer eso?

Has visto que se pueda hacer lo que quieres hacer tú? Hay otras aplicaciones (como el mismo outlook) que mandan el attachment de tal manera que el archivo se abre cuando se abre el mail? Que para empezar eso es una vulnerabilidad en la seguridad, porque entonces puedes mandar un virus zipeado y outlook felizmente lo abrirá para ejecutarlo sin preguntarle al usuario... pero si otro software puede enviar un vcal que outlook abre de manera automática cuando el usuario ve el mail, lo que debes hacer es revisar ese correo, porque a fin de cuentas ese software envió un correo que outlook interpreta de cierta forma para abrir el attachment automáticamente. Revisa las diferencias entre un correo que funciona como quieres y el correo que generas tú.

Imagen de avefenix_x

Solo outlook lo hace

Desde la interface de outlook se generan nuevos eventos que se envían y al momento de que el usuario destino abre el correo del evento del outlook el programa abre el Vcal en lugar del correo y te pide confirmación para agregarlo al calendario. Esto es una funcionalidad especifica de outlook hasta donde he visto, lo único que quiero es reproducirla :). para darle al usuario final un plus. pero de todo lo que lei, lo han intentado pero el outlook no se deja. y si puede ser hasta ciertamente un problema de seguridad para outlook si me dejara hacer eso.
Hice algunas pruebas enviando el Vcal que genera el outlook pero tampoco funciono, creo que el problema está en los Headers del correo, una forma muy específica de envió de outlook 2007.
Gracias por los comentarios es la primera ves que escribo comentarios a qui y hay alguien del otro lado del charco que comparte opiniones muy rapido, a veces mis ideas son un poco locas pero sé que solo así se logran mejores cosas. Saludos.

Imagen de ezamudio

headers

Si mal no recuerdo, el MimeMessage te deja ponerle los encabezados que quieras, así que podrías seguir intentando. Finalmente un correo es puro texto, desde los encabezados hasta los archivos anexos, todo se puede ver como un archivo de texto. La cosa es hacer un texto que Outlook interprete como dices.

Imagen de avefenix_x

Al enviar mail se congela el navegador.

Cuando envio el correo con el calendario se me cogela la navegador un momento.
Una idea de hacer para monitorear mi aplicacion y que cada cierto tiempo envie esos correo para no darle al usuario la impresion de bloqueo del navegador.
Por que no deja ni que salga la el div de espera, despues de que hace la operacion sale, y ya para que si ya realizo todo. :)
Estoy utilizando DWR para hacer el envio de la informacion.
Saludos.

Imagen de ezamudio

thread

Utiliza un thread separado para enviar el correo. Si existe la posibilidad de que se envien muchos correos seguidos, usa un ThreadPool para que encoles el envío del correo y no tenga que esperar el usuario a que se envie. Revisa mi blog, tengo un post de ThreadPools.

Imagen de avefenix_x

quartz

Ya termine toda la tarea sin problemas solo te voy a comentar algunos problemas que tuve con la configuración en spring de la tarea quartz.
Primero realice la configuración con CronTriggerBean y SimpleTriggerBean pero no funcionaba pero tampoco mandaba ningun tipo de error(De esos problemas donde no sabes por dónde darle solución), me di a la tarea de seguir los logs de Spring y resulta que por alguna razón las tareas tenían que ver con mis beans de conexión de base de datos(dataSource y transactionManager). Lo más raro de todo era que no enviaban error ni publicaban los logs de la tarea que en teoría tenía que hacer (La de envió de correo) y al final solo me quede con mi bean SimpleTriggerBean que si funcionaba correctamente.
segundo para poder accesar a los beans lo tuve que hacer con el ApplicationContext ya que no me inyectaba con @Autowired mis beans de acceso a base de datos.
Lo que si no pude realizar fue que a partir de mi ApplicationContext obtener el path de mi aplicacion tal y como lo hago con el request.
Saludos.

Imagen de ezamudio

contextos

Lo de obtener el path de tu aplicación tal y como lo haces con el request, solamente se puede hacer en el contexto de una petición HTTP. Con Quartz no puedes hacer eso porque están esos beans en otro contexto.

Para que te funcionen las anotaciones @Autowired, @Resource, @Required, @PostConstruct, @PreDestroy etc necesitas declarar el <context:annotation-config /> en tu applicationContext.

Imagen de avefenix_x

Mi aplicacion ya tiene esa configuracion

Mi aplicacion ya tiene eos parametros y aparte todos los beans que utilizo estan en el mismo applicationContext aparte utilizo un y tambien uso el @Qualifier para accesar al beans por nombre. y no funciono, la unica forma como lo logre fue agregando la propiedad applicationContextSchedulerContextKey a mi bean y obtenerla con un get desde mi beans y sacar los beans que necesitaba.
Y para lo del path estuve vivoreando mi variable de org.springframework.context.ApplicationContext desde el debug y tiene una propiedad servletContext de tipo ApplicationContextFacade en la que se encuentra esa informacion que necesito :) solo que no supe como llegar a ella.
Saludos.

Vcalendar con ASP

Hola que tal:
Yo estoy haciendo exactamente lo mismo con ASP, y la vdd me gustaría que me echaran la mano ya que me atoré en la parte de abrir automáticamente la cita desde el outlook. Es decir en resumen, creo la cita la adjunto, la mando pero al usuario le llega solo un correo mas sin la posibilidad de agregar dicha cita al calendario del usuario. Por favor les pido atentamente su ayuda...

Imagen de avefenix_x

Apoyo ayuda archivo.

Yo lo que hice fue crear un archivo Vcalendar valido para outlook y lo anexe al correro despues el usuario lo abre y acepta la cita. No es de forma automatica por que eso si no lo pude hacer ya que microsoft outlook emite un calendario que solo el entiende, lo puedes intentar a ver como te va a ti por estar trabajando en ASP.