Inserting Images in Emails


https://forum.kartris.com/Topic1883.aspx
Print Topic | Close Window

By pcotgrove - Mon 1 Apr 2013
Is it possible to insert images into the emails that the system generates?

For example I would like to have an image in the New Customer email that is generated as part of a new customer registration.

I have amended the text in the EmailText_CustomerSignupHeader in the database with the relevant markup tag but it is not translated and appears as jsut text!

Many Thanks
By Paul - Mon 1 Apr 2013
It should be possible, but you'd need to put fully qualified URLs for the images (e.g. http://www.site.xyz/images/myimage.jpg), and host them on your site (maybe put aside a folder for this).

Also worth considering that most mail systems won't display images in HTML email by default for privacy reasons (because the images are called from a remote server, the act of calling them can be used to notify the remote server that you're viewing the mail). For example, gmail is typical - an HTML email will have gaps where the images would be, and you have to click a link 'display images' to see them.
By pcotgrove - Tue 2 Apr 2013
Hi Paul

Thanks for the info - as I stated in the original post, I have updated the EmailText_CustomerSignupHeader property in the database to be something similar to:

<img src="http://www.abc.com/Images/Email/smiley.gif"> so that this image would appear at the top of the email sent to a new customer after they have completed registration.
When the email is received the body of the email reads:
There is no image, either displayed or not (disaplayed as a space as you describe in your post) - the html markup seems to be treated as a string literal and is not processed as HTML.
Is there anything else I need to consider here? Standard breaks <br /> appear to work ok but I just can seem to do anything with these image tags or the small amount of inline CSS that I also tried with
By Paul - Tue 2 Apr 2013
EmailText_CustomerSignupHeader and other language strings are used in text emails. Originally kartris only supported text emails.

In 2.0, templates are now supported. You can find the HTML templates for the various mails in the following folder:

Skins/Kartris/Templates

Kartris will look for templates in the active site skin, the default being 'Kartris'. If you're using an older skin without these templates, you can copy the templates in from the Kartris default skin.

If there are no HTML templates found, Kartris will revert to sending pure text email. Even if this contains HTML markup, it won't show as HTML in the email because the MIME type for the messages is not set as HTML.

I'll try to add something in the user guide about this, still working through that to try to get everything up to date.
By pcotgrove - Tue 2 Apr 2013
Thats great info Paul, thanks - I have taken a good look at these templates and will look at that approach

Just one question - how does the system know what template to use. If I create a new template in my skin template folder called NewCustomer.html, whereabouts in the system do I register the template name so that the email functions will pick the template up and use it instead of the text based entries within the database?
By pcotgrove - Tue 2 Apr 2013
Looking through the code and the templates I can see how this all works but in the CustomerAccount.aspx.vb there is no call to the RetrieveHTMLEmailTemplate method.

With this is mind is there a way to implememt anHTML template for new customer registration 'out of the box' or is this something I would have to implement myself?

Your earlier post indicated that there maybe something place for the customer registration but it is not looking that way from what I can see
By Paul - Wed 3 Apr 2013
At present only the items already templated with email templates in the default kartris skin are handled... so the files will have to have these names (although there is a language part in the name which can be used to create files for other languages within the same skin) but not sure why the new customer one isn't there, i don't think there are technical reasons it cannot be handled.
By Paul - Thu 4 Apr 2013
Medz updated the email templating to include the new customer... this is the changeset on codeplex:

http://kartris.codeplex.com/SourceControl/changeset/22910

This should be in the next build 2.0002, maybe 1-2 weeks time, but you can grab the updated code from the repository now.
By pcotgrove - Thu 4 Apr 2013
Hi Paul

Applied the changes and the email gets sent using the template but it all appears as clear text and not translated into HMTL as below:



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">



<html xmlns="http://www.w3.org/1999/xhtml"xml:lang="en" lang="en">



<head>



<styletype="text/css">



#mail_container { border: solid 1px#999; padding: 20px; width: 600px; }



#mail_container p { font-family: Segoe UI,Arial, Helvetica, Sans-Serif; font-size: 13px; font-weight: normal; color:#555; padding: 5px 0; margin: 0; }



#mail_container h1 { font-family:"Segoe UI Light", Segoe UI, Arial, Helvetica, Sans-Serif;font-weight: lighter; font-size: 180%; letter-spacing: 0px; color: #000;margin: 3px 0 10px 0; }



#mail_container h2 { font-family:"Segoe UI Light", Segoe UI, Arial, Helvetica, Sans-Serif;font-weight: lighter; font-size: 140%; letter-spacing: 0px; color: #000;margin: 8px 0 3px 0; }



#mail_container .line { margin-top: 10px;border-bottom: solid 1px #ccc; }



#mail_container table { background-color: #eee;border-collapse: collapse; width: 100%; }



