首页 文章

日历邀请包含图像的HTML正文

提问于
浏览
1

我无法将图像显示为邮件消息的HTML正文的一部分,该邮件消息还包含日历附件(iCal) .

我尝试做的是:发送一个由Outlook识别的日历邀请,还包含一个HTML正文(也显示在Outlook 2013中) . 该HTML应该内嵌显示页眉和页脚图像 .

我的代码在gmail中查看时有效,但它不会在Outlook中显示图像 - 而是在我希望图像实际显示的正文位置显示“header.jpg”和“footer.jpg” .

我已尝试对此代码库进行了大量修改 - 要么忽略日历邀请部分(然后图像工作),要么日历邀请部分工作,图像不会显示,而是替换为“header.jpg”和双击时打开的“screen.jpg”文件 . 我可以绕过这个并在Outlook中内嵌显示图像吗?

这是我正在使用的代码(剪掉不相关的东西):

var header = new LinkedResource("header.jpg", MediaTypeNames.Image.Jpeg);
header.ContentId = Guid.NewGuid().ToString();
header.TransferEncoding = TransferEncoding.Base64;
header.ContentType = new ContentType("image/jpg");
header.ContentType.Name = "header.jpg";
header.ContentLink = new Uri(string.Format("cid:{0}", header.ContentId));

var screen = new LinkedResource("screen.jpg", MediaTypeNames.Image.Jpeg);
screen.ContentId = Guid.NewGuid().ToString();
screen.TransferEncoding = TransferEncoding.Base64;
screen.ContentType = new ContentType("image/jpg");
screen.ContentType.Name = "screen.jpg";
screen.ContentLink = new Uri(string.Format("cid:{0}", screen.ContentId));


var sb = new System.Text.StringBuilder();

var dtStart = appointmentStart;
var dtEnd = appointmentEnd;

var htmlcontent = string.Format("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">" +
    "<HTML><HEAD><META http-equiv=Content-Type content=\"multipart/alternative; charset=iso-8859-1\"></HEAD>" +
    "<BODY>" +
    "<img src=\"cid:" + header.ContentId + "\"/>" +
    "<div><strong>The bold works fine, but the header and footer don't work! /strong></div>" +
   "
" + "<div><img src=\"cid:" + screen.ContentId + "\"/></div>" + "</BODY></HTML>" ); var plaincontent = String.Format("snip snip"); var av1 = AlternateView.CreateAlternateViewFromString(htmlcontent, new ContentType("text/html");); av1.LinkedResources.Add(header); av1.LinkedResources.Add(screen); sb.AppendLine("BEGIN:VCALENDAR"); sb.AppendLine("VERSION:2.0"); sb.AppendLine("METHOD:REQUEST"); sb.AppendLine("BEGIN:VEVENT"); sb.AppendLine(request.ContactEmail); sb.AppendLine("CLASS:PUBLIC"); sb.AppendLine(string.Format("CREATED:{0:yyyyMMddTHHmmss}", DateTime.Now)); sb.AppendLine("DESCRIPTION:" + plaincontent); sb.AppendLine("X-ALT-DESC;FMTTYPE=text/html:" + htmlcontent); sb.AppendLine(string.Format("DTSTART:{0:yyyyMMddTHHmmssZ}", dtStart.ToUniversalTime())); sb.AppendLine(string.Format("DTEND:{0:yyyyMMddTHHmmssZ}", dtEnd.ToUniversalTime())); sb.AppendLine(string.Format("DTSTAMP:{0:yyyyMMddTHHmmssZ}", DateTime.Now.ToUniversalTime())); sb.AppendLine("ORGANIZER;CN=\"TheOrganizer\":mailto:" + "TheOrganizer@foobar.com"); sb.AppendLine("SEQUENCE:0"); sb.AppendLine("UID:" + request.EmailNotificationUniqueId); sb.AppendLine("LOCATION:" + request.Location + " : " + request.LocationInformation); sb.AppendLine("SUMMARY;LANGUAGE=en-us:" + "removed"); sb.AppendLine("BEGIN:VALARM"); sb.AppendLine("TRIGGER:-PT1440M"); sb.AppendLine("ACTION:DISPLAY"); sb.AppendLine("DESCRIPTION:Reminder"); sb.AppendLine("END:VALARM"); sb.AppendLine("END:VEVENT"); sb.AppendLine("END:VCALENDAR"); var icsView = AlternateView.CreateAlternateViewFromString(sb.ToString(), new ContentType("text/calendar")); var message = new MailMessage(); message.AlternateViews.Add(body); message.AlternateViews.Add(icsView); return message;

