Besoin d’une réponse automatique Outlook qui ressemble à une vraie réponse ? Voici pas à pas comment bâtir une règle + macro VBA pour envoyer un « RE: <sujet d’origine> », conserver le fil et éviter les boucles. Alternatives sans code et options serveur incluses.
Objectif : une réponse automatique qui a l’air manuelle
Le besoin est simple mais précis : remplacer le préfixe imposé « Réponse automatique: » par un « RE: <sujet d’origine> » réellement dynamique, tout en gardant le fil (thread) d’origine intact : expéditeur, destinataires, suivi de conversation, contenu cité. L’idée est de donner l’illusion d’une réponse saisie à la main, utile quand on souhaite rester discret (absence courte, surcharge ponctuelle, support de première ligne, etc.).
Ce que vous allez obtenir
- Un objet personnalisé exactement au format « RE: <sujet d’origine> » sans doublons (« RE: RE: … »).
- Un corps de message personnalisable (texte « manuel », signature, balises dynamiques basiques) inséré au-dessus de la citation d’Outlook.
- Des garde‑fous anti‑boucles (no‑reply, OOF, listes, limitation 1 réponse/jour/adresse, etc.).
- La possibilité d’envoyer automatiquement ou de préafficher la réponse (mode « Display »).
- Des alternatives sans code et des pistes serveur si votre PC ne peut pas rester allumé.
Comparatif des approches
Approche | Principe | Points clés / Contraintes |
---|---|---|
Macro VBA + règle Outlook (solution réellement dynamique) | Créer une règle « Lors de la réception d’un message » → « Exécuter un script ». Dans le script : Set newMsg = Item.Reply newMsg.Subject = "RE: " & Item.Subject newMsg.Display ou newMsg.Send | Objet parfaitement personnalisé, sans doublon. Possibilité d’ajouter signature et message « manuel ». Prérequis : Outlook pour Windows classique, macros autorisées, action « Exécuter un script » disponible. Règle côté client : Outlook doit rester ouvert. |
Règle « Répondre avec un modèle » (alternative sans code) | Rédiger un modèle .oft avec un objet fixe (ex. « RE: »), puis créer une règle « Répondre en utilisant un modèle ». | Simple, aucun code. Objet statique : impossible d’injecter le sujet d’origine → ne répond pas totalement au besoin. |
Réponses automatiques (absences) | Options > « Réponses automatiques » | Objet imposé « Réponse automatique: … ». Pas conforme au cahier des charges. |
Solutions serveur / tierces | Agent côté Exchange/Microsoft 365, add‑in ou service SaaS. | Les règles de transport ne concatènent pas dynamiquement l’objet. Certains add‑ins le font (souvent payants) et fonctionnent 24/7 sans client ouvert. |
Compatibilité par environnement
Environnement | VBA / « Exécuter un script » | Remarques |
---|---|---|
Outlook pour Windows classique | Oui | Solution recommandée. Macros soumises à la stratégie de l’entreprise. |
Nouvelle application « Outlook pour Windows » | Non | Basée sur le Web : pas de VBA, pas d’« Exécuter un script ». |
Outlook sur le Web / mobile | Non | Utiliser une solution côté serveur (add‑in, automatisation). |
Outlook pour Mac | Non | Pas de VBA. Alternatives : script AppleScript limité ou solution serveur. |
Pré‑requis, sécurité et bonnes pratiques
- Macros signées : si votre organisation bloque les macros, signez la macro (certificat interne ou créé avec l’outil fourni par Office) et définissez la stratégie « Autoriser uniquement les macros signées ».
- Action « Exécuter un script » : peut nécessiter une activation par l’administrateur. Quand elle n’est pas disponible, la solution VBA n’est pas possible.
- PC allumé + Outlook ouvert : la règle est côté client, elle ne s’exécute que si Outlook est actif.
- Anti‑boucles : limitez à une réponse par expéditeur et par jour, ignorez les adresses « no‑reply », identifiez les réponses automatiques (en-têtes de message), filtrez éventuellement les remises et NDR.
- Conformité : selon votre politique, ajoutez en bas de votre message une mention du type « Message envoyé automatiquement » (RGPD, transparence).
Pas-à-pas : mettre en place la solution VBA + règle
Activer l’onglet Développeur
- Ouvrez Outlook > Fichier > Options > Personnaliser le Ruban.
- Cochez Développeur puis validez.
Créer et signer la macro
- Appuyez sur Alt+F11 pour ouvrir l’éditeur VBA.
- Menu Insertion > Module, puis collez l’un des codes ci‑dessous.
- Option recommandé : signez le projet (menu Outils > Signature numérique…). Vous pouvez générer un certificat utilisateur via l’outil standard fourni avec Office.
- Fermez l’éditeur, redémarrez Outlook si demandé.
Créer la règle Outlook « Exécuter un script »
- Fichier > Gérer les règles et alertes > Nouvelle règle.
- Sélectionnez « Appliquer la règle aux messages que je reçois ».
- Définissez des conditions utiles pour limiter le périmètre (par exemple « envoyé à mon nom », « expéditeur n’appartient pas à mon domaine » si vous ne voulez répondre qu’aux externes).
- Dans les actions, cochez Exécuter un script et choisissez la macro créée.
- Ajoutez des exceptions si nécessaire (ex. liste de diffusion, VIP, interne).
- Enregistrez.
Version express du code (suffisante dans la majorité des cas)
Ce bloc : 1) crée une vraie réponse conservant le fil, 2) force un unique « RE: » propre, 3) ajoute un message discret au‑dessus du texte cité. Par défaut il envoie automatiquement ; passez en Display
si vous préférez valider visuellement.
' Module Outlook VBA
Option Explicit
Public Sub AutoReply_RE(ByVal Item As Outlook.MailItem)
On Error GoTo ExitPoint
If Item Is Nothing Then Exit Sub
```
' Ignore les messages susceptibles de boucler ou inutiles
If IsAutoResponder(Item) Then Exit Sub
If IsNoReplyAddress(Item.SenderEmailAddress) Then Exit Sub
If AlreadyRepliedToday SenderSmtp(Item) Then Exit Sub
Dim newMsg As Outlook.MailItem
Set newMsg = Item.Reply
newMsg.Subject = BuildReplySubject(Item.Subject)
newMsg.HTMLBody = BuildCustomBody(Item) & newMsg.HTMLBody
' Astuce: affichez au lieu d'envoyer pour vos premiers tests
' newMsg.Display
newMsg.Send
MarkRepliedToday SenderSmtp(Item)
```
ExitPoint:
On Error Resume Next
End Sub
Private Function BuildReplySubject(ByVal original As String) As String
Dim cleaned As String
cleaned = StripCommonPrefixes(original)
BuildReplySubject = "RE: " & cleaned
End Function
Private Function StripCommonPrefixes(ByVal subj As String) As String
Dim s As String, i As Long, pfx As String
s = Trim(subj)
For i = 1 To 10
If Len(s) < 3 Then Exit For
pfx = LCase$(Left$(s, 3))
If pfx = "re:" Or pfx = "fw:" Or pfx = "tr:" Or pfx = "sv:" Or pfx = "aw:" Then
s = Trim$(Mid$(s, 4))
Else
Exit For
End If
Next
StripCommonPrefixes = s
End Function
Private Function BuildCustomBody(ByVal msg As Outlook.MailItem) As String
Dim dn As String
dn = HtmlEncode(msg.SenderName)
BuildCustomBody = "Bonjour " & dn & "," & _
"Merci pour votre message. Je reviens vers vous très vite." & _
"— Votre Nom
"
End Function
Private Function SenderSmtp(ByVal msg As Outlook.MailItem) As String
On Error Resume Next
Dim s As String
s = msg.SenderEmailAddress
If LCase$(msg.SenderEmailType) = "ex" Then
Dim exu As Outlook.ExchangeUser
Set exu = msg.Sender.GetExchangeUser
If Not exu Is Nothing Then s = exu.PrimarySmtpAddress
End If
SenderSmtp = LCase$(s)
End Function
Private Function IsNoReplyAddress(ByVal addr As String) As Boolean
Dim a As String: a = LCase$(addr)
IsNoReplyAddress = (InStr(a, "no-reply") > 0) Or (InStr(a, "noreply") > 0) Or (InStr(a, "donotreply") > 0)
End Function
Private Function IsAutoResponder(ByVal msg As Outlook.MailItem) As Boolean
On Error Resume Next
Dim hdr As String
hdr = GetHeaders(msg)
Dim h As String: h = LCase$(hdr)
If InStr(h, "auto-submitted:") > 0 Then IsAutoResponder = True
If InStr(h, "x-auto-response-suppress:") > 0 Then IsAutoResponder = True
If InStr(h, "precedence: bulk") > 0 Or InStr(h, "precedence: list") > 0 Then IsAutoResponder = True
' Heuristiques sujet
Dim s As String: s = LCase$(msg.Subject)
If InStr(s, "réponse automatique") > 0 Or InStr(s, "automatic reply") > 0 Then IsAutoResponder = True
End Function
Private Function GetHeaders(ByVal msg As Outlook.MailItem) As String
On Error Resume Next
GetHeaders = msg.PropertyAccessor.GetProperty("[http://schemas.microsoft.com/mapi/proptag/0x007D001E](http://schemas.microsoft.com/mapi/proptag/0x007D001E)")
End Function
Private Function HtmlEncode(ByVal s As String) As String
s = Replace$(s, "&", "&")
s = Replace$(s, "<", "<")
s = Replace$(s, ">", ">")
HtmlEncode = s
End Function
' ---- Limitation à une réponse par expéditeur et par jour ----
Private Function CachePath() As String
CachePath = Environ$("APPDATA") & "\AutoReplyRE\cache.csv"
End Function
Private Sub EnsureCacheFolder()
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
Dim folderPath As String: folderPath = Environ$("APPDATA") & "\AutoReplyRE"
If Not fso.FolderExists(folderPath) Then fso.CreateFolder folderPath
End Sub
Private Function AlreadyRepliedToday(ByVal addr As String) As Boolean
On Error Resume Next
EnsureCacheFolder
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
Dim p As String: p = CachePath
If Not fso.FileExists(p) Then Exit Function
Dim ts As Object: Set ts = fso.OpenTextFile(p, 1, False)
Dim line As String, parts() As String, today As String
today = Format$(Date, "yyyy-mm-dd")
Do While Not ts.AtEndOfStream
line = Trim$(ts.ReadLine)
If Len(line) > 0 Then
parts = Split(line, ";")
If UBound(parts) >= 1 Then
If LCase$(parts(0)) = addr And parts(1) = today Then
AlreadyRepliedToday = True: Exit Do
End If
End If
End If
Loop
ts.Close
End Function
Private Sub MarkRepliedToday(ByVal addr As String)
On Error Resume Next
EnsureCacheFolder
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
Dim p As String: p = CachePath
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
Dim today As String: today = Format$(Date, "yyyy-mm-dd")
' Charger existant
If fso.FileExists(p) Then
Dim ts As Object: Set ts = fso.OpenTextFile(p, 1, False)
Dim line As String, parts() As String
Do While Not ts.AtEndOfStream
line = Trim$(ts.ReadLine)
If Len(line) > 0 Then
parts = Split(line, ";")
If UBound(parts) >= 1 Then dict(LCase$(parts(0))) = parts(1)
End If
Loop
ts.Close
End If
' Mettre à jour
dict(addr) = today
' Sauvegarder
Dim ts2 As Object: Set ts2 = fso.OpenTextFile(p, 2, True)
Dim k As Variant
For Each k In dict.Keys
ts2.WriteLine CStr(k) & ";" & CStr(dict(k))
Next
ts2.Close
End Sub
Version avancée : options d’orfèvre
Le bloc suivant ajoute des options supplémentaires : restriction aux expéditeurs externes, choix du compte d’envoi, insertion d’une signature HTML enregistrée, mode test « Display », journalisation d’erreurs, etc.
' Module Outlook VBA
Option Explicit
' ---------------- Configuration ----------------
Private Const EXTERNAL_ONLY As Boolean = False ' True = répondre seulement aux expéditeurs externes
Private Const SEND_IMMEDIATELY As Boolean = True ' False = prévisualiser (Display)
Private Const PREFERRED_SENDER As String = "" ' Renseignez "[alias@domaine.com](mailto:alias@domaine.com)" si vous avez plusieurs comptes
Private Const SIGNATURE_NAME As String = "" ' Nom de votre signature Outlook (fichier .htm)
' ------------------------------------------------
Public Sub AutoReply_RE_Advanced(ByVal Item As Outlook.MailItem)
On Error GoTo Fail
If Item Is Nothing Then Exit Sub
```
If ShouldSkip(Item) Then Exit Sub
If EXTERNAL_ONLY And IsInternal(Item) Then Exit Sub
If AlreadyRepliedToday SenderSmtp(Item) Then Exit Sub
Dim reply As Outlook.MailItem
Set reply = Item.Reply
reply.Subject = BuildReplySubject(Item.Subject)
Dim custom As String
custom = BuildPoliteBody(Item) ' personnalisez ici
If Len(SIGNATURE_NAME) > 0 Then custom = custom & LoadSignatureHtml(SIGNATURE_NAME)
reply.HTMLBody = custom & reply.HTMLBody
If Len(PREFERRED_SENDER) > 0 Then
ApplyAccount reply, PREFERRED_SENDER
End If
If SEND_IMMEDIATELY Then reply.Send Else reply.Display
MarkRepliedToday SenderSmtp(Item)
Exit Sub
```
Fail:
LogError "AutoReply_RE_Advanced", Err.Number, Err.Description
End Sub
Private Function ShouldSkip(ByVal msg As Outlook.MailItem) As Boolean
If msg Is Nothing Then ShouldSkip = True: Exit Function
If IsAutoResponder(msg) Then ShouldSkip = True: Exit Function
If IsNoReplyAddress(msg.SenderEmailAddress) Then ShouldSkip = True: Exit Function
' Option: ignorez certaines boîtes, sujets, etc.
End Function
Private Function BuildPoliteBody(ByVal msg As Outlook.MailItem) As String
BuildPoliteBody = "Bonjour " & HtmlEncode(msg.SenderName) & "," & _
"Merci pour votre message. Je suis momentanément indisponible et je vous réponds d’ici peu." & _
"Bien cordialement,
Votre Nom
"
End Function
Private Sub ApplyAccount(ByVal m As Outlook.MailItem, ByVal smtp As String)
On Error Resume Next
Dim acc As Outlook.Account
For Each acc In Application.Session.Accounts
If LCase$(acc.SmtpAddress) = LCase$(smtp) Then
Set m.SendUsingAccount = acc
Exit For
End If
Next
End Sub
Private Function IsInternal(ByVal msg As Outlook.MailItem) As Boolean
Dim mySmtp As String: mySmtp = DefaultSmtp()
Dim myDomain As String: myDomain = DomainFromEmail(mySmtp)
Dim snd As String: snd = DomainFromEmail(SenderSmtp(msg))
IsInternal = (Len(myDomain) > 0 And LCase$(myDomain) = LCase$(snd))
End Function
Private Function DefaultSmtp() As String
On Error Resume Next
DefaultSmtp = Application.Session.Accounts.Item(1).SmtpAddress
End Function
Private Function DomainFromEmail(ByVal addr As String) As String
Dim atPos As Long: atPos = InStr(1, addr, "@")
If atPos > 0 Then DomainFromEmail = Mid$(addr, atPos + 1)
End Function
' --- Réutilisation des fonctions utiles de la version express ---
' (StripCommonPrefixes, BuildReplySubject, SenderSmtp, IsNoReplyAddress,
' IsAutoResponder, GetHeaders, HtmlEncode, AlreadyRepliedToday, MarkRepliedToday)
Private Sub LogError(ByVal where As String, ByVal n As Long, ByVal d As String)
On Error Resume Next
EnsureCacheFolder
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
Dim p As String: p = Environ$("APPDATA") & "\AutoReplyRE\errors.log"
Dim ts As Object: Set ts = fso.OpenTextFile(p, 8, True)
ts.WriteLine Format$(Now, "yyyy-mm-dd hh:nn:ss") & " | " & where & " | " & CStr(n) & " | " & d
ts.Close
End Sub
Private Function LoadSignatureHtml(ByVal sigName As String) As String
On Error Resume Next
Dim f As String
f = Environ$("APPDATA") & "\Microsoft\Signatures" & sigName & ".htm"
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FileExists(f) Then Exit Function
Dim ts As Object: Set ts = fso.OpenTextFile(f, 1, False)
LoadSignatureHtml = ts.ReadAll
ts.Close
End Function
Conseils d’implémentation pour éviter les mauvaises surprises
- Commencez en mode « Display » : laissez
.Display
au lieu de.Send
le temps de valider format et ton. - Test croisé : envoyez‑vous un mail depuis une boîte externe (Gmail, etc.) pour vérifier l’objet, le threading, l’anti‑boucle, la présence de signature.
- Empêchez les doubles RE: la fonction
StripCommonPrefixes
supprime les préfixes connus avant de préfixer en « RE: ». - Filtrez les « no‑reply » : évitez les réponses inutiles.
- Limitez à un envoi/jour/adresse : le cache simple proposé suffit dans 99 % des cas et peut être vidé au redémarrage si besoin.
- Définissez le périmètre : via la règle, ciblez les messages « pour moi » seulement, et/ou EXTERNAL si votre annuaire sépare bien interne/externe.
- Respectez la transparence : si votre politique l’exige, ajoutez une discrète mention « envoyé automatiquement » en bas de page.
Modèles de message « discrets » prêts à coller
Situation | Texte suggéré |
---|---|
Occupé en rendez‑vous | Bonjour {Nom}, merci pour votre message. Je suis en rendez‑vous et reviens vers vous dans la journée. |
Absence courte <24h | Bonjour {Nom}, je suis momentanément indisponible et vous réponds demain matin. Si urgent : {contact de délégation}. |
Support niveau 1 | Bonjour {Nom}, votre demande est bien reçue. Nous l’examinons et revenons vers vous sous peu avec les prochaines étapes. |
Alternative sans code : règle « Répondre avec un modèle »
Si votre environnement bloque les macros, vous pouvez créer un modèle .oft
et une règle « Répondre en utilisant un modèle ». C’est simple, mais l’objet restera figé (par exemple « RE: ») : vous ne pourrez pas insérer automatiquement le sujet original. Procédure :
- Rédigez un nouveau message, ajustez objet (ex. « RE: ») et corps, puis Fichier > Enregistrer sous > type Modèle Outlook (*.oft).
- Créez la règle : Gérer les règles et alertes > Nouvelle règle > « Répondre en utilisant un modèle spécifique » > sélectionnez le
.oft
.
Pourquoi les « Réponses automatiques » natives ne conviennent pas
La fonctionnalité d’absence du bureau force un objet « Réponse automatique: … » et n’autorise pas l’édition dynamique de l’objet. Même si le corps est personnalisable, l’objet restera détectable comme automatique.
Scénarios 24/7 sans poste allumé
Si vous ne pouvez pas laisser Outlook ouvert :
- Add‑in/agent côté serveur (Exchange/Microsoft 365) : certaines solutions commerciales savent générer des réponses avec objet dynamique et threading correct directement sur la boîte aux lettres. Avantage : haute disponibilité, conforme aux politiques centralisées.
- Automatisation cloud : des flux côté tenant peuvent intercepter un nouveau mail et envoyer un message de suivi. Attention : l’action « répondre » conserve le fil mais n’expose pas toujours l’objet ; l’action « envoyer un nouveau mail » permet l’objet mais peut rompre le fil si l’en‑tête In‑Reply‑To n’est pas géré.
Dépannage et vérifications rapides
Symptôme | Cause probable | Action |
---|---|---|
L’action « Exécuter un script » n’apparaît pas | Action désactivée par la politique de l’entreprise | Demandez à l’administrateur de l’activer. Sans cela, la solution VBA n’est pas possible. |
La macro ne s’exécute pas | Macros bloquées ou non signées | Signez la macro et choisissez un niveau de sécurité qui accepte les macros signées uniquement. |
Boucle avec un autre auto‑répondeur | Expéditeur automatique non filtré | Renforcez IsAutoResponder (en‑têtes, mots‑clés) et gardez la limite 1/jour/adresse. |
Objet « RE: RE: … » | Préfixe non normalisé | Vérifiez la fonction StripCommonPrefixes . |
Signature absente | Les signatures n’apparaissent pas automatiquement en VBA | Chargez le fichier .htm de la signature via LoadSignatureHtml et concaténez‑le. |
Checklist avant départ
- La règle est bien activée et limitée au périmètre voulu.
- La macro est signée et autorisée.
- Le message d’accroche est validé par votre équipe et conforme à la charte.
- Test externe réussi : objet parfait, fil conservé, pas de double envoi.
- Le PC reste allumé, Outlook ouvert, mise en veille désactivée pendant l’absence.
Questions fréquentes
Est‑ce que les pièces jointes sont renvoyées ? Non, une réponse (Reply) n’inclut pas les pièces jointes d’origine ; c’est normal et cohérent avec l’objectif « réponse courte ». Si vous devez renvoyer les pièces, votre script devrait plutôt faire un Forward (perte du fil) ou les ré‑attacher manuellement.
Peut‑on répondre depuis un alias particulier ? Oui, renseignez PREFERRED_SENDER
et la macro sélectionnera le compte d’envoi correspondant si présent dans Outlook.
Et si je veux répondre seulement aux mails externes ? Passez EXTERNAL_ONLY = True
dans la version avancée (simple comparaison de domaines). Ajustez si vous avez des sous‑domaines internes multiples.
Comment modifier le texte du message ? Éditez BuildCustomBody
/BuildPoliteBody
. Vous pouvez insérer msg.SenderName
pour une salutation personnalisée.
Comment réinitialiser la limite 1/jour/adresse ? Supprimez le fichier cache.csv
situé dans %APPDATA%\AutoReplyRE
(ou arrêtez/reprenez Outlook si vous automatisez le nettoyage au démarrage).
Mentions conformité et éthique
Donner l’apparence d’une réponse manuelle est acceptable pour une gestion pragmatique de la charge, à condition de rester transparent vis‑à‑vis des obligations internes (mentions automatiques, conservation des preuves, confidentialité). Évitez toute formulation trompeuse ou qui impliquerait une action déjà réalisée alors que ce n’est pas le cas.
En résumé
- Solution fiable et gratuite : Macro VBA + règle « Exécuter un script ». C’est la seule manière côté client d’obtenir « RE: <sujet d’origine> » dynamique tout en gardant le fil.
- Alternative sans code : modèle + règle (objet statique).
- Rôle des fonctions natives : « Réponses automatiques » ≠ besoin visé (objet imposé).
- Disponibilité 24/7 : passer par une solution côté serveur si Outlook ne peut pas rester ouvert.