5

I am trying to use the following code to send out meeting request using nodemailer. The problem I am facing is that the meeting invite is going as an attachment ics file instead of request where one can directly add. I have tried it on multiple mail client. Any pointers would be highly appreciated.

transport.sendMail({
                    from: 'BakBak.io <biplav.saraf@gmail.com>',
                    to: 'biplav.saraf@gmail.com',
                    subject: 'Meeting',
                    //html: "Hi",
                    text: "Hola!!",
                    alternative: {
                      contentType: "text/calendar; method=REQUEST; name='meeting.ics';component=VEVENT",
                      contents: new Buffer(cal.toString()),
                      contentEncoding:"7bit",
                      "Content-Class":"urn:content-classes:calendarmessage"
                    },
                    headers: {
                              "Content-Type": "text/calendar", 
                              //"charset":"utf-8",
                              "method":"REQUEST",
                              "component":"VEVENT",
                              "Content-Class":"urn:content-classes:calendarmessage"
                            }//,
                    //attachments : [{filename:'invite.ics',contents: cal.toString()}]
                    }, function(err, responseStatus) {
                    if (err) {
                        console.log(err);
                        res.render('schedule',{errors: err.message});
                    } else {
                        console.log(responseStatus.message);
                        res.render('schedule',{success_msg: "Successfully Created!"});
                    }
                });
biplav
  • 781
  • 6
  • 13

3 Answers3

2

Gmail does not show meeting request and give an option to add to calendar if sender and receiver are same.

This is what worked for me:

transport.sendMail({
                    from: 'BakBak.io <biplav.saraf@gmail.com>',
                    to: 'donateoldspectacles@gmail.com',
                    subject: 'Meeting',
                    html: "Hiya!!",
                    text: "Hola!!",
                    alternatives: [{
                      contentType: "text/calendar",
                      content: new Buffer(ical)
                    }]
                    }, function(err, responseStatus) {
                    if (err) {
                        console.log(err);
                        res.render('schedule',{errors: err.message});
                    } else {
                        console.log(responseStatus.message);
                        res.render('schedule',{success_msg: "Successfully Created!"});
                    }
                });
Oliver Salzburg
  • 21,652
  • 20
  • 93
  • 138
biplav
  • 781
  • 6
  • 13
  • What are you passing as ical ? string? Since I have a problem with nodemailer and alternatives section which is not being generated properly – mirkobrankovic Jan 12 '17 at 14:55
  • Yes, ical is a string. The code to generate the ical can be found over here http://censore.blogspot.in/2017/01/how-to-send-meeting-request-correctly.html – biplav Jan 14 '17 at 13:30
2

This worked for me without using ical-generator

const express    = require('express');
const http       = require('http');
const bodyParser = require('body-parser');
const nodeMailer = require('nodemailer');
const cors  = require('cors');

const app = express();

app.use(cors());

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.post("/v1/sendemail", (req, res) => {

  let transporter = nodeMailer.createTransport({
    host: "smtp.xxx.de",
    secureConnection: true,
    port: 465,
    tls: {
      chipers: "SSLv3"
    },
    auth: {
      user: "xxx@xxx.xxx",
      pass: "xxx"
    }
  });
  let content = 'BEGIN:VCALENDAR\n' +
        'VERSION:2.0\n' +
        'BEGIN:VEVENT\n' +
        'SUMMARY:Summary123\n' +
        'DTSTART;VALUE=DATE:20201030T093000Z\n' +
        'DTEND;VALUE=DATE:20201030T113000Z\n' +
        'LOCATION:Webex \n' +
        'DESCRIPTION:Description123\n' +
        'STATUS:CONFIRMED\n' +
        'SEQUENCE:3\n' +
        'BEGIN:VALARM\n' +
        'TRIGGER:-PT10M\n' +
        'DESCRIPTION:Description123\n' +
        'ACTION:DISPLAY\n' +
        'END:VALARM\n' +
        'END:VEVENT\n' +
        'END:VCALENDAR';

  let mailOptions = {
    from: "from@xxx.xx",
    to: "to@xxx.xx",
    subject: "Subject",
    text: "Test",
    icalEvent: {
        filename: "invitation.ics",
        method: 'request',
        content: content
        }
      };

  transporter.sendMail(mailOptions, function(error, info) {
    if (error) {
      res.status(500).send({
        message: {
          Error: "Could not sent email"
        }
      })
    }
  });
});

const port = process.env.PORT || '3001';
app.set('port', port);

const server = http.createServer(app);
server.listen(port, () => {
  console.log(`API running on localhost:${port}`);
});
Y.kh
  • 163
  • 2
  • 6
0

I think the issue is here: "Content-Type": "text/calendar" If you want to simply add the content as plain text or HTML, where the user can click a link in the email to add it, then you might want to use text or an HTML header. You can simply send the link to the Google calendar for example from where the user can simply click & join the event.

The "Content-Type": "text/calendar" is making the mail sender / client belive that there is an actual file attached or associated with the email.

Update:

The attached ICS file must be attached else the mail client cannot tell it is an event, you just need to use the proper headers. For example:

Content-Type: text/calendar; method=REQUEST
Content-Transfer-Encoding: Base64
Content-Disposition: attachment; filename=iCal-20140610-083450.ics

The attach the .ics file. The mail client will be smart enough to figure it out and give an option to add to the local calendar if clicked.

There are some mail clients, like AirMail that automatically detects any dates in the text, no attachments required, and allows the user to directly integrate the event to the local calendar but this feature is not widely available.

Stefan
  • 1,214
  • 1
  • 9
  • 17
  • I didnt get the part where you mentioned "You can simply send the link to the Google calendar for example from where the user can simply click & join the event." How to do this? @Aichholzer – biplav Jun 20 '14 at 10:21
  • 1
    I guess I was wrongly looking at it. What I meant was to simply send a link to the event which users can click and be taken to the event, on Google Caledar for example, but not what you are looking for I guess. – Stefan Jun 20 '14 at 10:29