有什么根本错误的吗?这看起来应该非常简单明了 . 我喜欢 . 替代视图正文中的图像.ics附件 . HTML正文工作正常( **** 显示粗体)但是嵌入的图像不会显示 .

我尝试使用base64手动编码图像,但根本没用 . 我在htmlContent var中尝试使用和不使用HTML标头标签,这也没有任何区别 .

这应该不是那么困难 - 我错过了什么?

编辑:这是谷歌的消息来源 . 这在谷歌浏览器窗口中工作正常(显示正常 . )不幸的是在Outlook中消息不起作用...也许交换服务器正在抑制内部消息的图像?这甚至是一件事吗?

Delivered-To: snip@gmail.com
Received: by 10.182.167.74 with SMTP id zm10csp2847908obb;
        Fri, 7 Oct 2016 15:42:14 -0700 (PDT)
X-Received: by 10.37.171.105 with SMTP id u96mr17483671ybi.63.1475880134797;
        Fri, 07 Oct 2016 15:42:14 -0700 (PDT)
Return-Path: <snip@snip.com>
Received: from msg12.snip.com (msg12.snip.com. [192.195.66.28])
        by mx.google.com with ESMTPS id q11si2985157ywc.340.2016.10.07.15.42.14
        for <snip@gmail.com>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Fri, 07 Oct 2016 15:42:14 -0700 (PDT)
Received-SPF: pass (google.com: domain of snip@snip.com designates 192.195.66.28 as permitted sender) client-ip=192.195.66.28;
Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of snip@snip.com designates 192.195.66.28 as permitted sender) smtp.mailfrom=snip@snip.com
Received: from int11.snip.pvt (int11.snip.pvt [153.6.62.222]) by msg12.snip.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.2.2) with ESMTP id u97MgC5a022486 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for <snip@gmail.com>; Fri, 7 Oct 2016 22:42:12 GMT
Received: from snip.com (snip.com [snip]) by int11.snip.pvt (Sentrion-MTA-4.3.1/Sentrion-MTA-4.2.2) with ESMTP id u97MgBAv016400 for <snip@gmail.com>; Fri, 7 Oct 2016 22:42:12 GMT
Received: from snip.com with Microsoft SMTPSVC(7.5.7601.17514);
     Fri, 7 Oct 2016 18:42:12 -0400
MIME-Version: 1.0
From: snip <snip@snip.com>
To: snip@gmail.com
Date: 7 Oct 2016 18:42:12 -0400
Content-Type: multipart/alternative; boundary=--boundary_0_8278962b-71cf-4ca1-9a64-5fb9629f2042
Message-ID: <5U9T3T00000050@snip.com>
X-OriginalArrivalTime: 07 Oct 2016 22:42:12.0895 (UTC) FILETIME=[0BC44AF0:01D220EC]
X-Flow-Control: Sendmail Flow Controller v2.2.5 int11.snip.pvt u97MgBAv016400
X-Flow-Control-Info: class=Default rcpts=1 size=37636

----boundary_0_8278962b-71cf-4ca1-9a64-5fb9629f2042
Content-Type: multipart/related; boundary=--boundary_1_306bb8e7-fb92-4eab-bf5c-b7393cf499ac; type="text/html"

----boundary_1_306bb8e7-fb92-4eab-bf5c-b7393cf499ac
Content-Type: text/html
Content-Transfer-Encoding: quoted-printable

