Skip to content
This repository
Browse code

Added outbound documentation, and fixed a few bugs while at it.

  • Loading branch information...
commit 1e8814dbe7518d7e4257dc94055562fba48b02b3 1 parent 8928f8e
Matt Sergeant authored October 13, 2011
15  config/outbound.bounce_message
... ...
@@ -0,0 +1,15 @@
  1
+Received: (Haraka {pid} invoked for bounce); {date}
  2
+Date: {date}
  3
+From: MAILER-DAEMON@{me}
  4
+To: {from}
  5
+Subject: failure notice
  6
+Message-Id: {msgid}
  7
+
  8
+Hi. This is the Haraka Mailer program at {me}.
  9
+I'm afraid I wasn't able to deliver your message to the following ddresses.
  10
+This is a permanent error; I've given up. Sorry it didn't work out.
  11
+
  12
+{to}: {reason}
  13
+
  14
+--- Below this line is a copy of the message.
  15
+
14  configfile.js
@@ -60,8 +60,8 @@ cfreader.load_config = function(name, type) {
60 60
         result = cfreader.load_json_config(name);
61 61
     }
62 62
     else {
63  
-        result = cfreader.load_flat_config(name);
64  
-        if (result && type !== 'list') {
  63
+        result = cfreader.load_flat_config(name, type);
  64
+        if (result && type !== 'list' && type !== 'data') {
65 65
             result = result[0];
66 66
             if (/^\d+$/.test(result)) {
67 67
                 result = parseInt(result);
@@ -112,9 +112,17 @@ cfreader.load_ini_config = function(name) {
112 112
     return result;
113 113
 };
114 114
 
115  
-cfreader.load_flat_config = function(name) {
  115
+cfreader.load_flat_config = function(name, type) {
116 116
     var result = [];
117 117
     var data   = new String(fs.readFileSync(name));
  118
+    if (type === 'data') {
  119
+        while (data.length > 0) {
  120
+            var match = data.match(/^([^\n]*)\n?/);
  121
+            result.push(match[1]);
  122
+            data = data.slice(match[0].length);
  123
+        }
  124
+        return result;
  125
+    }
118 126
     var lines  = data.split(/\r\n|\r|\n/);
119 127
     
120 128
     lines.forEach( function(line) {
106  docs/Outbound.md
Source Rendered
... ...
@@ -0,0 +1,106 @@
  1
+Outbound Mail with Haraka
  2
+=========================
  3
+
  4
+A default installation of Haraka will queue outbound mail for delivery in the
  5
+queue directory. Those mails will be delivered to the appropriate MX record
  6
+for that domain. Mails are queued onto your disk, and will deal appropriately
  7
+with temporary failures to retry delivery later.
  8
+
  9
+Outbound mails are defined as those that have set the `connection.relaying`
  10
+flag to `true` via a plugin. The simplest way of doing that is to use SMTP
  11
+AUTH, and have the client authenticate. For example using the `auth/flat_file`
  12
+plugin. However it is very simple to write a custom plugin to do this.
  13
+
  14
+Outbound Mail Hooks
  15
+-------------------
  16
+
  17
+### The queue_outbound hook
  18
+
  19
+The first hook that is called prior to queueing an outbound mail is the
  20
+`queue_outbound` hook. Only if all these hooks return `CONT` (or if there are
  21
+no hooks) will the mail be queued for outbound delivery. A return of `OK` will
  22
+indicate that the mail has been queued in some custom manner for outbound
  23
+delivery. Any of the `DENY` return codes will cause the message to be
  24
+appropriately rejected.
  25
+
  26
+### The get_mx hook
  27
+
  28
+Upon starting delivery the `get_mx` hook is called, with the parameter set to
  29
+the domain in question (for example a mail to `user@example.com` will call the
  30
+`get_mx` hook with `(next, hmail, domain)` as parameters). This is to allow
  31
+you to implement a custom handler to find MX records. For most installations
  32
+there is no reason to implement this hook - Haraka will find the correct MX
  33
+records for you.
  34
+
  35
+### The bounce hook
  36
+
  37
+If the mail completely bounces then the `bounce` hook is called. This is *not*
  38
+called if the mail is issued a temporary failure (a 4xx error code). The hook
  39
+parameter is the error message received from the remote end. If you do not wish
  40
+to have a bounce message sent to the originating sender of the email then you
  41
+can return `OK` from this hook to stop it from sending a bounce message.
  42
+
  43
+### The delivered hook
  44
+
  45
+When mails are successfully delivered to the remote end then the `delivered`
  46
+hook is called. The return codes from this hook have no effect, so it is only
  47
+useful for logging the fact that a successful delivery occurred.
  48
+
  49
+Bounce Messages
  50
+---------------
  51
+
  52
+The contents of the bounce message are configured by a file called
  53
+`config/outbound.bounce_message`. If you look at this file you will see it
  54
+contains several template entries wrapped in curly brackets. These will be
  55
+populated as follows:
  56
+
  57
+* pid - the current process id
  58
+* date - the current date when the bounce occurred
  59
+* me - the contents of `config/me`
  60
+* from - the originating sender of the message
  61
+* msgid - a uuid for the mail
  62
+* to - the end recipient of the message, or the first recipient if it was to
  63
+multiple people
  64
+* reason - the text from the remote server indicating why it bounced
  65
+
  66
+Following the bounce message itself will be a copy of the entire original
  67
+message.
  68
+
  69
+Creating a mail internally for outbound delivery
  70
+------------------------------------------------
  71
+
  72
+Sometimes it is necessary to generate a new mail from within a plugin.
  73
+
  74
+To do that, you can use the `outbound` module directly:
  75
+
  76
+    var outbound = require('./outbound');
  77
+    
  78
+    var plugin = this;
  79
+    
  80
+    var to = 'user@example.com';
  81
+    var from = 'sender@example.com';
  82
+    
  83
+    var contents = [
  84
+        "From: " + from,
  85
+        "To: " + to,
  86
+        "MIME-Version: 1.0",
  87
+        "Content-type: text/plain; charset=us-ascii",
  88
+        "Subject: Some subject here",
  89
+        "",
  90
+        "Some email body here",
  91
+        ""].join("\n");
  92
+        
  93
+    var outnext = function (code, msg) {
  94
+        switch (code) {
  95
+            case DENY:  plugin.logerror("Sending mail failed: " + msg);
  96
+                        break;
  97
+            case OK:    plugin.loginfo("mail sent");
  98
+                        next();
  99
+                        break;
  100
+            default:    plugin.logerror("Unrecognised return code from sending email: " + msg);
  101
+                        next();
  102
+        }
  103
+    };
  104
+    
  105
+    outbound.send_email(from, to, contents, outnext);
  106
+
23  outbound.js
@@ -858,22 +858,6 @@ HMailItem.prototype.try_deliver_host = function () {
858 858
     });
859 859
 }
860 860
 
861  
-var default_bounce_template = ['Received: (Haraka {pid} invoked for bounce); {date}\n',
862  
-'Date: {date}\n',
863  
-'From: MAILER-DAEMON@{me}\n',
864  
-'To: {from}\n',
865  
-'Subject: failure notice\n',
866  
-'Message-Id: {msgid}\n',
867  
-'\n',
868  
-'Hi. This is the Haraka Mailer program at {me}.\n',
869  
-'I\'m afraid I wasn\'t able to deliver your message to the following addresses.\n',
870  
-'This is a permanent error; I\'ve given up. Sorry it didn\'t work out.\n',
871  
-'\n',
872  
-'{to}: {reason}\n',
873  
-'\n',
874  
-'--- Below this line is a copy of the message.\n',
875  
-'\n'];
876  
-
877 861
 function populate_bounce_message (from, to, reason, hmail, cb) {
878 862
     var values = {
879 863
         date: new Date().toString(),
@@ -885,13 +869,10 @@ function populate_bounce_message (from, to, reason, hmail, cb) {
885 869
         msgid: '<' + utils.uuid() + '@' + config.get('me', 'nolog') + '>',
886 870
     };
887 871
     
888  
-    var bounce_msg_ = config.get('outbound.bounce_message', 'nolog', 'list');
889  
-    if (bounce_msg_.length === 0) {
890  
-        bounce_msg_ = default_bounce_template;
891  
-    }
  872
+    var bounce_msg_ = config.get('outbound.bounce_message', 'nolog', 'data');
892 873
     
893 874
     var bounce_msg = bounce_msg_.map(function (item) {
894  
-        return item.replace(/\{(\w+)\}/g, function (i, word) { return values[word] || '?' });
  875
+        return item.replace(/\{(\w+)\}/g, function (i, word) { return values[word] || '?' }) + '\n';
895 876
     });
896 877
     
897 878
     var data_stream = hmail.data_stream();

0 notes on commit 1e8814d

Please sign in to comment.
Something went wrong with that request. Please try again.