python-o365 icon indicating copy to clipboard operation
python-o365 copied to clipboard

ICS Attachment Does Not Display as Calendar Invitation in Outlook

Open tomy137 opened this issue 11 months ago • 3 comments

Hello,

I am encountering an issue where an ICS file attached to an email does not appear as a calendar invitation in Outlook when the email is sent using the O365 Python library.

Problem Details:

  • SMTP Works: When sending the same ICS file via an SMTP client, the email is correctly interpreted as a calendar invitation in Outlook.
  • O365 Fails: When sending the same ICS file using the O365 Python library, the ICS file is treated as a regular attachment, and Outlook does not display it as a calendar invitation.

Additional Information:

  • The ICS file itself is not faulty, as it works as expected when sent through SMTP.
  • I observed differences in the email headers and formatting between emails sent via SMTP and those sent using O365. These differences might be causing the issue.

Steps to Reproduce:

  1. Obtain a Well-Formatted ICS File: Use an ICS file that is known to display correctly as a calendar invitation in Outlook.
  2. Send via SMTP: Use the following code to send the ICS file via SMTP:
import smtplib
from email.mime.multipart import MIMEMultipart
ical = """
# ** Well-Formatted ICS File **
 """
msg = MIMEMultipart()
msg.attach( MIMEText(ical,'calendar;method=REQUEST') )
# add to, from etc.
mailserver = smtplib.SMTP(****,587)
# login etc.
mailserver.sendmail(fromaddrs,toaddrs,msg.as_string())
  1. Verify Invitation in Outlook: The email arrives in the recipient's inbox, and the ICS file is interpreted as a calendar invitation. image
  2. Send via O365: Use the following code to send the same ICS file via the O365 Python library:
mailbox = account.mailbox()
message = mailbox.new_message()
message.to.add('***')
message.sender.address = "***"
message.sender.name = '****'
message.subject = '****'
message.body = "*****"
message.attachments.add([(io.BytesIO(OLD_ICS.encode('utf-8')), "invite.ics")])
#I've tried with and without this other lines and different combinaisons : 
message.attachments[0].contentType = "text/calendar; method=REQUEST; charset=UTF-8"
message.attachments[0].contentId = 'cid:calendar-invite'
message.attachments[0].is_inline = True
message.send()
  1. Observe the Result: The email arrives, but the ICS file is treated as a plain attachment, and the calendar invitation is not displayed in Outlook. image

Additional Observations:

I compared the eml files generated by both methods (SMTP vs O365) and noticed the following differences:

SMTP Email:

  • Content-Type: multipart/mixed;
  • Attachments:
    • Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: base64
    • Content-Type: text/calendar; method="REQUEST"; charset="utf-8" Content-Transfer-Encoding: base64

O365 Email:

  • Content-Type: multipart/related; type="multipart/alternative"
  • Attachments:
    • Content-Type: multipart/alternative;
    • Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable
    • Content-Type: text/calendar; name="invite.ics" Content-Description: invite.ics Content-Disposition: inline; filename="invite.ics"; size=3257; creation-date="Fri, 20 Dec 2024 13:54:06 GMT"; modification-date="Fri, 20 Dec 2024 13:54:06 GMT" Content-Transfer-Encoding: base64

I don't really know what to deduce from this and whether it's relevant or not...

Have you ever managed to do this?

tomy137 avatar Dec 20 '24 14:12 tomy137

I've never tried...

Can you try add a link to the ics in the body of the message?

Add this: <a href='cid:invite.ics'>here</a>

alejcas avatar Jan 24 '25 11:01 alejcas

I see other people reporting this issue, but with no resolution :-(

RogerSelwyn avatar Apr 18 '25 17:04 RogerSelwyn

I see other people reporting this issue, but with no resolution :-(

Yeah I don't know how to solve this, but I'll try it myself and see if I can find a solution

alejcas avatar Apr 22 '25 08:04 alejcas

O365 Mail lacks method and charset parameters in Content-Type header. I see they're being specified in OP's code, but I'm not familiar with this library so I can't advise further. There could be another way to add them.

Outlook should display mail itself as invite if it sees method=REQUEST in attachment's Content-Type.

Not sure why section 8.1 specifies charset as optional though.

While not a problem in OP's case, I noticed Outlook handles some other aspects of ICS badly. For example opening ICS files themselves using method PUBLISH are still seen as invites to be accepted if ORGANIZER is specified (which RFC 5546 specification defines it should be). From my understanding, that behavior should be restricted for REQUESTs that are dealing with kind of ICS requiring responses from invited people. PUBLISHed events can't be updated with another PUBLISH, it just creates a duplicate, instead of looking up the old event by UID and updating accordingly if new ICS' SEQUENCE is greater, which goes against behavior described in section 3.2.1 of RFC 5546.

UCyborg avatar Sep 02 '25 22:09 UCyborg