<img src=3D"cid:443ba735-6376-45a1-a5af-6c679321baa2"/><div><strong>The bol=
d works fine, but the header and footer don't work!</strong></div>
<di= v><img src=3D"cid:145c43b0-da9e-40c4-b149-3a149fbc4503"/></div> ----boundary_1_306bb8e7-fb92-4eab-bf5c-b7393cf499ac Content-Type: image/jpeg Content-Transfer-Encoding: base64 Content-ID: <443ba735-6376-45a1-a5af-6c679321baa2> ----boundary_1_306bb8e7-fb92-4eab-bf5c-b7393cf499ac Content-Type: image/jpeg Content-Transfer-Encoding: base64 Content-ID: <145c43b0-da9e-40c4-b149-3a149fbc4503> ----boundary_1_306bb8e7-fb92-4eab-bf5c-b7393cf499ac-- ----boundary_0_8278962b-71cf-4ca1-9a64-5fb9629f2042 Content-Type: text/calendar Content-Transfer-Encoding: base64 QkVHSU46VkNBTEVOREFSDQpWRVJTSU9OOjIuMA0KTUVUSE9EOlJFUVVFU1QNCkJFR0lOOlZFVkVO VA0KSmRyYWhsQGdtYWlsLmNvbQ0KQ0xBU1M6UFVCTElDDQpDUkVBVEVEOjIwMTYxMDA3VDE4NDIx MQ0KREVTQ1JJUFRJT046DQpYLUFMVC1ERVNDO0ZNVFRZUEU9dGV4dC9odG1sOjxpbWcgc3JjPSJj aWQ6NDQzYmE3MzUtNjM3Ni00NWExLWE1YWYtNmM2NzkzMjFiYWEyIi8+PGRpdj48c3Ryb25nPlRo ZSBib2xkIHdvcmtzIGZpbmUsIGJ1dCB0aGUgaGVhZGVyIGFuZCBmb290ZXIgZG9uJ3Qgd29yayE8 L3N0cm9uZz48L2Rpdj48YnIgLz48ZGl2PjxpbWcgc3JjPSJjaWQ6MTQ1YzQzYjAtZGE5ZS00MGM0 LWIxNDktM2ExNDlmYmM0NTAzIi8+PC9kaXY+DQpEVFNUQVJUOjIwMTYxMDI0VDE0MDAwMFoNCkRU RU5EOjIwMTYxMDI0VDE4MDAwMFoNCkRUU1RBTVA6MjAxNjEwMDdUMjI0MjExWg0KT1JHQU5JWkVS O0NOPSJEaXNuZXkgUmVmcmVzaCBUZWFtIjptYWlsdG86RGlzbmV5LlJlZnJlc2guVGVhbUBkaXNu ZXkuY29tDQpTRVFVRU5DRTowDQpVSUQ6NGE5YjczNWQtOTQwYS00Mzk0LTkzODItMzMyMmQxNDg0 MTBiDQpMT0NBVElPTjpPcmxhbmRvIDogDQpTVU1NQVJZO0xBTkdVQUdFPWVuLXVzOkNvbXB1dGVy IFJlZnJlc2ggQXBwb2ludG1lbnQNCkJFR0lOOlZBTEFSTQ0KVFJJR0dFUjotUFQxNDQwTQ0KQUNU SU9OOkRJU1BMQVkNCkRFU0NSSVBUSU9OOlJlbWluZGVyDQpFTkQ6VkFMQVJNDQpFTkQ6VkVWRU5U DQpFTkQ6VkNBTEVOREFSDQo= ----boundary_0_8278962b-71cf-4ca1-9a64-5fb9629f2042--

