所以我的红宝石项目中有Icalendar gem。我正在尝试在邀请上获取是/否/也许的回复按钮,但每当发送时,我只会收到"添加到日历"。
想知道我还需要什么:
def make_ical_appointment(start_time, end_time, uid, email_one, email_two)
ical = Icalendar::Calendar.new
ical.timezone.tzid = "UTC"
e = Icalendar::Event.new
e.dtstart = start_time
e.dtend = end_time
e.organizer = %W(mailto:#{email_one} mailto#{email_two})
e.uid = uid
ical.add_event(e)
ical.publish
mail.attachments['appointment.ics'] = { mime_type: 'application/ics', content: ical.to_ical }
end
我已经读到人们需要将其设置为METHOD:REQUEST,但我不确定在哪里做。我也读过您需要设置与会者,但似乎只有在有闹钟时才能设置与会者?
只是想让它看起来像一个普通的邀请。
做两件事来解决问题:
阅读 RFC-2445,它定义了 iCal 格式。看起来讨论 ATTENDEE 属性的第 4.8.4.1 节和讨论 RSVP 参数的第 4.2.17 节将特别令人感兴趣。
查看您收到的电子邮件和.ics文件,这些文件在各种电子邮件客户端中正确显示。
我在上面的评论中链接到的页面有三个提示。
第一个提示
我尝试添加此属性:
calendar.custom_property("METHOD", "REQUEST")
.[1]
从文档中我认为这应该是append_custom_property
.
打开某人从Google日历发送给我的邀请,我找到了这一行:
METHOD:REQUEST
所以这似乎是合法的。
第二个提示
我猜您需要添加一个
ATTENDEE
属性,其中包含RSVP=TRUE
和电子邮件设置为Outlook或Yahoo链接到其用户的同一电子邮件。[2]
在同一邀请中,我发现:
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=
TRUE;CN=Firstname Lastname;X-NUM-GUESTS=0:mailto:jordan@example.com
我没有阅读整个 RFC,但我认为它是这样分解的:
-
ATTENDEE
是属性名称。 - 第一个
;
和第一个:
之间的所有内容都是参数。它们中的每一个都记录在 RFC 中,我不知道它们是否都是必需的,但我们可以看到RSVP=TRUE
参数。 - 第一个
:
之后的一切,即mailto:jordan@example.com
是值
查看append_custom_property
的来源,我们看到它检查value
是否是Icalendar::Value
对象,如果不是,它会创建一个带有 Icalendar::Values::Text.new(value)
.由于除了值之外,我们还有参数,让我们在这里查看该构造函数。我们看到它可以接受第二个参数,这是一个params
哈希。
还没有测试它,但这向我表明,您可以使用如下所示的代码构建像上面这样的行†:
attendee_params = { "CUTYPE" => "INDIVIDUAL",
"ROLE" => "REQ-PARTICIPANT",
"PARTSTAT" => "NEEDS-ACTION",
"RSVP" => "TRUE",
"CN" => "Firstname Lastname",
"X-NUM-GUESTS" => "0" }
attendee_value = Icalendar::Values::Text.new("MAILTO:jordan@example.com", attendee_params)
ical.append_custom_property("ATTENDEE", attendee_value)
编辑:在Icalendar 2.x中,看起来你也可以做:
attendee_value = Icalendar::Values::CalAddress.new("MAILTO:jordan@example.com", attendee_params)
ical.append_attendee(attendee_value)
CalAddress 类是 Uri 的一个子类,它只是通过 URI.parse
运行给定的值,append_attendee
似乎是append_custom_property("ATTENDEE", ...)
的快捷方式。
我不确定所有这些参数是否真的是必需的,但您可以通过阅读 RFC 了解它们中的每一个是什么。
第三个提示
为了使它在所有邮件客户端中工作,我必须做的是将其作为多部分/替代消息发送,并将 ical 作为替代视图而不是附件。[3]
果然,在Gmail中做"显示原件"时,我看到我收到的邀请电子邮件是多部分电子邮件,其中text/calendar
部分:
--047d7b0721581f7baa050a6c3dc0
Content-Type: text/calendar; charset=UTF-8; method=REQUEST
Content-Transfer-Encoding: 7bit
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
...
。和application/ics
附件部分:
--047d7b0721581f7bae050a6c3dc2
Content-Type: application/ics; name="invite.ics"
Content-Disposition: attachment; filename="invite.ics"
Content-Transfer-Encoding: base64
QkVHSU46VkNBTEVOREFSDQpQUk9ESUQ6LS8vR29vZ2xlIEluYy8vR29vZ2xlIENhbGVuZGFyIDcw
...
你已经得到了第二部分,感谢mail.attachments
.对于第一部分,您只需使用正确的content_type
创建一个新Mail::Part
并将其添加到 mail.parts
,如下所示:
ical_part = Mail::Part.new do
content_type "text/calendar; charset=UTF-8; method=REQUEST"
body ical.to_ical
end
mail.add_part(ical_part)
这就是我所拥有的一切。同样,我没有测试过这些,我不确定它是否会解决您的问题,但希望它能为您提供一些想法。
我认为,最重要的是查看带有邀请的电子邮件的来源(如果您使用Gmail,则"显示原始"位于"回复"按钮旁边的下拉菜单下(,并查看它们是如何构建的,同样查看.ics附件,看看它们是否与您生成的内容匹配。
祝你好运!
†从 Icalendar 将参数哈希转换为 iCal 参数的方式来看,我认为您也可以使用符号键,如下所示:
attendee_params = { cutype: "INDIVIDUAL",
role: "REQ-PARTICIPANT",
partstat: "NEEDS-ACTION",
rsvp: "TRUE",
cn: "Firstname Lastname",
x_num_guests: "0" }