Rankia USA Rankia Argentina Rankia Argentina Rankia Chile Rankia Chile Rankia Colombia Rankia Colombia Rankia España Rankia España Rankia México Rankia México Rankia Perú Rankia Perú Rankia Portugal Rankia Portugal
Acceder

Trucos y tretas en Outlook VBA para programadores - Macro de avisos y alertas

Cuando se trabaja con correos en la oficina, hay gente con suerte que recibe cuando mucho uno o dos correos al dia cuando mucho, pero cuando recibes 200 al dia, tienes que encontrar maneras de separar la paja del trigo.  Una manera muy usada es crear reglas.  Pero hay ocasiones donde el correo es tan urgente que debe ser atendido de inmediato, y me refiero a una ventana de tiempo de 5 a 15 minutos.  Si tu trabajo tiene este tipo de correos, es posible que crear reglas no sea suficiente.  Vas a necesitar una macro de Outlook que te avise.

Algunos escenarios donde puede ocurrir que necesites alertas:

  • Hay un equipo que reporta su estado por correo, o que genera avisos de eventos en una red.  El evento debe ser atendido de inmediato si ocurre una falla.  En esa red no todo es importante y recibes toneladas de correos automatizados de ese equipo.  Crear una regla solo de ayuda a dirigir todo ese spam a un directorio pero no separa las notificaciones de los reportes de averia.
  • Tu jefe necesita que le leas de inmediato cuando te envia correos.  Y tu recibes 200 correos al dia.  Aunque envies sus correos a una carpeta, no vas a estar revisando esa carpeta cada 5 minutos.
  • Trabajas en una multinacional y te han devuelto un caso de backoffice, y te notifican por correo y quieres tener buenas metricas de tiempos de respuesta.

Este truco es muy valioso para gentes que usan mucho por correo.

Un agradecimiento al Ing. José Pablo Luna Sánchez por este valioso aporte.

Agregando codigo a Outlook

Accediendo al IDE de VBA

Normalmente solo deberias presional Alt F11 para acceder al IDE, pero en algunas maquinas puedes tener problemas porque la combinacion de teclas no responde.  Entonces necesitas habilitar la pestaña de Developer y desde alli ingresar al IDE de VBA.  Empiezas por pinchar con el boton derecho del raton sobre el nombre de las pestañas en Outlook

Ingresando codigo

Aunque podriamos poner todo el codigo en un mismo lugar, por cuestion de orden no lo haremos asi.  El codigo generico va en un sitio y el codigo especifico va aparte.  Empieza por crear un modulo para ese codigo especifico.

Al final tendras esto.  Observaras que tienes dos modulos (ThisOutlookSession y Module1).  Para acceder al codigo contenido en cada uno, debe hacer doble click sobre el que desees abrir.

El codigo que debe ir en cada uno es el siguiente.

ThisOutlookSession


Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
    Dim strIDs: strIDs = Split(EntryIDCollection, ",")
    Dim oMail As MailItem, nIndex
    Dim oNameSpace As NameSpace
    Set oNameSpace = Application.GetNamespace("MAPI")
    On Error GoTo detectaerror
    For nIndex = 0 To UBound(strIDs)
        Set oMail = oNameSpace.GetItemFromID(strIDs(nIndex))
        RevisarCorreo oMail
    Next
Exit Sub
detectaerror:
    'MsgBox "Error: " & Err.Number & " " & Err.Description, vbExclamation, "VBATools.pl"
End Sub

Module1

Como notaras en el siguiente codigo, se usa una variable booleana para recoger todas las condiciones para dar avisos.  Hay multiples avisos, para tiquetes urgentes, tiquetes devueltos de backoffice, aviso de jefes, reporte de fallos, etc.  Notaras que los valores del correo entrante se almacenan en las siguientes variables:

  • eFrom: De quien viene el correo
  • eTo: Hacia quien va el correo
  • eSubject: Asunto del correo
  • eBody

La funcion getSmtpMailAddress sirve para hacer conversion del formato de direccion de correo al formato que contiene una arroba.  Si no usas esto, vas a obtener unas cadenas de caracteres que Outlook maneja internamente y que no es util.

Ademas, he agregado un proceso llamado Contiene que permite detectar si un texto esta contenido dentro de otro. La constante DisableCaseSensitive permite hacer que las diferencias entre mayusculas y minusculas sean irrelevantes.

En Module1 puedes agregar todo el codigo que veas necesario.  La he dado una estructura para que sea facil de modificar.

Habiendo aclarado esto, el código que debes colocar en Module1 es el siguiente...


Const DisableCaseSensitive = False