1 回答

  • 0

    Try using the below code which contains a method to attach inline images along with email invitations and normal attachments just adjust the code according to your need

    private String senderAddress = "YOUR EMAIL ADDRESS";
        private final String password = "YOUR EMAIL PASSWORD";
        public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd'T'HHmm'00'");
        public static SimpleDateFormat dateParser = new SimpleDateFormat("dd-MM-yyyy HH:mm");
        public static SimpleDateFormat dateFormater = new SimpleDateFormat("dd-MM-yyyy");
    
        public String getSenderAddress() {
            return senderAddress;
        }
    
        public String getPassword() {
            return password;
        }
    
        public Session getMailSession() {
    
            Properties props = new Properties();
            props.put("mail.smtp.host", "smtp.gmail.com");
            props.put("mail.smtp.port", "587");
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.starttls.enable", "true");
    
            return Session.getInstance(props, new javax.mail.Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(getSenderAddress(), getPassword());
                }
            });
        }
    
        public String newSend(Invitation invitation, String methodType)  {
    
            String UID = null;
    
            // register the text/calendar mime type
            MimetypesFileTypeMap mimetypes = (MimetypesFileTypeMap) MimetypesFileTypeMap.getDefaultFileTypeMap();
            mimetypes.addMimeTypes("text/calendar ics ICS");
    
            // register the handling of text/calendar mime type
            MailcapCommandMap mailcap = (MailcapCommandMap) MailcapCommandMap.getDefaultCommandMap();
            mailcap.addMailcap("text/calendar;; x-java-content-handler=com.sun.mail.handlers.text_plain");
    
            MimeMessage message = new MimeMessage(getMailSession());
            try {
                message.setFrom(new InternetAddress(senderAddress));
                message.setSubject(invitation.getSubject());
                message.addRecipient(Message.RecipientType.TO, new InternetAddress(invitation.getTo()));
    
                Multipart multipart = new MimeMultipart("mixed");
                invitation.setDescription(getHtmlWithEncodedImages(multipart,invitation));
    
                Multipart mpMixedAlternative = newChild(multipart, "alternative");
    
                // html part
                BodyPart messageBodyPart = buildHtmlTextPart(invitation);
                mpMixedAlternative.addBodyPart(messageBodyPart);
    
                // Add part two, the calendar
                BodyPart calendarPart = buildCalendarPart(invitation, methodType);
                calendarPart.setDisposition(BodyPart.INLINE);
                mpMixedAlternative.addBodyPart(calendarPart);
    
                addAttachment(multipart);
                // Put the multipart in message
                message.setContent(multipart);
    
                // send the message
                Transport transport = getMailSession().getTransport("smtp");
                transport.connect();
    
    
                transport.sendMessage(message, message.getAllRecipients());
    
                transport.close();
                UID = invitation.getTo() + "" + invitation.getStartdate().toString() + "" + invitation.getStarttime();
            } catch (Exception e) {
                //TODO logger log exception
            }
            return UID;
        }
    
        private void addAttachment(Multipart multipart) {
    
            MimeBodyPart mbpAttachment = new MimeBodyPart();
    
            File file=new File("C:/users/ishan.juneja/Desktop/temp.txt");
            DataSource datasource=new FileDataSource(file);
            try {
                mbpAttachment.setDataHandler(new DataHandler(datasource));
                mbpAttachment.setDisposition(BodyPart.ATTACHMENT);
    
                mbpAttachment.setFileName("temp.txt");
                multipart.addBodyPart(mbpAttachment);
            } catch (MessagingException e) {
                // TODO logger log exception
            }
    
    
        }
    
        public String uploadImage(MultipartFile file){
    
            byte[] bytes;
            try {
                String path = System.getProperty("catalina.home");
                File dir = new File(path+"/tmpFiles");
                if(!dir.isDirectory()){
                    dir.mkdir();
                    }
                bytes = file.getBytes();
                File serverfile = new File(dir.getAbsolutePath()+"/"+file.getName()+Math.random()+".png");
                BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(serverfile));
                stream.write(bytes);
                stream.close();
    
                System.out.println("file uploaded "+serverfile.getAbsolutePath());
    
                String hostname="Unknown";
                try {
                    hostname = InetAddress.getLocalHost().getHostName();
                } catch (UnknownHostException e1) {
                    e1.printStackTrace();
                }
    
    
                return "{\"location\" : \"http://"+hostname+":8080/emailinvitation/image/path/"+serverfile.getName()+"\"}";
    
            } catch (IOException e) {
            }
    
            return "{\"location\":\"http://localhost:8080/emailinvitation/image/path/unknown.png\"}";
        }
    
        private Multipart newChild(Multipart parent, String alternative) {
            MimeMultipart child = new MimeMultipart(alternative);
            MimeBodyPart mbp = new MimeBodyPart();
            try {
                parent.addBodyPart(mbp);
                mbp.setContent(child);
            } catch (MessagingException e) {
                // TODO logger log exception
            }
    
            return child;
        }
    
        private BodyPart buildCalendarPart(Invitation invitation, String methodType) throws Exception {
    
            Date date1 = dateParser.parse(dateFormater.format(invitation.getStartdate()) + " " + invitation.getStarttime());
            String startDate = timeZoneToUTC(invitation, date1);
    
            Date date2 = dateParser.parse(dateFormater.format(invitation.getEnddate()) + " " + invitation.getEndtime());
            String endDate = timeZoneToUTC(invitation, date2);
    
            BodyPart calendarPart = new MimeBodyPart();
    
    
            String calendarContent = "BEGIN:VCALENDAR\n" + "METHOD:" + methodType + "\n" + "PRODID: BCP - Meeting\n"
                    + "VERSION:2.0\n" + "X-WR-TIMEZONE:" + invitation.getTimezone() + "\n" + "BEGIN:VEVENT\n" + "DTSTAMP:"
                    + startDate + "Z\n" + "DTSTART:" + startDate + "Z\n" + "DTEND:" + endDate + "Z\n"
                    + "SUMMARY:test request\n" + "UID:" + invitation.getTo() + "" + startDate + "\n"
                    + "ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=FALSE:MAILTO:" + invitation.getTo() + "\n"
                    + "ORGANIZER:MAILTO:" + senderAddress + "\n" + "LOCATION:Test\n"  + "SEQUENCE:0\n"
                    + "PRIORITY:5\n" + "CLASS:PUBLIC\n" + "STATUS:CONFIRMED\n" + "TRANSP:OPAQUE\n" + "BEGIN:VALARM\n"
                    + "ACTION:DISPLAY\n" + "DESCRIPTION:REMINDER\n" + "TRIGGER;RELATED=START:-PT00H15M00S\n"
                    + "END:VALARM\n" + "END:VEVENT\n" + "END:VCALENDAR";
    
            calendarPart.addHeader("Content-Class", "urn:content-classes:calendarmessage");
            calendarPart.setContent(calendarContent, "text/calendar;method=" + methodType);
    
            return calendarPart;
        }
    
        private BodyPart buildHtmlTextPart(Invitation invitation) {
    
            MimeBodyPart descriptionPart = new MimeBodyPart();
            String content = invitation.getDescription();
            try {
                descriptionPart.setContent(content, "text/html; charset=utf-8");
            } catch (MessagingException e) {
                // TODO logger log exception
    
            }
            return descriptionPart;
        }
    
        private void addImages(Multipart parent,String filename)  {
    
            MimeBodyPart mbpAttachment = new MimeBodyPart();
    
            try {
    
                File file = new File("C:\\apache-tomcat-8.5.24\\tmpFiles\\"+filename);
                FileDataSource ds = new FileDataSource(file);
                mbpAttachment.setDataHandler(new DataHandler(ds));
                mbpAttachment.setDisposition(BodyPart.INLINE);
                mbpAttachment.setHeader("Content-ID", filename);
                mbpAttachment.setFileName(filename);
                parent.addBodyPart(mbpAttachment);
            } catch (Exception e) {
                //TODO logger log exception
    
            }
    
    
        }
    
        private String timeZoneToUTC(Invitation invitation, Date date) {
            ZoneId zone = ZoneId.of(invitation.getTimezone());
    
            String date1 = dateParser.format(date);
    
            DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm").withZone(zone);
    
            ZonedDateTime utc = ZonedDateTime.parse(date1, fmt).withZoneSameInstant(ZoneId.of("UTC"));
    
            Timestamp sqlTs = Timestamp.valueOf(utc.toLocalDateTime());
    
            return dateFormat.format(sqlTs);
        }
    
        public String getHtmlWithEncodedImages(Multipart parent,Invitation invitation) {
    
            String temp = invitation.getDescription();
            String html="<html><body>"+invitation.getDescription()+"</body></html>";
            Document document = Jsoup.parse(html);
            Elements allElements=document.body().getElementsByTag("img");
            for (Element element : allElements) {
                String elementstring=element.toString();
                String tempfilename = elementstring.substring(elementstring.indexOf("file"));
                String filename=tempfilename.substring(0,tempfilename.indexOf('"'));
                temp=temp.replace(elementstring.substring(elementstring.indexOf('"'), elementstring.lastIndexOf('"')),"\"cid:"+filename);
    
                addImages(parent, filename);
            }
            System.out.println("--++--"+temp);
            return temp;
        }
    

相关问题