Ask for a mail sender class


#1

anyone have already coded a cross platform class that send basically emails to be used in juce ? i mean i can use popen to call externally the sendmail or mailx process… but on windows and mac ? probably an external page in php that does the real work, but that’s not a good solution imho…

i have such a need, and i would like to hear if you guys approached the problem already or can gave me some ideas on how to do that without hassling to much.


#2

WebService perhaps…?
Make use of the URL class to connect and post the content of the email to a small WebService function.


#3

yeah that is one of the solutions i think about. a small php page somewhere that does sending the mail.

anyway i’m still open to other solutions :smiley:


#4

It depends what you are trying to do.

Just firing a mail at an open SMTP server is trivial, and a class to do so would be extremely easy to write. If, however, you’re looking for ESMTP, SSL, or IMAP support, for example, that’s a huge amount of work, since essentially you’re into building a full email client.

Probably the safest approach is to write a small SMTP client of your own, that can resolve the name of the outgoing mail to a recipient server, then just pipe the raw SMTP to that server. The name resolution stuff might be a little fiddly - I’ve never written anything to do that personally, but the SMTP part is trivial.


#5

well, i need to send a mail from a smtp server that needs authentication using ssl and starttls command. i see that smtp commands are quite straightforward, but i don’t know how to cope with auth, ssl and such things (well i’m too lazy at the moment !).

i’ve already a juce::SMTP class that does work (no auth, ssl just plain smtp commands to send a memoryblock). anyway i’m trying to find some code around that maybe can help on this…


#6

I’m interested in the subject… any progress?


#7

i’ve got this, it was a start from some time ago.
don’t know even if it compiles :lol:

i never finished it properly cause i ended doing an external web script fo sending the email, now would be good to make use of curl+openssl libraries to have more control:

juce_SMTP.h

/*
  ==============================================================================

   This file is part of the JUCE library - "Jules' Utility Class Extensions"
   Copyright 2004-7 by Raw Material Software ltd.

  ------------------------------------------------------------------------------

   JUCE can be redistributed and/or modified under the terms of the
   GNU General Public License, as published by the Free Software Foundation;
   either version 2 of the License, or (at your option) any later version.

   JUCE is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with JUCE; if not, visit www.gnu.org/licenses or write to the
   Free Software Foundation, Inc., 59 Temple Place, Suite 330,
   Boston, MA 02111-1307 USA

  ------------------------------------------------------------------------------

   If you'd like to release a closed-source product which uses JUCE, commercial
   licenses are also available: visit www.rawmaterialsoftware.com/juce for
   more information.

  ==============================================================================
*/

#ifndef __JUCE_SMTP_JUCEHEADER__
#define __JUCE_SMTP_JUCEHEADER__

#include "juce_Socket.h"

//==============================================================================
/**
    Represents a SMTP sever and has a bunch of useful functions to send messages
    and receive manipulate it.

    This class can be used to launch URLs in browsers, and also to create
    InputStreams that can read from remote http or ftp sources.

    @code

        SMTP smtp;
        smtp.connect ("smtp.gmail.com", 465, true, "your@email.com", "xxx");
        smtp.sendMessage ("your@email.com",
                          "destination@email.com",
                          "your message body",
                          true);

    @endcode

*/
class JUCE_API  SMTP
{
public:

    //==============================================================================
    /** Creates a URL from a string. */
    SMTP ();

    /** Destructor. */
    ~SMTP() throw();

    //==============================================================================
    bool connect (const String& host,
                  const int port = 25,
                  const bool useAuthentication = false,
                  const String& login = String::empty,
                  const String& password = String::empty);

	void close ();

    //==============================================================================
    bool sendMessage (const String& fromAddress,
                      const String& toAddress,
                      const String& messageData,
					  const bool closeConnection = false);

    //==============================================================================
    juce_UseDebuggingNewOperator

private:

    //==============================================================================
    void writeString (const String& message);
    String readString ();

    StreamingSocket socket;
    String hostName;
    int volatile portNumber;
    bool connected, useAuthentication;
    String authLogin;
    String authPassword;
};


