hmm: Nodemailer von Node.js

Moin Moin,

ich soll eine Anwendung schreiben die Name und EMail entgegen nimmt und einen Aktivierungslink an den EMail Inhaber sendet.

Gegeben habe ich folgende daten:

   var transporterObjectConfig = nodemailer.createTransport('SMTP', {
    host: 'exchange.tu-berlin.de',
    port: '587',
    secure: false,
    requireTLS: true,
    auth: {
    user: 'ich@win.tu-berlin.de',
    pass: 'meinpassword'
    }
    });

das grundgerüst von nodemailer sieht so aus:

    var nodemailer = require('nodemailer');
    
    var transporter = nodemailer.createTransport('smtps://user%40gmail.com:pass@smtp.gmail.com');
       
    // setup e-mail data with unicode symbols
    var mailOptions = {
        from: '"Christopher" <ich@campus.tu-berlin.de>', // sender address
        to: 'ichk@gmx.de', // list of receivers
        subject: 'Hello ✔', // Subject line
        text: 'Hello world ?', // plaintext body
        html: '<b>Hello world ?</b>' // html body
    };
    
    // send mail with defined transport object
    transporter.sendMail(mailOptions, function(error, info){
        if(error){
            return console.log(error);
        }
        console.log('Message sent: ' + info.response);
    });

fragen:

  1. für die eingabe würde ich eine form in html schreiben mit einem sende button, wie fliegt die form eingabe rüber in mein node.js script? bisher habe ich node.js immer nur per console "node test.js" gestartet

  2. mein akuteller versuch, bei dem ich mir eine mail schicken wollte, scheitert:

    var nodemailer = require('nodemailer');
    
    //var transporter = nodemailer.createTransport('smtps://user%40gmail.com:pass@smtp.gmail.com');
    
    var transporterObjectConfig = nodemailer.createTransport('SMTP', {
    host: 'exchange.tu-berlin.de',
    port: '587',
    secure: false,
    requireTLS: true,
    auth: {
    user: 'ich@win.tu-berlin.de',
    pass: 'meins'
    }
    });

    
    // setup e-mail data with unicode symbols
    var mailOptions = {
        from: '"Christopher" <ich@campus.tu-berlin.de>', // sender address
        to: 'ich@gmx.de', // list of receivers
        subject: 'Hello ✔', // Subject line
        text: 'Hello world ?', // plaintext body
        html: '<b>Hello world ?</b>' // html body
    };
    
    // send mail with defined transport object
    transporterObjectConfig.sendMail(mailOptions, function(error, info){
        if(error){
            return console.log(error);
        }
        console.log('Message sent: ' + info.response);
    });

passwörter und email habe ich richtig eingetragen. fehlermeldung:

/home/ubuntu/workspace/node_modules/nodemailer/lib/mailer/index.js:31 compile: [(...args) => this._convertDataImages(...args)], ^^^

SyntaxError: Unexpected token ... at exports.runInThisContext (vm.js:53:16) at Module._compile (module.js:373:25) at Object.Module._extensions..js (module.js:416:10) at Module.load (module.js:343:32) at Function.Module._load (module.js:300:12) at Module.require (module.js:353:17) at require (internal/module.js:12:17) at Object.<anonymous> (/home/ubuntu/workspace/node_modules/nodemailer/lib/nodemailer.js:3:16) at Module._compile (module.js:409:26) at Object.Module._extensions..js (module.js:416:10)

