[SOLVED] Send an email with Gmail account using C#

Hi guys !!! 8)

I wrote this class that works perfectly in Windows but that give me lots of problems with Unity:

using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.Net.Sockets;
using UnityEngine;

public class MailSender : MonoBehavior {
	
   // Send an e-mail by using mono C# native classes using an existent Gmail account
   // The "String file" parameter must contain the "filepath + nomefile" informations
   public void sendReport (string file) {
      try {
         // Create the e-mail object
         MailMessage msgMail = new MailMessage ("addressFrom@gmail.com", "addressTo@domain.ext", "Subject", "Body of the mail");
         // Create  the file attachment for this e-mail message.
         Attachment att = new Attachment (file, MediaTypeNames.Application.Octet);
         // Add time stamp information for the file.
         ContentDisposition disposition = att.ContentDisposition;
         disposition.CreationDate = System.IO.File.GetCreationTime (file);
         disposition.ModificationDate = System.IO.File.GetLastWriteTime (file);
         disposition.ReadDate = System.IO.File.GetLastAccessTime (file);
         // Add the file attachment to this e-mail message.
         msgMail.Attachments.Add (att);
         // We need to use the port number 587 to send
         SmtpClient smtp = new SmtpClient("smtp.gmail.com", 587);
         // We neeed to enable the SSL encryption
         smtp.EnableSsl = true;
         // Set the delivery method to send directly with the exixtent connection via smtp
         smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
         // disable the default credentials to make our own authentication
         smtp.UseDefaultCredentials = false;
         // set needed authentication parameters
         smtp.Credentials = new System.Net.NetworkCredential ("username", "password");
         smtp.Send (msgMail);
         // Dispose the attachment
         att.Dispose ();
      } catch (Exception e) {
         Debug.LogError (e.StackTrace);
      } // try-catch       
   } // sendReport
	
} // MailSender

I think that, as it was written, couldn’t work with the mono version included in the current Unity 2.1 version.

Can anyone help me adapting this class to make possible to use it in Unity?

THANKS A LOT !!! :smile:

If you define what “but that give me lots of problems with Unity” means, I’m sure someone would be happy to help.

:stuck_out_tongue: yes sure… I’m sorry !!!

The issues is that

smtp.EnableSsl = true;

throws the following exception:

  at System.Net.Mail.SmtpClient.ChangeToSSLSocket () [0x00000] 
  at System.Net.Mail.SmtpClient.InitiateSecureConnection () [0x00000] 
  at System.Net.Mail.SmtpClient.Send (System.Net.Mail.MailMessage message) [0x00000]

and if you won’t catch exceptions it throws this:

NotImplementedException: The requested feature is not implemented.
System.Net.Mail.SmtpClient.Send (System.Net.Mail.MailMessage message)

while

smtp.UseDefaultCredentials = false;

throws the following exception:

  at System.Net.Mail.SmtpClient.set_UseDefaultCredentials (Boolean value) [0x00000]

and if you won’t catch exceptions it throws this:

NotImplementedException: Default credentials are not supported
System.Net.Mail.SmtpClient.set_UseDefaultCredentials (Boolean value)

If you comment the 2 lines of code I said, the connection will fail launching the following exception:

at System.Net.Mail.SmtpClient.Send (System.Net.Mail.MailMessage message) [0x00000]

I hope this can help !!!

I’d take this one to the mono team and ask how much of this is implemented in the version of mono that unity uses (I believe its version 1.2.5). They have a forum somewhere and on irc.gnome.org they have the Mono channel.

But in Unity 2.5 what version of mono will be used? If I’m not mistaking mono actually is at version 2.2…

The mono version will not change with unity 2.5
As mentioned on the various related threads its mainly Support for Windows + a new editor interface as well as related scripting capabilities + bug fixes
no other larger scale changes

so if you are in need of this you will have to replicate the functionality for now or find an assembly that offers the features you need

Ok !!

I’ll do my best and then I will share it with the community !!! :wink:

Really, you’re better off talking to a server-side script that actually sends the email, instead of directly sending it from the client.

There are other reasons for this, too; many ISPs block outbound SMTP ports.

I dont know much about webcode but this type of thing has been on my mind for a long time. I work with quite a few volunteer groups around the world doing animal welfare work. (Sometimes borders on animal rights-thats a whole debate).

So theres a whole lot of gamers in the world, and some feel like I do, that the way animals get treated sucks (skinned alive dogs and boiled alive cats in China, canadian seal clubbing, illegal whaling, etc) and for years I’ve wanted to make a game where you do the usual gameplay stuff, but then to progress, you need to submit an email- now that could be to a politician, a head of a dodgy business, even a media outlet. So when users are playing a game, they are actually participating in an animal welfare campaign when they send such an email.

Obviously it would need some kind of algorhythm to ensure such a letter isnt full of swear words etc, and I have no idea about how to implement that, but my point is that if games could be used to implement change, then they suddenly are a lot more useful than for mere escapism and entertainment.

Good luck with this, I hope you succeed.