#endif   // __JUCE_SMTP_JUCEHEADER__

juce_SMTP.cpp

/*
  ==============================================================================

   This file is part of the JUCE library - "Jules' Utility Class Extensions"
   Copyright 2004-7 by Raw Material Software ltd.

  ------------------------------------------------------------------------------

   JUCE can be redistributed and/or modified under the terms of the
   GNU General Public License, as published by the Free Software Foundation;
   either version 2 of the License, or (at your option) any later version.

   JUCE is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with JUCE; if not, visit www.gnu.org/licenses or write to the
   Free Software Foundation, Inc., 59 Temple Place, Suite 330,
   Boston, MA 02111-1307 USA

  ------------------------------------------------------------------------------

   If you'd like to release a closed-source product which uses JUCE, commercial
   licenses are also available: visit www.rawmaterialsoftware.com/juce for
   more information.

  ==============================================================================
*/

#include "../../basics/juce_StandardHeader.h"

BEGIN_JUCE_NAMESPACE

#include "juce_SMTP.h"

//==============================================================================
SMTP::SMTP ()
    : connected (false),
      useAuthentication (false)
{
}

SMTP::~SMTP() throw()
{
    close ();
}

//==============================================================================
bool SMTP::connect (const String& host,
                    const int port,
                    const bool useAuth,
                    const String &login,
                    const String &password)
{
    if (connected)
        close ();

    hostName = host;
    portNumber = port;
    useAuthentication = useAuth;
    authLogin = login;
    authPassword = password;
    
    if (socket.connect (hostName, portNumber, 0))
    {
        int retValue = socket.waitUntilReady (true, 10000);
        if (retValue == 1)
        {
            String bytesRead = readString ();
            
            DBG (bytesRead);

			if (useAuthentication)
			{
			    writeString ("EHLO\n");
				readString ();
				
				// XXX - what to do from now on ?
				// XXX - what about if i want ssl ?
			}
			else
			{
			    writeString ("HELO\n");
				readString ();
			}

			connected = true;
        }
        else if (retValue == 0)
        {
            printf ("Timeout waiting for SMTP server\n");
        }
        else if (retValue == -1)
        {
            printf ("Error waiting for SMTP server\n");
        }
    }
    else
    {
        printf ("Error connecting to SMTP server !\n");
    }

    return connected;
}

void SMTP::close ()
{
	if (socket.isConnected ())
	{
		writeString ("QUIT\n");
		readString ();
		
		socket.close ();
	}

	hostName = String::empty;
	portNumber = 25;
	useAuthentication = false;
	authLogin = String::empty;
	authPassword = String::empty;
	connected = false;
}

//==============================================================================
bool SMTP::sendMessage (const String& fromAddress,
                        const String& toAddress,
                        const String& messageData,
						const bool closeConnection)
{
    if (! connected)
        return false;

    writeString ("MAIL from: ");
    writeString (fromAddress);
    writeString ("\n");
    printf ("%s\n", (const char*) readString ());
    // TODO - handle return status code

    writeString ("RCPT To: ");
    writeString (toAddress);
    writeString ("\n");
    printf ("%s\n", (const char*) readString ());
    // TODO - handle return status code

    writeString ("RCPT To: ");
    writeString (toAddress);
    writeString ("\n");
    printf ("%s\n", (const char*) readString ());
    // TODO - handle return status code

    writeString ("DATA\n");
    writeString (messageData);
    writeString (".\n");
    printf ("%s\n", (const char*) readString ());
    // TODO - handle return status code
    
	if (closeConnection)
		close ();

    return true;
}

//==============================================================================
void SMTP::writeString (const String& message)
{
    socket.write ((const char*) message, message.length ());
}

String SMTP::readString ()
{
    const int bufferSize = 1024;
    char responseBuffer [bufferSize];

    int bytesRead = socket.read (responseBuffer, bufferSize);

    (void*) bytesRead;

    DBG (String (responseBuffer) + " " + String (bytesRead));

    return String (responseBuffer);
}


END_JUCE_NAMESPACE

at least is a starting point !