Send email: Difference between revisions

From Rosetta Code
Content added Content deleted
Line 58: Line 58:
Call doc.Send( False )
Call doc.Send( False )


</lang>
=={{header|Java}}==

<lang Java>
import java.util.Properties;

import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Message.RecipientType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**
* Mail
*/
public class Mail
{
/** session */
protected Session session;

/**
* Mail constructor.
*
* @param host Host
*/
public Mail(String host)
{
Properties properties = new Properties();
properties.put("mail.smtp.host", host);

session = Session.getDefaultInstance(properties);
}

/**
* Send email message.
*
* @param from From
* @param tos Recipients
* @param ccs CC Recipients
* @param subject Subject
* @param text Text
* @throws MessagingException
*/
public void send(String from, String tos[], String ccs[], String subject,
String text)
throws MessagingException
{
MimeMessage message = new MimeMessage(session);

message.setFrom(new InternetAddress(from));

for (String to : tos) {
message.addRecipient(RecipientType.TO, new InternetAddress(to));
}

for (String cc : ccs) {
message.addRecipient(RecipientType.TO, new InternetAddress(cc));
}

message.setSubject(subject);
message.setText(text);

Transport.send(message);
}
}
</lang>
</lang>



Revision as of 21:02, 10 February 2010

Task
Send email
You are encouraged to solve this task according to the task description, using any language you may know.

Write a function to send an email. The function should have parameters for setting From, To and Cc addresses; the Subject, and the message text, and optionally fields for the server name and login details.

  • If appropriate, explain what notifications of problems/success are given.
  • Solutions using libraries or functions from the language are preferred, but failing that, external programs can be used with an explanation.
  • Note how portable the solution given is between operating systems when multi-OS languages are used.

(Remember to obfuscate any sensitive data used in examples)

AutoHotkey

ahk discussion

Library: COM.ahk

<lang autohotkey>sSubject:= "greeting" sText  := "hello" sFrom  := "ahk@rosettacode" sTo  := "whomitmayconcern"

sServer  := "smtp.gmail.com" ; specify your SMTP server nPort  := 465 ; 25 bTLS  := True ; False inputbox, sUsername, Username inputbox, sPassword, password

COM_Init() pmsg := COM_CreateObject("CDO.Message") pcfg := COM_Invoke(pmsg, "Configuration") pfld := COM_Invoke(pcfg, "Fields")

COM_Invoke(pfld, "Item", "http://schemas.microsoft.com/cdo/configuration/sendusing", 2) COM_Invoke(pfld, "Item", "http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout", 60) COM_Invoke(pfld, "Item", "http://schemas.microsoft.com/cdo/configuration/smtpserver", sServer) COM_Invoke(pfld, "Item", "http://schemas.microsoft.com/cdo/configuration/smtpserverport", nPort) COM_Invoke(pfld, "Item", "http://schemas.microsoft.com/cdo/configuration/smtpusessl", bTLS) COM_Invoke(pfld, "Item", "http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", 1) COM_Invoke(pfld, "Item", "http://schemas.microsoft.com/cdo/configuration/sendusername", sUsername) COM_Invoke(pfld, "Item", "http://schemas.microsoft.com/cdo/configuration/sendpassword", sPassword) COM_Invoke(pfld, "Update")

COM_Invoke(pmsg, "Subject", sSubject) COM_Invoke(pmsg, "From", sFrom) COM_Invoke(pmsg, "To", sTo) COM_Invoke(pmsg, "TextBody", sText) COM_Invoke(pmsg, "Send")

COM_Release(pfld) COM_Release(pcfg) COM_Release(pmsg) COM_Term()

  1. Include COM.ahk</lang>

Lotusscript

<lang Lotusscript>Dim session As New NotesSession Dim db As NotesDatabase Dim doc As NotesDocument Set db = session.CurrentDatabase Set doc = New NotesDocument( db ) doc.Form = "Memo" doc.SendTo = "John Doe" doc.Subject = "Subject of this mail" Call doc.Send( False )

</lang>

Java

<lang Java> import java.util.Properties;

import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.Message.RecipientType; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage;

/**

* Mail
*/

public class Mail {