#mail_container th { background-color: #fff;border-bottom: solid 1px #000; padding: 2px 5px; text-transform: uppercase;font-size: 85%; color: #999; }



#mail_container td { border-bottom: solid1px #ccc; padding: 2px 5px; text-align: right; }



#mail_container .col1 { text-align: left; }



#mail_container .col2 { text-align: right;vertical-align: top; }



#mail_container .row_totals strong { color: #f00; }



#mail_container .row_item .col2 { color: #090; }



#mail_container a { font-weight: normal;color: #04d; }



</style>



<metahttp-equiv="content-type" content="text/html;charset=utf-8" />



<title>NewAccount on xyz.com</title>



</head>



<body>





<divid="mail_container">



<h1class="email_text"></h1>



<pclass="email_text">



Anaccount has been created for you on xyz. If you return to ourshop, use the details below to log in:



</p>





<br/>





<p>Email Address: [email protected]</p>



<p>Password: xxxxx</p>





<br/>





<pclass="email_text">To view your account, go to <a href="http://xyz.com/customer.aspx">http://xyz.com/customer.aspxhttp://xyz.com/customer.aspx</a>.



Here you can view your orders,change your password, and see any saved shopping baskets.</p>





<br/>



<h2class="email_text">



</h2>



<pclass="email_text">Hope to see you again soon!</p>



</div>



</body>



</html>

By Paul - Fri 5 Apr 2013
Do you have general.email.enableHTML config setting set to 'y'?
By pcotgrove - Fri 5 Apr 2013
Yes I believe so, I certainly get the templated email when recieving order status changes.

After making the changes, is there any requirement to run the precomile.bat file or are the changes just intepreted on runtime?
By pcotgrove - Fri 5 Apr 2013
Sorry to keep spamming you

I have noticed that the sendmail function is not in the same format as the other implementations, the password reset version for example - the boolean blnHTMLEmail is not being used although it is set correctly when the template is retrieved.

Could this be a problem or should I try to precompile the site? Not sure if I need to do this if the code changes, can you confirm??

From NewCustomerSignUp

SendEmail(LanguagesBLL.GetEmailFrom(CInt(Session("LANG"))), strEmail, strSubject, sbEmailText.ToString)


From PasswordReset

SendEmail(LanguagesBLL.GetEmailFrom(intCurrentLanguage), strEmailAddress, strSubjectLine, strBodyText, , , , , blnHTMLEmail)
By Paul - Fri 5 Apr 2013
Shouldn't need to precompile, things should run fine as the scripts...

I am checking the code now, I think the HTMLemail boolean is optional, but it assumes text if not there, which could explain the problem. I'll check the file now.
By Paul - Fri 5 Apr 2013
Can you try replacing that code block with this modified one:


'Send new account email to new customer
If KartSettingsManager.GetKartConfig("frontend.users.emailnewaccountdetails") = "y" And blnNewUser Then

Dim blnHTMLEmail As Boolean = KartSettingsManager.GetKartConfig("general.email.enableHTML") = "y"
If blnHTMLEmail Then
Dim strHTMLEmailText As String = RetrieveHTMLEmailTemplate("NewCustomerSignUp")
'build up the HTML email if template is found
If Not String.IsNullOrEmpty(strHTMLEmailText) Then
strHTMLEmailText = strHTMLEmailText.Replace("[webshopurl]", WebShopURL)
strHTMLEmailText = strHTMLEmailText.Replace("[websitename]", GetGlobalResourceObject("Kartris", "Config_Webshopname"))
strHTMLEmailText = strHTMLEmailText.Replace("[customeremail]", UC_KartrisLogin.UserEmailAddress)
strHTMLEmailText = strHTMLEmailText.Replace("[customerpassword]", UC_KartrisLogin.UserPassword)
sbdNewCustomerEmailText.Clear()
sbdNewCustomerEmailText.Append(strHTMLEmailText)
Else
blnHTMLEmail = False
End If
End If
SendEmail(strFromEmail, UC_KartrisLogin.UserEmailAddress, strSubject, sbdNewCustomerEmailText.ToString, , , , , blnHTMLEmail)
End If
By pcotgrove - Fri 5 Apr 2013
Just to let you know I have got this working, I had to amend your code snippet sent in the earlier post.

Here is my working code:

'Send new account email to new customer
If KartSettingsManager.GetKartConfig("frontend.users.emailnewaccountdetails") = "y" Then