transporterObjectConfig ist von der uni vorgegeben, wie benutze ich das? ich habe auch etwas von eindeutigen strings gelesen, aber das deckt sich nicht mit verschiedenen quellen die ich im internet gefunden habe. wie ist der nächste schritt zum email verwenden?

  1. Moin,

    SyntaxError: Unexpected token …

    befasse Dich mal mit Mail-Headern und dem Deklarieren von Content-Types verschiedener Zeichenkodierungen. Des Weiteren mit Transfer-Encoding und MIME. Da sind nämlich alles Dinge die selbstverständlich auch für Node.js gelten. Guck Dir die Maildatei an, die erstellt wird und versendet werden soll. Dann findest Du auch den Fehler.

    PS: In Self beschrieben -- Der Zugriff auf FormularElemente.

  2. Hallo hmm,

    1. für die eingabe würde ich eine form in html schreiben mit einem sende button, wie fliegt die form eingabe rüber in mein node.js script? bisher habe ich node.js immer nur per console "node test.js" gestartet

    Dafür musst du einen HTTP-Server in Node.js starten und dort das notwendige HTML ausliefern. Siehe auch https://nodejs.org/api/http.html.

    1. mein akuteller versuch, bei dem ich mir eine mail schicken wollte, scheitert:
        var nodemailer = require('nodemailer');
        
        //var transporter = nodemailer.createTransport('smtps://user%40gmail.com:pass@smtp.gmail.com');
        
        var transporterObjectConfig = nodemailer.createTransport('SMTP', {
        host: 'exchange.tu-berlin.de',
        port: '587',
        secure: false,
        requireTLS: true,
        auth: {
        user: 'ich@win.tu-berlin.de',
        pass: 'meins'
        }
        });
    
        
        // setup e-mail data with unicode symbols
        var mailOptions = {
            from: '"Christopher" <ich@campus.tu-berlin.de>', // sender address
            to: 'ich@gmx.de', // list of receivers
            subject: 'Hello ✔', // Subject line
            text: 'Hello world ?', // plaintext body
            html: '<b>Hello world ?</b>' // html body
        };
        
        // send mail with defined transport object
        transporterObjectConfig.sendMail(mailOptions, function(error, info){
            if(error){
                return console.log(error);
            }
            console.log('Message sent: ' + info.response);
        });
    

    passwörter und email habe ich richtig eingetragen. fehlermeldung:

    /home/ubuntu/workspace/node_modules/nodemailer/lib/mailer/index.js:31 compile: [(...args) => this._convertDataImages(...args)], ^^^

    SyntaxError: Unexpected token ... at exports.runInThisContext (vm.js:53:16) at Module._compile (module.js:373:25) at Object.Module._extensions..js (module.js:416:10) at Module.load (module.js:343:32) at Function.Module._load (module.js:300:12) at Module.require (module.js:353:17) at require (internal/module.js:12:17) at Object.<anonymous> (/home/ubuntu/workspace/node_modules/nodemailer/lib/nodemailer.js:3:16) at Module._compile (module.js:409:26) at Object.Module._extensions..js (module.js:416:10)

    Das sieht aus wie ein JS-Fehler, aber ich kann in dem von dir geposteten Code keinen Fehler entdecken. Kannst du irgendwo das ganze Projekt online stellen?

    LG,
    CK

    1. So, kein Fehler?

      ✔ im Header ist schonmal einer.

      1. Hallo pl,

        So, kein Fehler?

        Lesen und verstehen. Die Fehlermeldung scheint vom Node.js-Modul-Framework zu kommen, dass einen Syntax-Fehler anmäkelt, nicht vom Mail verschicken. Ich kann allerdings keinen Syntax-Fehler finden.

        ✔ im Header ist schonmal einer.

        Wenn du meinst, dass das checkmark ein Fehler ist, dann muss ich dich leider enttäuschen: ob das ein Fehler ist oder nicht lässt sich mit den zugrunde liegenden Informationen nicht sagen. Wer weiss, was dieser nodemailer macht – ich kann mir durchaus vorstellen, dass er die Header auch entsprechend kodiert.

        LG,
        CK

        1. Wenn du meinst, dass das checkmark ein Fehler ist, dann muss ich dich leider enttäuschen: ob das ein Fehler ist oder nicht lässt sich mit den zugrunde liegenden Informationen nicht sagen.

          Doch, überlege mal logisch, Du bist doch Programmierer: Ohne jegliche Angabe einer zu beabsichtigten Kodierung kann das nicht richtig sein.

          Weil, und das dürfte sich doch mittlerweile auch rumgesprochen haben, es keine Möglichkeit gibt, eine Kodierung automatisch zu ermitteln.

          MfG

          1. Hallo pl,

            Wenn du meinst, dass das checkmark ein Fehler ist, dann muss ich dich leider enttäuschen: ob das ein Fehler ist oder nicht lässt sich mit den zugrunde liegenden Informationen nicht sagen.

            Doch, überlege mal logisch, Du bist doch Programmierer: Ohne jegliche Angabe einer zu beabsichtigten Kodierung kann das nicht richtig sein.

            Als Source-Encoding geht man von UTF-8 aus. Das ist in den meisten Umgebungen inzwischen üblich. Der Rest ist irrelevant, da es automatisch entschieden werden kann.

            LG,
            CK

    2. hm ganz onlinestellen ist soeine sache.

      ich arbeite in der ide cloud 9 io (von der uni vorgegeben), dass teil stellt die sachen bereits unter einer url online. beispiel: ich habe eine index.html, dann kann ich machen das die seite unter blabla/index.html online gestellt wird. aber aktuell habe ich nur den js code den ich mit "node mail.js" starte, den aufruf per html habe ich noch nicht gebaut.

      das ganze ist ein node js projekt (cloud 9 io stellt das als default parat) und ich habe nodemailer wie folgt installiert:

      npm install nodemailer npm WARN package.json chat-example@0.0.0 No repository field. npm WARN package.json chat-example@0.0.0 No license field. npm WARN engine nodemailer@3.1.0: wanted: {"node":">=6.0.0"} (current: {"node":"4.6.1","npm":"2.15.9"}) nodemailer@3.1.0 node_modules/nodemailer

      sind die warnmeldungen relevant?

      das projekt besteht ansonsten nur aus:

          var nodemailer = require('nodemailer');
          
          //var transporter = nodemailer.createTransport('smtps://user%40gmail.com:pass@smtp.gmail.com');
          
          var transporterObjectConfig = nodemailer.createTransport('SMTP', {
          host: 'exchange.tu-berlin.de',
          port: '587',
          secure: false,
          requireTLS: true,
          auth: {
          user: 'xxx@win.tu-berlin.de',
          pass: 'xxx'
          }
          });
      
          
          // setup e-mail data with unicode symbols
          var mailOptions = {
              from: '"Christopher" <wyczisk@campus.tu-berlin.de>', // sender address
              to: 'wyczisk@gmx.de', // list of receivers
              subject: 'Hello', // Subject line
              text: 'Hello world ?', // plaintext body
              html: '<b>Hello world ?</b>' // html body
          };
          
          // send mail with defined transport object
          transporterObjectConfig.sendMail(mailOptions, function(error, info){
              if(error){
                  return console.log(error);
              }
              console.log('Message sent: ' + info.response);
          });
      

      stimmt der aufruf nodemailer.createTransport?

      1. ok, gerade hab ich gelesen das nodemailer garnicht in cloud 9 io funktioniert, ich installier jetzt erstmal node auf meinem laptop

        1. so auf windows installiert.

          jetzt sagt mir die konsole:

          cannot create property 'mailer' on string 'SMTP' blabla

          1. ` var nodemailer = require('nodemailer');

            var transporterObjectConfig = nodemailer.createTransport({
            host: 'exchange.tu-berlin.de',
            port: '587',
            secure: false,
            requireTLS: true,
            auth: {
            user: 'xxx@win.tu-berlin.de',
            pass: 'xxx'
            }
            });
            
            
            // setup e-mail data with unicode symbols
            var mailOptions = {
                from: '"Christopher" <wyczisk@campus.tu-berlin.de>', // sender address
                to: 'wyczisk@gmx.de', // list of receivers
                subject: 'Hello', // Subject line
                text: 'Hello world ?', // plaintext body
                html: '<b>Hello world ?</b>' // html body
            };
            
            // send mail with defined transport object
            transporterObjectConfig.sendMail(mailOptions, function(error, info){
                if(error){
                    return console.log(error);
                }
                console.log('Message sent: ' + info.response);
            });`
            

            'SMTP', -> das rausnehmen, dann gehts

            so, der email soll ein für 5 minuten erreichbarer link angefügt werden:

            "Übermitteln Sie in der Mail einen sehr langen, nicht zu erratenden und für jeden Registrierer einen anderen Link, z.B. http://localhost:8080/regs/861safd64fa412135dsaf463da5s43f. . . Diese URL kann dann für 5min an ihrem Server angesprochen werden und wird danach ungültig. Wenn der Benutzer im gültigen Zeitraum darauf zugreift, dann wird eine ErfolgsbestätigungsWebseite angezeigt, andernfalls eine Fehlerbenachrichtigung mit der Möglichkeit zur erneuten Registrierung. "

            soll ich mir so eine unterseite einfach für 5 min bauen per:

            // include the http module
            var http = require('http');
            
            // create a webserver
            http.createServer(function (req, res) {
            
                // respond to any incoming http request
                res.writeHead(200, {'Content-Type': 'text/plain'});
                res.end('Hello World\n');
            
            }).listen(8080, '127.0.0.1');
            
            // log what that we started listening on localhost:1337
            console.log('Server running at 127.0.0.1:8080');
            

            und dann einfach gucken wie ich 5 min messe?

            "Zusatzfrage: Welche einfache Möglichkeit fällt Ihnen ein für eine HTML-Mail zu erkennen, ob der Empfänger bereits die Mail gelesen hat, wenn Sie einen im Internet ansprechbaren Server besitzen? "

            da zusatzfrage würde ich die ignorieren und am wochenende rätzeln. habt ihr paar hinweise (ohne lösung)?

            1. Hello,

              "Zusatzfrage: Welche einfache Möglichkeit fällt Ihnen ein für eine HTML-Mail zu erkennen, ob der Empfänger bereits die Mail gelesen hat, wenn Sie einen im Internet ansprechbaren Server besitzen? "

              da zusatzfrage würde ich die ignorieren und am wochenende rätzeln. habt ihr paar hinweise (ohne lösung)?

              • atime(), ctime(), mtime() der Ressource
              • Access-Log im Webserver
              • eigene Kontrolldatei schreiben lassen mit den Zugriffsdaten/-zeiten

              Liebe Grüße
              Tom S.

              --
              Die Krawatte ist das Kopftuch des Westens
            2. Tach!

              soll ich mir so eine unterseite einfach für 5 min bauen per: [...] und dann einfach gucken wie ich 5 min messe?

              Ich tät eine Datenhaltung nehmen und für jede Anfrage die erzeugte ID und einen Timestamp festhalten, nebst den anderen für deinen konkreten Fall interessanten Daten. Zum testen, ob die ID drin ist, würde ich vorher alle Datensätze löschen, deren Timestamp älter als jetzt minus 5 Minuten ist, dann schauen, ob für die ID ein Eintrag in der Datenhaltung enthalten ist.

              "Zusatzfrage: Welche einfache Möglichkeit fällt Ihnen ein für eine HTML-Mail zu erkennen, ob der Empfänger bereits die Mail gelesen hat, wenn Sie einen im Internet ansprechbaren Server besitzen?"

              Es gibt keine zuverlässig funktionierende Methode. Ansonsten geht dich diese Information nichts an und ist vermutlich auch nicht mit dem Datenschutz vereinbar. Aber du kannst ja mal selbst nachdenken. Was braucht man denn, um diese Information zu erhalten? Eine Benachrichtigung des Servers. Wie bekommt der Server die Information? Indem was angefordert wird, das nicht in der Mail enthalten ist, aber zur Anzeige benötigt wird. Aber meist machen die Mail-Clients solche Requests nicht ohne den Anwender vorher zu fragen, ob Dinge nachgeladen werden sollen.

              dedlfix.

              1. ich habe eine index.html und eine helloworld.js

                die helloworld.js sieht so aus:

                var express = require('express'); var app = express();

                var express = require('express');
                var app = express();
                
                app.get('/', function (req, res) {
                  res.send('Hello World!');
                });
                
                app.get('/test', function (req, res) {
                	console.log('works');
                });
                
                app.listen(3000, function () {
                  console.log('Example app listening on port 3000!');
                });
                

                ich kann node helloworld.js machen was auch geht. aber wie schaff ich es dass meine index.html ebenfalls auf localhost:300/bla gestartet wird so dass die komunikation funktioniert?

                1. auch diese scheiße funktioniert jetzt, allerdings richtig unsauber weil ich kein bock mehr habe:

                  
                  
                  var express = require('express');
                  var app = express();
                  var path = require('path');
                  
                  app.get('/', function(req, res) {
                      res.sendFile(path.join(__dirname + '/index.html'));
                  });
                  
                  app.get('/hello', function (req, res) {
                    res.send('Hello World!');
                  });
                  
                  app.post('/test', function (req, res) {
                  	console.log('works');
                  	
                  	    var nodemailer = require('nodemailer');
                      
                      var transporterObjectConfig = nodemailer.createTransport({
                      host: 'hostname',
                      port: '587',
                      secure: false,
                      requireTLS: true,
                      auth: {
                      user: 'username',
                      pass: 'password'
                      }
                      });
                  
                      
                      // setup e-mail data with unicode symbols
                      var mailOptions = {
                          from: 'sender address', // sender address
                          to: 'recipient', // list of receivers
                          subject: 'Hello', // Subject line
                          text: 'Hello world ?', // plaintext body
                          html: '<b>Hello world ?</b>' // html body
                      };
                      
                      // send mail with defined transport object
                      transporterObjectConfig.sendMail(mailOptions, function(error, info){
                          if(error){
                              return console.log(error);
                          }
                          console.log('Message sent: ' + info.response);
                      });
                  });
                  
                  app.listen(3000, function () {
                    console.log('Example app listening on port 3000!');
                  });
                  

                  und html:

                  <!DOCTYPE html>
                  <html lang="en">
                  <head>
                      <meta charset="UTF-8">
                      <title>Sample Site</title>
                  	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
                      <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
                      <style>
                          body { padding-top:50px; }
                      </style>
                  </head>
                  <body>
                  <input name="like" id="like" value="Like" type="submit" />
                      <div class="container">
                          <div class="jumbotron">
                              <h1>res.sendFile() Works!</h1>
                          </div>
                      </div>
                  	
                  	<script>
                  		$('#like').click(function(){
                  			$.post('/test');
                  		});
                  	</script>
                      
                  </body>
                  </html>
                  

                  jetzt bau ich email und username eingabe. im anschluss zerbrech ich mir den kopf über aktivierungslink

                  1. Moin,

                    in deinem HTML-Code ist etwas zu viel,

                    	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
                    

                    und an anderer Stelle zu kompliziert:

                    <body>
                    <input name="like" id="like" value="Like" type="submit" />
                    	
                    	<script>
                    		$('#like').click(function(){
                    			$.post('/test');
                    		});
                    	</script>
                        
                    </body>
                    

                    Denn dieser Code geht auch viel billiger ohne mit jQuery auf gutes altes HTML zu schießen:

                    <form action="/test" method="post">
                      <input name="like" id="like" value="Like" type="submit" />
                    </form>
                    

                    Viele Grüße
                    Robert

                    1. Hallo Robert B.,

                      <form action="/test" method="post">
                        <input name="like" id="like" value="Like" type="submit" />
                      </form>
                      

                      Und für einen Button kann man auch das richtige Element verwenden 😉

                      Bis demnächst
                      Matthias

                      --
                      Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
            3. Eine Möglichkeit

              An die Emailadresse einen Timestamp mit dem Ablaufdatum dranhängen. Davon einen Hash bilden. example.org/confirm?8ge4gKjpsdge56x9s9s

              Wenn die Linkanfrage kommt Hash auslesen ob noch gültig und entsprechen weiterleiten.

              Create Securelink oder Oneway(time)link findet in der Suchmaschine einiges.

  3. Tach!

    1. für die eingabe würde ich eine form in html schreiben mit einem sende button, wie fliegt die form eingabe rüber in mein node.js script? bisher habe ich node.js immer nur per console "node test.js" gestartet

    So wie das im Internet üblich ist. Wenn einer bedient werden soll (Client) braucht es einen, der ihn bedient (Server).

    passwörter und email habe ich richtig eingetragen. fehlermeldung:

    Vielleicht doch nicht. Am besten eine IDE nehmen, die sich mit Javascript auskennt, dann bekommt man syntaktische Fehler gleich angezeigt.

    dedlfix.