   /** session */
   protected Session session;
   /**
    * Mail constructor.
    * 
    * @param host Host
    */
   public Mail(String host)
   {
       Properties properties = new Properties();
       properties.put("mail.smtp.host", host);
       session = Session.getDefaultInstance(properties);
   }
   /**
    * Send email message.
    * 
    * @param from From
    * @param tos Recipients
    * @param ccs CC Recipients
    * @param subject Subject
    * @param text Text
    * @throws MessagingException
    */
   public void send(String from, String tos[], String ccs[], String subject,
       String text)
       throws MessagingException
   {
       MimeMessage message = new MimeMessage(session);
       message.setFrom(new InternetAddress(from));
       for (String to : tos) {
           message.addRecipient(RecipientType.TO, new InternetAddress(to));
       }
       for (String cc : ccs) {
           message.addRecipient(RecipientType.TO, new InternetAddress(cc));
       }
       message.setSubject(subject);
       message.setText(text);
       Transport.send(message);
   }

} </lang>

Mathematica

Mathematica has the built-in function SendMail, example: <lang Mathematica>SendMail["From" -> "from@email.com", "To" -> "to@email.com",

"Subject" -> "Sending Email from Mathematica", "Body" -> "Hello world!", 
"Server" -> "smtp.email.com"]</lang>

The following options can be specified: <lang Mathematica>"To" "Cc" "Bcc" "Subject" "Body" "Attachments" "From" "Server" "EncryptionProtocol" "Fullname" "Password" "PortNumber" "ReplyTo" "ServerAuthentication" "UserName"</lang> Possible options for EncryptionProtocol are: "SSL","StartTLS" and "TLS". This function should work fine on all the OS's Mathematica runs, which includes the largest 3: Windows, Linux, Mac OSX.


OCaml

  • using the library smtp-mail-0.1.3

<lang ocaml>let h = Smtp.connect "smtp.gmail.fr";; Smtp.helo h "hostname";; Smtp.mail h "<john.smith@example.com>";; Smtp.rcpt h "<john-doe@example.com>";; let email_header = "\ From: John Smith <john.smith@example.com> To: John Doe <john-doe@example.com> Subject: surprise";; let email_msg = "Happy Birthday";; Smtp.data h (email_header ^ "\r\n\r\n" ^ email_msg);; Smtp.quit h;;</lang>

Perl

This subroutine throws an appropriate error if it fails to connect to the server or authenticate. It should work on any platform Perl does.

<lang perl>use Net::SMTP; use Authen::SASL;

 # Net::SMTP's 'auth' method needs Authen::SASL to work, but
 # this is undocumented, and if you don't have the latter, the
 # method will just silently fail. Hence we explicitly use
 # Authen::SASL here.

sub send_email

