【问题标题】:GMail Calendar Invite Not Rendering When Sent via PHP Application通过 PHP 应用程序发送 GMail 日历邀请时未呈现
【发布时间】:2026-01-26 13:45:02
【问题描述】:

我发现了几个关于类似主题的其他主题,但我的特定问题可能更微妙。我有一个 .ics iCalendar 文件,我想用它从我的 Laravel (PHP) 应用程序中发送活动邀请。

这个文件的内容:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:www.example.org
BEGIN:VEVENT
UID:53877c55800b2
DTSTAMP:20140529T182837Z
DTSTART:20140531T120000Z
SEQUENCE:0
TRANSP:OPAQUE
DTEND:20140531T130000Z
SUMMARY:Intro to Web Design
ATTENDEE:example@gmail.com
METHOD:REQUEST
END:VEVENT
END:VCALENDAR

当从我的 PHP 应用程序作为附件发送时,GMail 会识别日历邀请(请参阅日期旁边的小日历图标),但不会像我期望的那样嵌入可操作的日历小部件。

但是,当我手动将该线程转发给自己时,从 GMail 网络用户界面发送,它确实包含小部件。 (“在 Google 日历上查看”链接已失效,转至 http://www.google.com/calendar/undefined,但接下来我会继续处理)

在这里查看对比:

完全相同的 .ics 文件。它在http://icalvalid.cloudapp.net/ 上获得 100。据我所知,这可能与 GMail 的垃圾邮件保护过滤器有关。根据此链接https://developers.google.com/gmail/actions/registering-with-google 的相关但不同的服务,我需要使用 SPF/DKIM 进行身份验证,这似乎很难从我的本地开发环境中摆动。

有什么想法吗?关于如何使这个 GMail Invite 小部件出现的文档似乎非常薄。提前致谢!

编辑:添加原始源代码。

无邀请:

Return-Path: <jon.c.culver@gmail.com>
Received: from [127.0.0.1] (c-24-19-97-115.hsd1.wa.comcast.net. [24.19.97.115])
       by mx.google.com with ESMTPSA id nh8sm30028762pbc.25.2014.05.28.14.58.35
       for <culvejc@gmail.com>
       (version=TLSv1 cipher=RC4-SHA bits=128/128);
       Wed, 28 May 2014 14:58:35 -0700 (PDT)
Sender: Jon Culver <culvejc@gmail.com>
Message-ID: <d77e56242d5eb5b88c6a12c449a457d3@localhost>
Date: Wed, 28 May 2014 21:58:34 +0000
From: Invite <jon.c.culver@gmail.com>
To: culvejc@gmail.com
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="_=_swift_v4_1401314314_7e69457c82922c70669b91e8f6f04aa0_=_"


--_=_swift_v4_1401314314_7e69457c82922c70669b91e8f6f04aa0_=_
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable

You're invited!

Intro to Web Design

--_=_swift_v4_1401314314_7e69457c82922c70669b91e8f6f04aa0_=_
Content-Type: text/calendar; name=invite.ics
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=invite.ics

QkVHSU46VkNBTEVOREFSDQpWRVJTSU9OOjIuMA0KUFJPRElEOnd3dy5zZWF0dGxlZnJlZXNjaG9v
bC5vcmcNCkJFR0lOOlZFVkVOVA0KVUlEOjUzODY1YzBhNDIxZjMNCkRUU1RBTVA6MjAxNDA1MjhU
MjE1ODM0Wg0KRFRTVEFSVDoyMDE0MDUzMVQxMjAwMDBaDQpTRVFVRU5DRTowDQpUUkFOU1A6T1BB
UVVFDQpEVEVORDoyMDE0MDUzMVQxMzAwMDBaDQpTVU1NQVJZOkludHJvIHRvIFdlYiBEZXNpZ24N
CkFUVEVOREVFOmpvbi5jLmN1bHZlckBnbWFpbC5jb20NCk1FVEhPRDpSRVFVRVNUDQpFTkQ6VkVW
RU5UDQpFTkQ6VkNBTEVOREFS

--_=_swift_v4_1401314314_7e69457c82922c70669b91e8f6f04aa0_=_--

正确添加邀请:

MIME-Version: 1.0
Sender: culvejc@gmail.com
Received: by 10.170.223.212 with HTTP; Wed, 28 May 2014 14:58:54 -0700 (PDT)
In-Reply-To: <d77e56242d5eb5b88c6a12c449a457d3@localhost>
References: <d77e56242d5eb5b88c6a12c449a457d3@localhost>
Date: Wed, 28 May 2014 14:58:54 -0700
Delivered-To: culvejc@gmail.com
X-Google-Sender-Auth: 4NYaEgkYuT25UEyzdqbv3cPgdyY
Message-ID: <CABRfHznNc5fndT=L3X-BFDNseJ=gpX0Wwg4a9u96fzRzqRzPPQ@mail.gmail.com>
Subject: Fwd:
From: Jon Culver <jon.c.culver@gmail.com>
To: Jon Culver <culvejc@gmail.com>
Content-Type: multipart/mixed; boundary=001a1139d86a27ac0104fa7ceb83

--001a1139d86a27ac0104fa7ceb83
Content-Type: multipart/alternative; boundary=001a1139d86a27abfe04fa7ceb81

--001a1139d86a27abfe04fa7ceb81
Content-Type: text/plain; charset=UTF-8

---------- Forwarded message ----------
From: Invite <jon.c.culver@gmail.com>
Date: Wed, May 28, 2014 at 2:58 PM
Subject:
To: culvejc@gmail.com


You're invited! Intro to Web Design

--001a1139d86a27abfe04fa7ceb81
Content-Type: text/html; charset=UTF-8

<div dir="ltr"><br><br><div class="gmail_quote">---------- Forwarded message ----------<br>From: <b class="gmail_sendername">Invite</b> <span dir="ltr">&lt;<a href="mailto:jon.c.culver@gmail.com">jon.c.culver@gmail.com</a>&gt;</span><br>
Date: Wed, May 28, 2014 at 2:58 PM<br>Subject: <br>To: <a href="mailto:culvejc@gmail.com">culvejc@gmail.com</a><br><br><br>You&#39;re invited!

Intro to Web Design
</div><br></div>

--001a1139d86a27abfe04fa7ceb81--
--001a1139d86a27ac0104fa7ceb83
Content-Type: text/calendar; charset=US-ASCII; name="invite.ics"
Content-Disposition: attachment; filename="invite.ics"
Content-Transfer-Encoding: base64
X-Attachment-Id: a3995007e372820d_0.1

QkVHSU46VkNBTEVOREFSDQpWRVJTSU9OOjIuMA0KUFJPRElEOnd3dy5zZWF0dGxlZnJlZXNjaG9v
bC5vcmcNCkJFR0lOOlZFVkVOVA0KVUlEOjUzODY1YzBhNDIxZjMNCkRUU1RBTVA6MjAxNDA1MjhU
MjE1ODM0Wg0KRFRTVEFSVDoyMDE0MDUzMVQxMjAwMDBaDQpTRVFVRU5DRTowDQpUUkFOU1A6T1BB
UVVFDQpEVEVORDoyMDE0MDUzMVQxMzAwMDBaDQpTVU1NQVJZOkludHJvIHRvIFdlYiBEZXNpZ24N
CkFUVEVOREVFOmpvbi5jLmN1bHZlckBnbWFpbC5jb20NCk1FVEhPRDpSRVFVRVNUDQpFTkQ6VkVW
RU5UDQpFTkQ6VkNBTEVOREFS

--001a1139d86a27ac0104fa7ceb83--

【问题讨论】:

    标签: php laravel gmail icalendar


    【解决方案1】:

    METHOD:REQUEST 属性属于外部 VCALENDAR 对象而不属于 VEVENT 对象,因此应放在BEGIN:VEVENT 之前。

    您还缺少一个 ORGANIZER 属性。

    【讨论】:

    • 肯定有助于我的 VCALENDAR 的正确性,但仍然没有骰子。不过感谢您的建议!
    • 好吧,那你可能需要去 multipart/alternative (MIME message with multipart/mixed (multipart/alternative (text/plain, text/calendar), text/calendar))
    【解决方案2】:

    在 Laravel 中这样做,兄弟:

        \Mail::send('yourMail/file', $data, function($message) use($data)
        {
            $filename = "invite.ics";
            $meeting_duration = (3600 * 2); // 2 hours
            $meetingstamp = strtotime( $data['start_date'] . " UTC");
            $dtstart = gmdate('Ymd\THis\Z', $meetingstamp);
            $dtend =  gmdate('Ymd\THis\Z', $meetingstamp + $meeting_duration);
            $todaystamp = gmdate('Ymd\THis\Z');
            $uid = date('Ymd').'T'.date('His').'-'.rand().'@yourdomain.com';
            $description = strip_tags($data['texto']);
            $location = "Telefone ou vídeo conferência";
            $titulo_invite = "Your meeting title";
            $organizer = "CN=Organizer name:email@YourOrganizer.com";
    
            // ICS
            $mail[0]  = "BEGIN:VCALENDAR";
            $mail[1] = "PRODID:-//Google Inc//Google Calendar 70.9054//EN";
            $mail[2] = "VERSION:2.0";
            $mail[3] = "CALSCALE:GREGORIAN";
            $mail[4] = "METHOD:REQUEST";
            $mail[5] = "BEGIN:VEVENT";
            $mail[6] = "DTSTART;TZID=America/Sao_Paulo:" . $dtstart;
            $mail[7] = "DTEND;TZID=America/Sao_Paulo:" . $dtend;
            $mail[8] = "DTSTAMP;TZID=America/Sao_Paulo:" . $todaystamp;
            $mail[9] = "UID:" . $uid;
            $mail[10] = "ORGANIZER;" . $organizer;
            $mail[11] = "CREATED:" . $todaystamp;
            $mail[12] = "DESCRIPTION:" . $description;
            $mail[13] = "LAST-MODIFIED:" . $todaystamp;
            $mail[14] = "LOCATION:" . $location;
            $mail[15] = "SEQUENCE:0";
            $mail[16] = "STATUS:CONFIRMED";
            $mail[17] = "SUMMARY:" . $titulo_invite;
            $mail[18] = "TRANSP:OPAQUE";
            $mail[19] = "END:VEVENT";
            $mail[20] = "END:VCALENDAR";
    
            $mail = implode("\r\n", $mail);
            header("text/calendar");
            file_put_contents($filename, $mail);
    
            $message->subject($data['titulo']);
            $message->to($data['destinatario']);
            $message->attach($filename, array('mime' => "text/calendar"));
        });
    

    【讨论】:

      最近更新 更多