当我将 "METHOD: REQUEST" 添加到 iCalendar 时,Gmail 停止将其识别为事件
When I add "METHOD: REQUEST" to iCalendar, Gmail stops recognizing as event
我正在使用 iCalendar 为 Gmail 用户安排活动。但是,我希望能够发送更新,if/when 事件发生变化。我读到必须使用 METHOD:REQUEST 才能允许更新。
但是,当我将 METHOD:REQUEST 添加到我的 ics 文件时,Gmail 停止将其识别为日历邀请。
这是工作示例 WITHOUT "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
以上完美运行; Gmail 弹出一个按钮,询问我是否要接受。
这是不工作的例子 WITH "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
这会在 google 中生成一封空白电子邮件,并附有 .ics 文件。它不会出现在日历或其他任何地方。
这两个 iCalendar 文件在其他方面完全相同。但出于某种原因,添加 METHOD:REQUEST 会破坏 ics 文件/google 的读取能力。
为什么??
好的 - 经过数小时阅读 RFC5546、Whosebug 和许多其他博客,我终于有了答案。
范围:
- 发送日历邀请到 Gmail / Outlook / Privateemail(namecheap 的电子邮件客户端)
- 电子邮件客户端自动识别 .ics 文件并生成“接受”模板
- 在客户日历中自动显示为“暂定”的事件
- 发送自动移动客户端日历事件的事件修订
有两个基本原则对完成这项工作至关重要:
.ics 文件的 内容 必须与 Gmail / Outlook 社区的 .ics 文件非常匹配,这包括参数 和参数的顺序。
.ics 文件附加到电子邮件传输的方式很奇怪但很关键:(a) .ics 文件必须变成 'base64',以及 (b) headers的文件需要给一个类型:'text/calendar;method=REQUEST;name="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`
请注意:以上顺序非常重要!并且文本周围不能有死的 space,即使前后多出一个 space 也会扰乱电子邮件客户端。此外,这是一个可重复使用的动态 iCal 事件模板,只要我保留 event._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();
请注意:附件类型对于 Outlook 识别事件至关重要。
虽然我确信还有其他/更好的方法可以与这些服务集成,但我发现上述步骤可以让我完成我的范围。
我正在使用 iCalendar 为 Gmail 用户安排活动。但是,我希望能够发送更新,if/when 事件发生变化。我读到必须使用 METHOD:REQUEST 才能允许更新。
但是,当我将 METHOD:REQUEST 添加到我的 ics 文件时,Gmail 停止将其识别为日历邀请。
这是工作示例 WITHOUT "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
以上完美运行; Gmail 弹出一个按钮,询问我是否要接受。
这是不工作的例子 WITH "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
这会在 google 中生成一封空白电子邮件,并附有 .ics 文件。它不会出现在日历或其他任何地方。
这两个 iCalendar 文件在其他方面完全相同。但出于某种原因,添加 METHOD:REQUEST 会破坏 ics 文件/google 的读取能力。
为什么??
好的 - 经过数小时阅读 RFC5546、Whosebug 和许多其他博客,我终于有了答案。
范围:
- 发送日历邀请到 Gmail / Outlook / Privateemail(namecheap 的电子邮件客户端)
- 电子邮件客户端自动识别 .ics 文件并生成“接受”模板
- 在客户日历中自动显示为“暂定”的事件
- 发送自动移动客户端日历事件的事件修订
有两个基本原则对完成这项工作至关重要:
.ics 文件的 内容 必须与 Gmail / Outlook 社区的 .ics 文件非常匹配,这包括参数 和参数的顺序。
.ics 文件附加到电子邮件传输的方式很奇怪但很关键:(a) .ics 文件必须变成 'base64',以及 (b) headers的文件需要给一个类型:'text/calendar;method=REQUEST;name="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`
请注意:以上顺序非常重要!并且文本周围不能有死的 space,即使前后多出一个 space 也会扰乱电子邮件客户端。此外,这是一个可重复使用的动态 iCal 事件模板,只要我保留 event._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();
请注意:附件类型对于 Outlook 识别事件至关重要。
虽然我确信还有其他/更好的方法可以与这些服务集成,但我发现上述步骤可以让我完成我的范围。