Sub RevisarCorreo(oMail As MailItem)
    '-------------------------------
    'Leer datos del correo entrante
    eFrom = getSmtpMailAddress(oMail) 'oMail.SenderEmailAddress
    eTo = oMail.To
    eSubject = oMail.Subject
    eBody = oMail.Body
    '-------------------------------
    'Evaluar si corresponde a una alerta
    EsUnaFalla = eFrom = "[email protected]"
    EsUnaFalla = EsUnaFalla And Contiene(eSubject, "Notification")
    EsUnaFalla = EsUnaFalla And Contiene(eBody, "failed", DisableCaseSensitive)

    CasoDevuelto = eFrom = "[email protected]"
    CasoDevuelto = CasoDevuelto And Contiene(eSubject, "has been Resolved by backoffice") And Contiene(eSubject, "Ticket")
    CasoDevuelto = CasoDevuelto And Contiene(eBody, "Ticket Information", DisableCaseSensitive)

    EsUrgente = Contiene(eSubject, "Urgente", DisableCaseSensitive)
    EsUrgente = EsUrgente Or Contiene(eSubject, "Posible Fallo", DisableCaseSensitive)

    EsAvisoImportante = (eFrom = "[email protected]")
    EsAvisoImportante = EsAvisoImportante Or (eFrom = "[email protected]")

    AvisoJefes = (eFrom = "[email protected]")
    AvisoJefes = AvisoJefes Or (eFrom = "[email protected]")
    AvisoJefes = AvisoJefes Or (eFrom = "[email protected]")

    EmailExpiration = (eFrom = "[email protected]")
    EmailExpiration = EmailExpiration Or Contiene(eSubject, "Your Email account will expire", DisableCaseSensitive)

    EsTiqueteUrgente = Contiene(eSubject, "vip -", DisableCaseSensitive)
    '-------------------------------
    'Si corresponde a alerta, avisar y desplegar
    If EsAvisoImportante Then _
        DesplegarAlerta "Aviso importante: " & eSubject, "Aviso importante", oMail
    If EsUnaFalla Then DesplegarAlerta "Alerta falla: " & eSubject, "Alerta Outlook", oMail
    If CasoDevuelto Then DesplegarAlerta "Alerta Caso Devuelto: " & eSubject, "Alerta Backoffice", oMail
    If EsUrgente Then DesplegarAlerta "Alerta Urgente/Posible fallo: " & eSubject, "Alerta Correo", oMail
    If AvisoJefes Then DesplegarAlerta "Alerta miempresa: " & eSubject, "Alerta Jefaturas miempresa", oMail
    If EsTiqueteUrgente Then DesplegarAlerta "Alerta tiquete urgente: " & eSubject, "Alerta sistema", oMail
    If EmailExpiration Then DesplegarAlerta "Alerta Correo: " & eSubject, "Alerta miempresa", oMail
    '-------------------------------
End Sub

Sub DesplegarAlerta(sBody, sHeader, oMail As MailItem)
    MsgBox sBody, vbInformation, sHeader
    oMail.Display
End Sub

Function Contiene(Correo, Texto, Optional CaseSensitive As Boolean = True) As Boolean
    If CaseSensitive Then
        Contiene = InStr(Correo, Texto) <> 0
    Else
        Contiene = InStr(UCase(Correo), UCase(Texto)) <> 0
    End If
End Function

Function getSmtpMailAddress(oMail) As String
    Dim outlookApp As Outlook.Application, oOutlook As Object
    Dim strAddress As String, strEntryId As String
    Dim objAddressentry As Outlook.AddressEntry, objExchangeUser As Outlook.ExchangeUser
    Dim objReply As Outlook.MailItem, objRecipient As Outlook.Recipient

    Set outlookApp = New Outlook.Application
    Set oOutlook = outlookApp.GetNamespace("MAPI")
    Set oInbox = oOutlook.GetDefaultFolder(olFolderInbox)

    If oMail.SenderEmailType = "SMTP" Then
        strAddress = oMail.SenderEmailAddress
    Else
        Set objReply = oMail.Reply()
        On Error Resume Next
        Set objRecipient = objReply.Recipients.Item(1)
        strEntryId = objRecipient.EntryID
        objReply.Close OlInspectorClose.olDiscard
        strEntryId = objRecipient.EntryID
        'On Error GoTo ErrorServerUnavailable
        Set objAddressentry = oOutlook.GetAddressEntryFromID(strEntryId)
        'On Error GoTo 0
        Set objExchangeUser = objAddressentry.GetExchangeUser()
        strAddress = objExchangeUser.PrimarySmtpAddress()
        On Error GoTo 0
    End If
    getSmtpMailAddress = strAddress
Exit Function

ErrorServerUnavailable:
    'MsgBox "Servidor de correos no puede ser contactado", vbInformation, "Error: Servidor de correos"
    'End
End Function

Habilitar macro

Normalmente, por razones de seguridad, las macros suelen permanecer inhabilitadas en Outlook. Para que funcione la macro tendras que sacrificar esa seguridad.

Con la opcion Notification for all macros, Outlook pedira permiso para correr la macro. Es mas seguro pero es incomodo, y sabiendo que tiene codigo que se activa cuando llega un correo, no tiene mucho sentido.  Con la opcion de enable all macros, ya la macro puede funcionar pero sin seguridad contra codigo malicioso.  Tendras que tener mucho cuidado para evitar virus y malware que pueda colarse alli.

Con ese codigo puedes agregar tantas alertas como quieras.  Claro, si pones alertas para cosas muy frecuentes, la macro te dara tantas alertas que no te dejara trabajar, asi que debes estudiar primero la frecuencia y el tipo de alerta.

 

 

¡Sé el primero en comentar!
Comentar