AaronC

There goes my letter. :x

LOL yes its a case of keeping the blade sheathed my friend. It’s a world of abuse and changing anything is very difficult, so if theres any way to integrate this type of thing into mainstream media (videogames) then I’m all for it.

A tripleA “Animal Liberator” videogame might bring about some awareness and motivation to those who would otherwise live and die inside WOW…

AC

I’d agree with Matthew: For sending mail, have a little Webserver running that accepts a simple WWW request from the game (or from the game server, if you have one) is probably the most elegant solution. In an ASP.NET environment, you can use exactly the code you already have, and setting up a simple POST to that Webserver with the WWW class should be pretty easy (for the particular task of sending mail messages, I’d even recommend having your own mail-server … but that obviously depends on what exactly you want to do).

It’s true: Mono in Unity currently is on 1.2.5 … very old. My (totally uneducated guess) is that we’ll get a Mono update for Unity 3.0 (the last time Mono was updated was for Unity 2.0, so I guess that’s a “major release thing”) - but Unity 3.0’s not even announced so all us .NET friends will need to be a little patient, I guess :wink:

… and about the “tripleA Animal Liberator”: That sounds pretty cool. I have a few ideas towards that direction that I’m planning to use in RaMtiGA (after all, how could you raise any world to its Golden Age without loving and caring for all sentient beings … um … except for parasites, of course, like mosquitos and ticks … and bacteria and viruses :wink: ). Just gotta get Traces of Illumination finished first :wink:

The webserver is a very good idea, but… I don’t have the possibilities to make one. On top of that, if the SMTP outgoing port is blocked from the ISP it’s an user problem: he we’ll contact me by phone !!! :stuck_out_tongue:

Pratically I need to send a mail from game to one of my Gmail addresses because I need feedback about errors reports, suggestions, etc… for my application.

I’ve tried lots of possibly solutions, but the one that seems to me the best is to try to import in my project the mono “System.Net.dll” using it as an external plugin. Unfortunately there are 2 questions:

(1) if I import the dll in the Plugins folder of my project I got the following error:

Unhandled Exception: System.InvalidCastException: Cannot cast from source type to destination type.
  at Mono.CSharp.TypeManager.IsFriendAssembly (System.Reflection.Assembly assembly) [0x00000] 
  at Mono.CSharp.RootNamespace.GetTypeInAssembly (System.Reflection.Assembly assembly, System.String name) [0x00000] 
  at Mono.CSharp.GlobalRootNamespace.LookupTypeReflection (System.String name, Location loc) [0x00000] 
  at Mono.CSharp.Namespace.LookupType (System.String name, Location loc) [0x00000] 
  at Mono.CSharp.Namespace.Lookup (Mono.CSharp.DeclSpace ds, System.String name, Location loc) [0x00000] 
  at Mono.CSharp.TypeManager.CoreLookupType (System.String ns_name, System.String name, Boolean mayFail) [0x00000] 
  at Mono.CSharp.TypeManager.CoreLookupType (System.String namespaceName, System.String name) [0x00000] 
  at Mono.CSharp.TypeManager.InitCoreTypes () [0x00000] 
  at Mono.CSharp.Driver.MainDriver (System.String[] args) [0x00000] 
  at Mono.CSharp.Driver.Main (System.String[] args) [0x00000]

and I really ignore what this means !!!

(2) around the net I found examples that describes only the use of a function/method to import from the dll… what about classes? I mean, to send a mail I need to use the

System.Net.Mail.SmtpClient.Send(System.Net.MailMessage message)

function but… how could I create an instance of System.Net.MailMessage to send? On top of that I need also to include an attachment… but, ok, one by one !!!

Any suggestion?

If we’ll go through this I’ll post the complete code to send mail with Unity 2.1, I promise !! :slight_smile:

I would say PHP is a great solution. All you need is one php page, which you can send data to with the WWW command, and that page would use the PHP mail function to send your gmail account an e-mail.

If you’d like, I’d be more than happy to work with you to provide you a solution like this (hosting the php page which is accessed).

I understand what you need, my web design clients all have a contact page for exactly this purpose…for people to report inaccuracies, problems, or just stay in contact. The e-mails are sent using a simple php script.

Yeha :slight_smile: this is it !!!

I was thinking… I need some informations to improve my Unity application sent by the users, so, what if, instead of sending an e-mail, I’ll collect them in a database created with PHP? That’s to say:
(1) send the WWW command from Unity
(2) PHP receive the data
(3) PHP format and store the data
(4) the data will be accessible by a protected area of a site or server

However it will be also interesting to know how to send a mail via PHP mail function.

Yes !!! I will appreciate a lot if you could help me doing this, also because I know nothing about PHP… never used !!! :sweat_smile:

I would also to thank you for your hosting proposal, but I’m hardly knowing that we also have a domain to use as server side PHP application !!! :stuck_out_tongue:

I am actually working on a demo/tutorial series of Unity-PHP Integration. This will involve data sent from Unity and stored into a MySQL database (using PHP to receive, format and put the data in the database, as well as read it and send it back to Unity).

