How to user erlang gen_smtp to send html-formatted email? - html

gen_smtp can be found here
What I want is to let the content of email supports HTML tag, such as <strong>Hello</strong>
Will display as Hello.

Look at https://github.com/selectel/pat. It's an easy to use SMTP client and you can use any text, including html tags as body of the message.

See the gen_smtp mimemail tests for an example of multipart/alternative messages:
Email = {<<"text">>, <<"html">>, [
{<<"From">>, <<"me#example.com">>},
{<<"To">>, <<"you#example.com">>},
{<<"Subject">>, <<"This is a test">>}],
#{content_type_params => [
{<<"charset">>, <<"US-ASCII">>}],
disposition => <<"inline">>
},
<<"This is a <strong>HTML</strong> message with some non-ascii characters øÿ\r\nso there">>},
Encoded = mimemail:encode(Email)

The answer given by #Ward Bekker is fundamentally correct but it took me a while to make it work as the mimemail:encode/1 expects a proplist not a map which the example shows.
I used Erlang Erlang/OTP 23 [erts-11.0.3] and it failed with:
** exception error: no function clause matching proplists:get_value(<<"content-type-params">>, #{disposition => <<"inline">>,<<"content-type-params">> => [{<<"charset">>,<<"US-ASCII">>}]},[]) (proplists.erl, line 215)
in function mimemail:ensure_content_headers/7 (/Users/sean/Documents/code/erlang/scofblog/_build/default/lib/gen_smtp/src/mimemail.erl, line 661)
The following is the modified code and the encoded output:
Email = {
<<"text">>,
<<"html">>,
[
{<<"From">>, <<"me#example.com">>},
{<<"To">>, <<"you#example.com">>},
{<<"Subject">>, <<"This is a test">>}
],
[{<<"content-type-params">>, [{<<"charset">>, <<"US-ASCII">>}]},
{<<"disposition">>, <<"inline">>}
],
<<"This is a <strong>HTML</strong> øÿ\r\nso there">>
}.
62> mimemail:encode(Email).
<<"From: me#example.com\r\nTo: you#example.com\r\nSubject: This is a test\r\nContent-Type: text/html;\r\n\tcharset=US-ASCII\r\nCon"...>>
Hope that saves some head scratching.

Related

Erlang SMTP client WITH attachments

I'm looking for one of two things:
An Erlang library that supports sending of emails with attachments
An example of using gen_smtp to send an email with an attachment, since I have already successfully sent emails with this library
It seems there is very little in the way of SMTP client support with attachments out there, although there are plenty of modules that can send plain text emails via SMTP. Anyone have suggestions?
Also, using Windows - I'm not sure the sendmail route is available?
Agus, when I try that exact code, as well as similar code, I keep getting the following error, any ideas?:
** exception error: {badmap,[]}
in function maps:get/3
called as maps:get(content_type_params,[],[])
in call from mimemail:ensure_content_headers/7 (c:/temp/erlang/myapp/_build/default/lib/gen_smtp/src/mimemail.erl, line 667)
in call from mimemail:encode/2 (c:/temp/erlang/myapp/_build/default/lib/gen_smtp/src/mimemail.erl, line 161)
in call from email_test:send_email_with_attachment/0 (c:/temp/erlang/myapp/src/email_test.erl, line 14)
The version of gen_smtp I'm using in rebar.config:
{gen_smtp, ".*", {git, "git://github.com/gen-smtp/gen_smtp.git", {branch, master}}}
Short answer: you can use gen_smtp to send an email with attachment.
If you have used gen_smtp_client:send(Email, Options) or gen_smtp_client:send_blocking(Email, Options), then you can actually generate the Body's Email variable using mimemail:encode/2.
%% #doc Encode a MIME tuple to a binary.
encode({Type, Subtype, Headers, ContentTypeParams, Parts}, Options) ->
...
Below code shows how to send message with email inline body and 2 attachments (test1.txt and erlang.png respectively). The key here is to use multipart/mixed MIME type and construct the email body accordingly.
send_email_with_attachment() ->
From = "noreply#mydomain.com",
ToList = ["target_email#mydomain.com"],
Part2Filename = "/tmp/test1.txt",
{ok, Part2Binary} = file:read_file(Part2Filename),
Part3Filename = "/tmp/erlang.png",
{ok, Part3Binary} = file:read_file(Part3Filename),
Email = mimemail:encode(
{
<<"multipart">>, %%Type,
<<"mixed">>, %%Subtype,
%%Headers,
[
{<<"From">>, <<"No-Reply <noreply#mydomain.com>">>},
{<<"To">>, <<"target_email#mydomain.com">>},
{<<"Subject">>, <<"Mail Subject">>}
],
#{}, %%[], %%ContentTypeParams,
%%(Multi)Parts
[
%%Part 1: this is the inline mail body, note the {<<"disposition">>, <<"inline">>} tag
{
<<"text">>, %%Type,
<<"plain">>, %%Subtype,
%%Headers
[],
%%ContentTypeParams
#{
disposition => <<"inline">>
},
%%Part
<<"Email body (inline) is here blah blah..">>
},
%%Part 2: this is the text file as attachment, note the {<<"disposition">>, <<"attachment">>} tag
{
<<"text">>, %%Type,
<<"plain">>, %%Subtype,
%%Headers
[],
%%ContentTypeParams
#{
disposition => <<"attachment">>,
disposition_params => [{<<"filename">>, <<"test1.txt">>}]
},
%%Part
Part2Binary
},
%%Part 3: this is the PNG file as attachment, note the {<<"disposition">>, <<"attachment">>} tag
{
<<"image">>, %%Type,
<<"png">>, %%Subtype,
%%Headers
[],
%%ContentTypeParams
#{
disposition => <<"attachment">>,
disposition_params => [{<<"filename">>, <<"erlang.png">>}]
},
%%Part
Part3Binary
}
]
},
[] %%Options
),
Opts = [{relay, "smtp.mydomain.com"},
{tls, never}
],
gen_smtp_client:send({From, ToList, Email}, Opts).
This is what you will see in the mailbox:

How to return number and newline with JSON

I want to return a number and a new line
{ data : "3
"}
But every time, I try to do this it is considered invalid
Update
My parser tool tries to do things with Newlines. Here is the complete screenshot:
** Update 2**
This is with jsonlint.com
The problem is that data is not a valid key (check https://www.json.org/ or Do the JSON keys have to be surrounded by quotes?), you need to use quotes for keys in order to have valid syntax. Also you need to add \n for a new line character:
{ "data": "3\n"}
I pasted this into the console without an error:
{ "data" : "3\n"}
Testing one step further:
a = { "data" : "3\n"}
a.data + "hello" // pasted into the console
produced this:
3
hello

Formatting mail body sent from Perl script to include lines and spaces

I need to send an mail through my perl script:
use MIME::Lite;
GetOptions(
'mail|m:s' =>\$recipients
)
my #recipients = split(/,/, $recipients);
sub sendmail {
chomp #recipients;
$to = "#recipients";
$from = 'xyz#gmail.com';
$subject = 'Output';
$msg = MIME::Lite->new(
From => $from,
To => $to,
Subject => $subject,
Data => $mailbody
);
$msg->attr("content-type" => "text/html");
$msg->send;
print "Email Sent Successfully\n";
}
Here, I am appending output to mailbody like:
mailbody.=qq(Welcome\n);
which are statements containing output which has to be emailed.
How can I format this output to include additional lines and/or spaces? I think \n or even lots of spaces are also not accepted by mailbody.=qq(Welcome\n);, which results in a single line of content.
You've said:
"content-type" => "text/html"
This means you are writing HTML (or at least telling the email client that you are).
If you want to send plain text and format it using literal whitespace, then don't claim to send HTML!
"content-type" => "text/plain"
If you want to send HTML, then write HTML which has the formatting you want (e.g. use <p>...</p> to indicate paragraphs, and style="text-indent: 1em;" to indent the first line of a block).
If you want to send HTML (as your content-type implies) then you need to use HTML tags (<br>, <p>...</p>, etc) to format your text.
If you want to use newlines to format your text, then you need to change your content-type to text/plain.
A few other suggestions:
I wouldn't recommend MIME::Lite. These days, you should use something from the Email::* namespace - perhaps Email::Sender or Email::Stuffer (I think I mentioned this yesterday).
You should chomp() $recipients before splitting it into #recipients.
You use #recipients inside sendmail(), but you don't pass the array to the subroutine. It's bad practice to use global variables within a subroutine - it renders your subroutine less portable and harder to maintain.
MIME::Lite expects multiple recipients in a comma-separated string. So splitting $recipients into #recipients is pointless.

JSON error and Run script error

Apologies for any incorrect formatting I am new to these message boards
I am using HTML to customise a Textbox in Spotfire and although I get no errors in the Spotfire client I get the following error when I open the Spotfire analysis in Chrome
{ "titleFontColor":"#999999", "value":<SpotfireControl id="98bb1934a3c14ca2ab598deb672b8e44" />, "valueFontColor":"#010101", "symbol":"%", "min":<SpotfireControl id="0a05e2f1c4094273870d97a23b69efe2" />, "max":<SpotfireControl id="033f79eeccdb46ef982262c3c8a4ed0e" />, "humanFriendly":false, "humanFriendlyDecimal":2, "gaugeWidthScale":2.5, "gaugeColor":"#ebebeb", "label":"", "labelFontColor":"#b3b3b3", "shadowOpacity":0.2, "shadowSize":5, "shadowVerticalOffset":3, "levelColors":["#a9d70b","#f9c802","#ff0000"], "startAnimationTime":100, "startAnimationType":">", "donutStartAngle":90, "hideValue":true, "hideMinMax":true, "hideInnerShadow":false, "noGradient":false, "donut":true, "counter":false, "decimals":0, "formatNumber":false,
"customSectors": [{
"color" : "#D8181C",
"lo" : 0,
"hi" : 1
},{
"color" : "#F5CC0A",
"lo" : 1,
"hi" : 2
},{
"color" : "#50AF28",
"lo" : 2,
"hi" : 3
}] }
I get the following
Error - Unexpected token , in JSON at position 39.
I am very new to HTML and was wondering how I locate position 39 in order to try and find the error?
The second issue I am running into is that HTML displays the Donuts as I would expect in my Spotfire client but when I open the webplayer version the icons are not visible. I have to change tabs in the analysis and then return to the first page for the icons to appear. Is this likely to be an error in my HTML or an error elsewhere?
Thanks
In fact you have several problems,
-First you have to put all this code in one line otherwise "]" or "}" will make an error
-Second you have unexpected characters "<" and "/>" in your json you have to clean your json.
Then you can do in javascript
console.log(your_var)
or
console.log(JSON.parse(your_var))
it will transform in json you json (which is in string format)
We need sources to check what can be the problem.

Convert from HTML::Template to PDF:FromHtml says invalid XML

I create an HTML file using HTML::Template. The resulting code is a valid XML/HTML (check against a xml validator). But while convert to pdf using PDF::FromHTML a message of "invalid token in xml file" is found.
Trying changing the first declaration line from doctype to xml, or supressing, but nothing works. XML::Simple, PDF:API2, XML::Writer are last version.
Ay idea what is happening?
# create template object and store to verify
shout('s',"create template from $str_filepath") if ($bool_DEBUG);
$str_mytemplate = HTML::Template->new(filename => $str_filepath, case_sensitive => 0, no_includes => 1 );
$str_mytemplate->param(\%strct_toreplace);
$str_filepath = envDir('temp').newID().'.html';
shout('',"template created, storing to : $str_filepath") if ($bool_DEBUG);
if (open(FILE, '>', $str_filepath)) {
print FILE $str_mytemplate->output;
close (FILE);
}
# generate pdf from created file
shout('p',"Creating PDF ") if ($bool_DEBUG);
$pdf_this = PDF::FromHTML->new( encoding => 'utf-8' );
$pdf_this->load_file($str_filepath);
$pdf_this->convert( LineHeight => 10, Landscape => 1, PageSize => 'Letter', );
shout('p',"Display PDF") if ($bool_DEBUG);
print header(-type=>'application/pdf', -charset=>'UTF-8');
print $pdf_this->write_file();
$bool_DEBUG and shout(); are a variable and procedure to set and display messages while debugging mode.
Html code generated via template: http://www.etoxica.com/examplecode.html
Template used: http://www.etoxica.com/exampletemplate.tmpl
Message displayed:
SECTION: Creating PDF
Software error:
not well-formed (invalid token) at line 19, column 13, byte 430 at /usr/local/lib64/perl5/XML/Parser.pm line 187.
at /home/grupo/perl/usr/share/perl5/PDF/FromHTML.pm line 141.
Summary: Found the problem (I guess) ;)
Consider the following lines:
<td>
Some line of data
<br/>
A second line of data
</td>
When try to be read by PDF::FromHTML it will send a message of malformed token in the 5th line, specifically on the slash '/' from </td> tag; BUT, that is not the problem, the problem is created by the <br/> tag inside the <td></td>.
If it is changed to <br> or <br /> no error is found. I don't know if using <br> is a good html practice to xml compability, even is defined as it w3c br semantic.