当我将“方法:请求”添加到 iCalendar 时,Gmail 停止识别为活动

Izz*_*zzi 6 javascript icalendar outlook gmail rfc

我正在使用 iCalendar 为 Gmail 用户安排活动。但是,我希望能够在事件发生变化时发送更新。我读到我必须使用METHOD:REQUEST才能允许更新。

但是,当我将 METHOD:REQUEST 添加到我的 ics 文件中时,Gmail 不再将其识别为日历邀请。

这是没有“METHOD:REQUEST”的工作示例

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Cratic//Cratic Huddle//EN
NAME:Cratic Huddle
X-WR-CALNAME:Cratic Huddle
TIMEZONE-ID:Europe/Berlin
X-WR-TIMEZONE:Europe/Berlin
BEGIN:VEVENT
UID:60212c8395841f2cd057864f@cratic.ai
SEQUENCE:0
DTSTAMP:20210208T130601Z
DTSTART:20210219T133059Z
DTEND:20210219T140059Z
SUMMARY:Cratic Huddle
DESCRIPTION:This is the information
ORGANIZER;CN="Izzi":mailto:firstname.lastname@gmail.com
ATTENDEE;ROLE=REQ-PARTICIPANT:MAILTO:firstname.lastname@gmail.com
BEGIN:VALARM
ACTION:DISPLAY
TRIGGER:-PT15M
DESCRIPTION:Cratic Huddle
END:VALARM
BEGIN:VALARM
ACTION:AUDIO
TRIGGER:-PT15M
ATTACH;VALUE=URI:Basso
END:VALARM
URL;VALUE=URI:cratic.ai
END:VEVENT
END:VCALENDAR
Run Code Online (Sandbox Code Playgroud)

以上效果完美;Gmail 会弹出一个按钮,询问我是否接受。

这是“METHOD:REQUEST”不起作用的示例

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Cratic//Cratic Huddle//EN
METHOD:REQUEST
NAME:Cratic Huddle
X-WR-CALNAME:Cratic Huddle
TIMEZONE-ID:Europe/Berlin
X-WR-TIMEZONE:Europe/Berlin
BEGIN:VEVENT
UID:60212c8395841f2cd057864f@cratic.ai
SEQUENCE:0
DTSTAMP:20210208T125937Z
DTSTART:20210219T133059Z
DTEND:20210219T140059Z
SUMMARY:Cratic Huddle
DESCRIPTION:This is the information
ORGANIZER;CN="Izzi":mailto:firstname.lastname@gmail.com
ATTENDEE;ROLE=REQ-PARTICIPANT:MAILTO:firstname.lastname@gmail.com
BEGIN:VALARM
ACTION:DISPLAY
TRIGGER:-PT15M
DESCRIPTION:Cratic Huddle
END:VALARM
BEGIN:VALARM
ACTION:AUDIO
TRIGGER:-PT15M
ATTACH;VALUE=URI:Basso
END:VALARM
URL;VALUE=URI:cratic.ai
END:VEVENT
END:VCALENDAR
Run Code Online (Sandbox Code Playgroud)

这会在 google 中生成一封空白电子邮件,并附有 .ics 文件。它不会出现在日历或其他任何地方。

这两个 iCalendar 文件在其他方面都是相同的。但由于某种原因,添加 METHOD:REQUEST 会杀死 ics 文件/谷歌读取它的能力。

为什么??

Izz*_*zzi 15

好的 - 经过几个小时的阅读 RFC5546、Stackoverflow 和许多其他博客后,我终于有了答案。

范围:

  1. 发送日历邀请到 Gmail / Outlook / Privateemail(namecheap 的电子邮件客户端)
  2. 电子邮件客户端自动识别 .ics 文件并生成“接受”模板
  3. 事件自动在客户日历中显示为“暂定”
  4. 发送自动移动客户日历事件的事件修订

有两个基本原则对于这项工作至关重要:

  1. .ics 文件的内容必须与 Gmail/Outlook 社区的 .ics 文件非常匹配,其中包括参数和参数的顺序

  2. .ics 文件附加到电子邮件传输的方式很奇怪但很关键:(a) .ics 文件必须转换为“base64”,并且 (b) 文件的标头需要给出类型:“text/”日历;方法=请求;名称=“file.ics”'

下面我将给出每个示例,我希望这可以节省其他人在此过程中的时间。

.ics 内容示例:

let iCal = 

`BEGIN:VCALENDAR
PRODID:-//Cratic//_Scheduler//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:${DTStart}
DTEND:${DTEnd}
DTSTAMP:${DTStamp}
ORGANIZER;CN=name:mailto:name@gmail.com
UID:${event._id}@url.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=name@outlook.com;X-NUM-GUESTS=0:mailto:name@outlook.com
CREATED:${DTStamp}
DESCRIPTION:${event.body}
LAST-MODIFIED:${DTStamp}
LOCATION:${location}
SEQUENCE:${sequence}
STATUS:CONFIRMED
SUMMARY:${event.title}
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR`
Run Code Online (Sandbox Code Playgroud)

请注意:以上顺序非常重要!并且文本周围不能有死角,即使前后有一个额外的空格也会干扰电子邮件客户端。另外,这是一个可重用的动态 iCal 事件模板,只要我保留事件的记录。_id,我就可以使用该 _id 将修订发送给我的所有客户。

将 .ics 附加到电子邮件客户端:

// convert the invite to be base64 for attachment
const buf = Buffer.from(iCal.toString(), 'utf-8');
const base64Cal = buf.toString('base64');

// build the email
const sendEmail = async () => {
    const res = await client.transmissions.send({
        recipients: [{ address: 'name@outlook.com' }],
        content: {
          from: 'name@sparkmail.com',
          subject: req.body.a.title,
          text: req.body.a.body,
          attachments: [
            {
              name: 'invite.ics',
              type: 'text/calendar;method=REQUEST;name=\"invite.ics\"',
              data: base64Cal,
            },
          ],
        },
        options: { sandbox: false },
    });
}

// send the email
sendEmail();
Run Code Online (Sandbox Code Playgroud)

请注意:附件类型对于 Outlook 识别事件至关重要。

尽管我确信还有其他/更好的方法可以与这些服务集成,但我发现上述步骤可以让我完成我的范围。