I can also add a short part on PHP mail. While this isn’t Unity-related, I think it will help Unity users by demonstrating something they can do with the WWW call.

Very nice job !!! :wink:
What do you think if we send to PHP a XML file? Is it possible to read and process? Is it simpler than processing text files?

maybe because I’m a fool and I like complicated tasks !!! :stuck_out_tongue:

Ok guys… I did something but the result is not the one I would.

I’m using this PHP script:

<?php
	// the local variable with the path used to save the received data in
	$path = './uploaded/';
	// the name the file must have when it will be created
   	$filename = 'LocalReport-'.date("d-m-Y H:i:s").'.xml';

	// save the $_REQUEST array content in a local variable
	$received = print_r( $_REQUEST, true );
//	print( $received );

	// open a file stream in write and read and store its pointer
	$filePointer = fopen( $path.$filename, 'w+' );
	// write the file content and send a message to the host
	if (!fwrite( $filePointer, $received )) {
		print("ERROR while trying to save the file");
	} else {
		print("File saved successfully !!!");
	} // if-else
	// dispose the pointer
	fclose( $filePointer );
?>

by sending this request (C# code):

using UnityEngine;
using System.Xml;
using System.Collections;

/// <summary>
/// Class:                      ReportDataSender.cs
/// Path:                       Scripts
/// This class provides methods to send some report data via web using WWW Unity APIs
/// </summary>

public class ReportDataSender : MonoBehaviour {

    void Start() {
        // create the XML document
        XmlDocument document = new XmlDocument();
        // load the file from hard drive
        document.Load (Application.dataPath + "/Report/LocalReport.xml");
        // start a coroutine to send the XML file to the webserver
        StartCoroutine (sendData (document));
    } // Start

    private IEnumerator sendData (XmlDocument document) {
        // convert the XML document to an array of bytes
        char[] temp = document.OuterXml.ToCharArray();
        byte[] report = new byte[temp.Length];
        for (int i = 0; i < report.Length; i++) {
            report[i] = (byte) temp[i];
        } // for
        // send the data via web
        WWW www = new WWW ("http://DomainName/upload.php", report);
        // wait for the post completition
        while (![url]www.isDone[/url]) {
            Debug.Log ("I'm waiting... " + [url]www.uploadProgress[/url]);
            yield return new WaitForEndOfFrame();
        } // while
        // print the server answer on the debug log
        Debug.Log ([url]www.data[/url]);
        // destroy the www
        www.Dispose();
    } // sendData

} // ReportDataSender

the original file sent is:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE myapp[
	<!ELEMENT myapp (report)*>
	<!ELEMENT report (location, user, scene, subject, message)>
	<!ELEMENT location (#PCDATA)>
	<!ELEMENT user (#PCDATA)>
	<!ELEMENT scene (#PCDATA)>
	<!ELEMENT subject (#PCDATA)>
	<!ELEMENT message (#PCDATA)>
	<!ATTLIST myapp data CDATA #REQUIRED>
	<!ATTLIST report data CDATA #REQUIRED>]>
<myapp data="04/02/2009-18:19:47">
  <report data="04/02/2009-18:19:47">
    <location>My city</location>
    <user>My self</user>
    <scene>Level 1 (World 1)</scene>
    <subject>Comment</subject>
    <message>Thi level is awesome !!!</message>
  </report>
</myapp>

but instead of getting the file I sent, I got this thing:

Array
(
    [<?xml_version] => \"1.0\" encoding=\"UTF-8\"?><!DOCTYPE myapp[
	<!ELEMENT myapp (report)*>
	<!ELEMENT report (location, user, scene, subject, message)>
	<!ELEMENT location (#PCDATA)>
	<!ELEMENT user (#PCDATA)>
	<!ELEMENT scene (#PCDATA)>
	<!ELEMENT subject (#PCDATA)>
	<!ELEMENT message (#PCDATA)>
	<!ATTLIST myapp data CDATA #REQUIRED>
	<!ATTLIST report data CDATA #REQUIRED>]><myapp data=\"04/02/2009-18:19:47\"><report data=\"04/02/2009-18:19:47\"><location>My city</location><user>My self</user><scene>Level 1 (World 1)</scene><subject>Comment</subject><message>Thi level is awesome !!!</message></report></myapp>
)

I’ve to say that I know really nothing about PHP but I think that must be a Unity problem.
Can someone help me to try to understand what’s going on to solve this problem?

THANKS !!! :slight_smile:

EDIT: well… I have to say also that this is not an e-mail sending anymore, but directly, as you can guess, an XML post on a webserver !!!

No offense, but it seems like you’re greatly over complicating this. Why are you using XML?

WWWForm form = new WWWForm();
form.AddField("subject", "Email Subject");
form.AddField("body", "Hello!");
// ...

WWW www = new WWW("http://someurl.com", form);

And in PHP:

$subject = $_POST["subject"];
$body = $_POST["body"];