I'm trying to send transaction emails from my website using the MailKit library but I can't make the html render an anchor tag. In fact I'm not sure that any of the html is being rendered. Any ideas what's wrong? My code is below.
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Eternal Meta", "eternal.meta.transactions#gmail.com"));
message.To.Add(new MailboxAddress(user.Username, user.Email));
message.Subject = "Eternal Meta - Registration";
var builder = new BodyBuilder();
builder.HtmlBody = "<p>Use the link below to activate your account</p><br>Click Me";
message.Body = builder.ToMessageBody();
using (var client = new SmtpClient())
{
client.Connect("smtp.gmail.com", 587, false);
client.Authenticate("eternal.meta.transactions#gmail.com", "password");
client.Send(message);
client.Disconnect(true);
}
Use a fully qualified URL for the "href" attribute (like https://[...]).
The mail client can parse the HTML inside your message and most probably the "href" attribute gets removed as the URL is considered relative.
Related
Is there any way how to remove (anonymise - just place some empty string instead of url) all links in document?
A tags, and some javascripts actions which can open new url.
I have html in document and I am using nodejs, I can use puppeteer or some dom tool.
With javascript you can do this:
var anchors = document.getElementsByTagName('a');
for (var anchor of anchors) {
anchor.href = 'javascript:void(0)';
}
I've read that 'javascript:void(0)' is the best substitute.
This questions has been posed and answered several places on SO, specifically here : Issue with Gmail - Embedded images using MailKit
and handles my exact query, yet the answer doesn't seem to work for my case.
I've tried to build a simple mailer that embeds images in an HTML email, yet in several clients, all images still end up as attachments.
I suspect the fault to be in the way I handle the image attachments (one .gif and several .png) to be:
// Add pictures to embedded resources and replace links to pictures in the message
foreach (string imgpath in ImgPaths)
{
var image = builder.LinkedResources.Add(imgpath);
image.ContentId = MimeUtils.GenerateMessageId();
image.ContentDisposition = new ContentDisposition() { Disposition = ContentDisposition.Inline };
HtmlFormat = HtmlFormat.Replace(Path.GetFileName(imgpath), string.Format("cid:{0}", image.ContentId));
}
builder.HtmlBody = HtmlFormat;
message.Body = builder.ToMessageBody();
I can see from the emails (received in Gmail, for instance), do show that the images are being listed as:
src="images/cid:TPSXHQUDSAU4.JJRKUIEGLTZ5#Loralei"
All images are attached as attachments in both clients I've tried (gmail and roundcube). I've walked through your tutorials and checked out everything here: https://stackoverflow.com/search?q=Mailkit+Embed
Sadly, I just can't seem to find my error. Hopefully #jstedfast could see where I make my mistake?
UPDATE
As mentioned by #jstedfast, the corrected code should be (for my case anyway):
foreach (string imgpath in ImgPaths)
{
var test = Path.GetFileName(imgpath);
var image = builder.LinkedResources.Add(imgpath);
image.ContentId = MimeUtils.GenerateMessageId();
image.ContentDisposition = new ContentDisposition() { Disposition = ContentDisposition.Inline };
//HtmlFormat = HtmlFormat.Replace(Path.GetFileName(imgpath), string.Format("cid:{0}", image.ContentId));
HtmlFormat = HtmlFormat.Replace($"images/{test}", string.Format("cid:{0}", image.ContentId)); //use images/filename
}
This is a great guide to follow too, https://programming.vip/docs/5dac3983f0cd5.html
This looks like the problem:
<img src="images/cid:TPSXHQUDSAU4.JJRKUIEGLTZ5#Loralei" .../>
That needs to be:
<img src="cid:TPSXHQUDSAU4.JJRKUIEGLTZ5#Loralei" .../>
My guess is that in order to fix this, you'd change the following line of code:
HtmlFormat = HtmlFormat.Replace(Path.GetFileName(imgpath), string.Format("cid:{0}", image.ContentId));
to this:
HtmlFormat = HtmlFormat.Replace(imgpath, string.Format("cid:{0}", image.ContentId));
Hope that helps!
I am using a HTML documentation page by an external service which renders JSON snippets within an HTML page.
The HTML source code looks like this:
<pre>{
"product-link": "https://example.com/product-link",
"teaser_image": "https://example.com/teaser-image",
"product_image_first": "https://example.com/product-image-first",
"headline": "Example headline",
}</pre>
The JSON block renders without syntax highlighting.
Since I am not in control of the external service I would like to apply syntax highlighting (color) to the JSON snippet via user script.
I found Greasemonkey but still missing the point on how to inject a syntax highlighter library.
Thanks to xander here is the first working version of my user script base on code-prettify:
(function(d) {
stylizePreElements = function() {
var preElements = document.getElementsByTagName("pre");
for (i = 0; i < preElements.length; ++i) {
var preElement = preElements[i];
preElement.className += "prettyprint";
}
};
injectPrettifyScript = function() {
var scriptElement = document.createElement('script');
scriptElement.setAttribute("src", "https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js");
document.head.appendChild(scriptElement);
};
stylizePreElements();
injectPrettifyScript();
})(document)
Thank you for making my day nicer!
I have this situation:
The user has an editor on his page and he enters text(with colors, formating, hyperlinks and he can also add pictures). When he clicks Submit the data from the editor(with the proper formating) must be sent to a specific placeholder in a Microsoft Office Word document.
I am using OpenXml SDK to write in the document and I tried HtmlToOpenXml so I can read the html.
I use HtmlToOpenXml and from the html string(from the user) I det a couple of paragraphs and now I have to insert them in the content control. Do you know how can I find the control and append them in it(if possible)
I managed to fix this and here is the code I used
//name of the file which will be saved
const string filename = "test.docx";
//html string to be inserted and rendered in the word document
string html = #"<b>Test</b>";
//the Html2OpenXML dll supports all the common html tags
//open the template document with the content controls in it(in my case I used Richtext Field Content Control)
byte[] byteArray = File.ReadAllBytes("..."); // template path
using (MemoryStream generatedDocument = new MemoryStream())
{
generatedDocument.Write(byteArray, 0, byteArray.Length);
using (WordprocessingDocument doc = WordprocessingDocument.Open(generatedDocument, true))
{
MainDocumentPart mainPart = doc.MainDocumentPart;
//just in case
if (mainPart == null)
{
mainPart = doc.AddMainDocumentPart();
new Document(new Body()).Save(mainPart);
}
HtmlConverter converter = new HtmlConverter(mainPart);
Body body = mainPart.Document.Body;
//sdtElement is the Content Control we need.
//Html is the name of the placeholder we are looking for
SdtElement sdtElement = doc.MainDocumentPart.Document.Descendants<SdtElement>()
.Where(
element =>
element.SdtProperties.GetFirstChild<SdtAlias>() != null &&
element.SdtProperties.GetFirstChild<SdtAlias>().Val == "Html").FirstOrDefault();
//the HtmlConverter returns a set of paragraphs.
//in them we have the data which we want to insert in the document with it's formating
//After that we just need to append all paragraphs to the Content Control and save the document
var paragraphs = converter.Parse(html);
for (int i = 0; i < paragraphs.Count; i++)
{
sdtElement.Append(paragraphs[i]);
}
mainPart.Document.Save();
}
File.WriteAllBytes(filename, generatedDocument.ToArray());
}
I would like to send a html and a text content inline, but just one appears inline, the other appears as an attached file.
My code:
MimeMultipart multipart = new MimeMultipart();
String html = "<font size=\"5\">Test HTML</font>";
String text = "Test text + html";
BodyPart bodyparty = new MimeBodyPart();
bodyparty.setContent(text, "text/plain");
multipart.addBodyPart(bodyparty);
bodyparty = new MimeBodyPart();
bodyparty.setContent(html, "text/html");
multipart.addBodyPart(bodyparty);
message.setContent(multipart);
Transport transport = session.getTransport("smtp");
transport.connect(user_auth, user_password);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
Is it possible?
Thanks!
It's unlikely any mail client is going to display that the way you want. Why not embed the plain text part in the html part using <pre> or something like that?