'Build up email text
Dim strSubject As String = GetGlobalResourceObject("Email", "Config_SubjectLine5")
Dim sbEmailText As StringBuilder = New StringBuilder
sbEmailText.Append(GetGlobalResourceObject("Email", "EmailText_CustomerSignedUpHeader") & vbCrLf & vbCrLf)
sbEmailText.Append(GetGlobalResourceObject("Email", "EmailText_EmailAddress") & strEmail & vbCrLf)
sbEmailText.Append(GetGlobalResourceObject("Email", "EmailText_CustomerCode") & strPassword & vbCrLf & vbCrLf)
sbEmailText.Append(GetGlobalResourceObject("Email", "EmailText_CustomerSignedUpFooter1") & CkartrisBLL.WebShopURL & "customer.aspx" & GetGlobalResourceObject("Email", "EmailText_CustomerSignedUpFooter2"))
sbEmailText.Replace("<br>", vbCrLf).Replace("<br />", vbCrLf)

Dim blnHTMLEmail As Boolean = KartSettingsManager.GetKartConfig("general.email.enableHTML") = "y"

If blnHTMLEmail Then
Dim strHTMLEmailText As String = RetrieveHTMLEmailTemplate("NewCustomerSignUp")
'build up the HTML email if template is found

If Not String.IsNullOrEmpty(strHTMLEmailText) Then
strHTMLEmailText = strHTMLEmailText.Replace("[webshopurl]", WebShopURL)
strHTMLEmailText = strHTMLEmailText.Replace("[websitename]", GetGlobalResourceObject("Kartris", "Config_Webshopname"))
strHTMLEmailText = strHTMLEmailText.Replace("[customeremail]", GetGlobalResourceObject("Email", "EmailText_EmailAddress"))
strHTMLEmailText = strHTMLEmailText.Replace("[customerpassword]", GetGlobalResourceObject("Email", "EmailText_CustomerCode"))
sbEmailText.Clear()
sbEmailText.Append(strHTMLEmailText)
Else
blnHTMLEmail = False
End If

End If

SendEmail(LanguagesBLL.GetEmailFrom(CInt(Session("LANG"))), strEmail , strSubject, sbEmailText.ToString, , , , , blnHTMLEmail)
End If
By pcotgrove - Fri 5 Apr 2013
Small amendment!!

strHTMLEmailText = strHTMLEmailText.Replace("[customeremail]", strEmail)
strHTMLEmailText = strHTMLEmailText.Replace("[customerpassword]", strPassword)
By pcotgrove - Sat 6 Apr 2013
As you stated earlier in this thread, even though I embedded (base64) images into the email (via the template) they still show up in the recipient mailbox as red cross broken links, an the images will not display.

I have adopted a different approach using cid data - below is an example that appears in my HTML template files within the skin:

<img src="cid:EmbeddedLogo" alt="xyz.com" title="xyz.com" />

I made some 'hardcoded' changes to the SendEmail function in kartris.vb but these could easily becoming global settings held within the DB, general.email.logo for example that specifies the local path of the image to the web application.

My change is located just after the SMTP authenticated user check and basically adds in an AlternativeView using a LinkedResource which is the image(s)

Dim objMail As System.Net.Mail.SmtpClient = New System.Net.Mail.SmtpClient(GetKartConfig("general.email.mailserver"), CInt(GetKartConfig("general.email.smtpportnumber")))
Dim strUserName As String = GetKartConfig("general.email.smtpauthusername")
If Not String.IsNullOrEmpty(strUserName) Then
objMail.Credentials = New System.Net.NetworkCredential(strUserName, GetKartConfig("general.email.smtpauthpassword"))
End If

Dim htmlView = AlternateView.CreateAlternateViewFromString(strBody, Encoding.UTF8, MediaTypeNames.Text.Html)

Dim mediaType As String = MediaTypeNames.Image.Jpeg
Dim imgLogo As New LinkedResource("\\Images\\Templates\\logo.jpg", mediaType)
Dim imgThankYou As New LinkedResource("\\Images\\Templates\\thanks.jpg", mediaType)

imgLogo.ContentId = "EmbeddedLogo"
imgLogo.ContentType.MediaType = mediaType
imgLogo.TransferEncoding = TransferEncoding.Base64
imgLogo.ContentType.Name = imgLogo.ContentId
imgLogo.ContentLink = New Uri("cid:" + imgLogo.ContentId)

imgThankYou.ContentId = "EmbeddedThankYou"
imgThankYou.ContentType.MediaType = mediaType
imgThankYou.TransferEncoding = TransferEncoding.Base64
imgThankYou.ContentType.Name = imgThankYou.ContentId
imgThankYou.ContentLink = New Uri("cid:" + imgThankYou.ContentId)

htmlView.LinkedResources.Add(imgLogo)
htmlView.LinkedResources.Add(imgThankYou)
objMailMessage.AlternateViews.Add(htmlView)
objMailMessage.IsBodyHtml = True

objMail.Send(objMailMessage)

Now if the cid refernce exists in the template then the image is inserted and successfully displayed within the body of the message in the recipient mailbox.

Maybe you would like to integrate this into the next release? Would be great to see it configured from the Admin pages - it will also make it easy for me to upgrade to the newer versions as they are released.

Thanks