{my %o =
    (from => , to => [], cc => [],
     subject => , body => ,
     host => , user => , password => ,
     @_);
 ref $o{$_} or $o{$_} = [$o{$_}] foreach 'to', 'cc';
 my $smtp = new Net::SMTP($o{host} ? $o{host} : ())
     or die q(Couldn't connect to SMTP server);
 $o{password} and
    $smtp->auth($o{user}, $o{password}) ||
    die 'SMTP authentication failed';
 $smtp->mail($o{user});
 $smtp->recipient($_) foreach @{$o{to}}, @{$o{cc}};
 $smtp->data;
 $o{from} and $smtp->datasend("From: $o{from}\n");
 $smtp->datasend('To: ' . join(', ', @{$o{to}}) . "\n");
 @{$o{cc}} and $smtp->datasend('Cc: ' . join(', ', @{$o{cc}}) . "\n");
 $o{subject} and $smtp->datasend("Subject: $o{subject}\n");
 $smtp->datasend("\n$o{body}");
 $smtp->dataend;
 return 1;}</lang>

An example call:

<lang perl>send_email

  from => 'A. T. Tappman',
  to => ['suchandsuch@example.com', 'soandso@example.org'],
  cc => somebodyelse@example.net',
  subject => 'Important message',
  body => 'I yearn for you tragically.',
  host => 'smtp.example.com:587',
  user => 'tappman@example.com',
  password => 'yossarian';</lang>

If the host parameter is omitted, send_email falls back on the SMTP_Hosts defined in Net::Config. Hence, only two arguments are strictly necessary:

<lang perl>send_email

  to => 'suchandsuch@example.com',
  user => 'tappman@example.com';</lang>

PHP

<lang php>mail('hello@world.net', 'My Subject', "A Message!", "From: my@address.com");</lang>

Pike

Untested:

<lang pike>int main(){

  string to         = "some@email.add";
  string subject    = "Hello There.";
  string from       = "me@myaddr.ess";
  string msg        = "Hello there! :)";
  
  Protocols.SMTP.Client()->simple_mail(to,subject,from,msg);

}</lang>

Python

The function returns a dict of any addresses it could not forward to; other connection problems raise errors.
Tested on Windows, it should work on all POSIX platforms.

<lang python>import smtplib

def sendemail(from_addr, to_addr_list, cc_addr_list,

             subject, message,
             login, password,
             smtpserver='smtp.gmail.com:587'):
   header  = 'From: %s\n' % from_addr
   header += 'To: %s\n' % ','.join(to_addr_list)
   header += 'Cc: %s\n' % ','.join(cc_addr_list)
   header += 'Subject: %s\n\n' % subject
   message = header + message
   
   server = smtplib.SMTP(smtpserver)
   server.starttls()
   server.login(login,password)
   problems = server.sendmail(from_addr, to_addr_list, message)
   server.quit()
   return problems</lang>

Example use: <lang python>sendemail(from_addr = 'python@RC.net',

         to_addr_list = ['RC@gmail.com'],
         cc_addr_list = ['RC@xx.co.uk'], 
         subject      = 'Howdy', 
         message      = 'Howdy from a python function', 
         login        = 'pythonuser', 
         password     = 'XXXXX')</lang>

Sample Email received:

Message-ID: <4a4a1e78.0717d00a.1ba8.ffcfdbdd@xx.google.com>
Date: Tue, 30 Jun 2009 22:04:56 -0700 (PDT)
From: python@RC.net
To: RC@gmail.com
Cc: RC@xx.co.uk
Subject: Howdy

Howdy from a python function

R

Library: tcltk
Library: gdata
Library: caTools

R does not have a built-in facility for sending emails though some code for this, written by Ben Bolker, is available here.

Ruby

Uses the

Library: RubyGems

gems TMail which allows us to manipulate email objects conveniently, and mime-types which guesses a file's mime type based on its filename.

<lang ruby>require 'base64' require 'net/smtp' require 'tmail' require 'mime/types'

class Email

 def initialize(from, to, subject, body, options={})
   @opts = {:attachments => [], :server => 'localhost'}.update(options)
   @msg = TMail::Mail.new
   @msg.from    = from
   @msg.to      = to
   @msg.subject = subject
   @msg.cc      = @opts[:cc]  if @opts[:cc]
   @msg.bcc     = @opts[:bcc] if @opts[:bcc]
   if @opts[:attachments].empty?
     # just specify the body
     @msg.body = body
   else
     # attach attachments, including the body
     @msg.body = "This is a multi-part message in MIME format.\n"
     msg_body = TMail::Mail.new
     msg_body.body = body
     msg_body.set_content_type("text","plain", {:charset => "ISO-8859-1"})
     @msg.parts << msg_body
     octet_stream = MIME::Types['application/octet-stream']
     @opts[:attachments].select {|file| File.readable?(file)}.each do |file|
       mime_type = MIME::Types.type_for(file).first || octet_stream
       @msg.parts << create_attachment(file, mime_type)
     end
   end
 end
 attr_reader :msg
 def create_attachment(file, mime_type)
   attach = TMail::Mail.new
   if mime_type.binary?
     attach.body = Base64.encode64(File.read(file))
     attach.transfer_encoding = 'base64'
   else
     attach.body = File.read(file)
   end
   attach.set_disposition("attachment", {:filename => file})
   attach.set_content_type(mime_type.media_type, mime_type.sub_type, {:name=>file})
   attach
 end
 # instance method to send an Email object
 def send
   args = @opts.values_at(:server, :port, :helo, :username, :password, :authtype)
   Net::SMTP.start(*args) do |smtp|
     smtp.send_message(@msg.to_s, @msg.from[0], @msg.to)
   end
 end
 # class method to construct an Email object and send it
 def self.send(*args)
   self.new(*args).send
 end

end

Email.send(

 'sender@sender.invalid',
 %w{ recip1@recipient.invalid recip2@example.com },
 'the subject',
 "the body\nhas lines",
 {
   :attachments => %w{ file1 file2 file3 },
   :server => 'mail.example.com',
   :helo => 'sender.invalid',
   :username => 'user',
   :password => 'secret'
 }

)</lang>

Tcl

Library: tcllib

Also may use the tls package (needed for sending via gmail). <lang tcl>package require smtp package require mime package require tls

set gmailUser ******* set gmailPass hunter2; # Hello, bash.org!

proc send_simple_message {recipient subject body} {

   global gmailUser gmailPass
   # Build the message
   set token [mime::initialize -canonical text/plain -string $body]
   mime::setheader $token Subject $subject
   # Send it!
   smtp::sendmessage $token -userame $gamilUser -password $gmailPass \
           -recipients $recipient -servers smtp.gmail.com -ports 587
   # Clean up
   mime::finalize $token

}

send_simple_message recipient@example.com "Testing" "This is a test message."</lang>