Email: Этот адрес электронной почты защищен от спам-ботов. У вас должен быть включен JavaScript для просмотра.

Добрый день.

В продолжение темы об отправке Email из Unity на C#

Универсальное решение для всех почтовых клиентов подсмотрел здесь.

 

public static void SendMessageWithEmbeddedImages()
{
  string htmlMessage = @"<html>
                         <body>
                         <img src='cid:EmbeddedContent_1' />
                         </body>
                         </html>";
  SmtpClient client = new SmtpClient("mail.server.com");
  MailMessage msg = new MailMessage("Этот адрес электронной почты защищен от спам-ботов. У вас должен быть включен JavaScript для просмотра.",
                                    "Этот адрес электронной почты защищен от спам-ботов. У вас должен быть включен JavaScript для просмотра.");
  // Создаем HTML view
  AlternateView htmlView = AlternateView.CreateAlternateViewFromString(
                                               htmlMessage,
                                               Encoding.UTF8,
                                               MediaTypeNames.Text.Html);
  // Создаем текстовую альтернативу для почтовых клиентов, не поддерживающих HTML
  AlternateView plainView = AlternateView.CreateAlternateViewFromString(
                                              Regex.Replace(htmlMessage,
                                                            "<[^>]+?>",
                                                            string.Empty),
                                              Encoding.UTF8,
                                              MediaTypeNames.Text.Plain);
  string mediaType = MediaTypeNames.Image.Jpeg;
  LinkedResource img = new LinkedResource(@"C:\Images\MyImage.jpg", mediaType);
  // Обязательно установите все эти значения!!!
  img.ContentId = "EmbeddedContent_1";
  img.ContentType.MediaType = mediaType;
  img.TransferEncoding = TransferEncoding.Base64;
  img.ContentType.Name = img.ContentId;
  img.ContentLink = new Uri("cid:" + img.ContentId);
  htmlView.LinkedResources.Add(img);
  //////////////////////////////////////////////////////////////
  msg.AlternateViews.Add(plainView);
  msg.AlternateViews.Add(htmlView);
  msg.IsBodyHtml = true;
  msg.Subject = "Some subject";
  client.Send(msg);
}
(629)
(0)

Unity отправка почты, в том числе и с мобильных устройств Android и iOS
Столкнулся недавно с казалось бы тривиальной задачей "сохранение данных из приложения и отправка их на email", которая не дала мне спать пару ночей, пока я с ней разбирался.

Итак по порядку...

Во первых программа должна сохранять файл.
В данном случае я для примера в процедуре Start() пишу CSV файл с тестовым набором данных.
Обратите внимание, что для сохранения файла желательно использовать путь Application.persistentDataPath, поскольку он указывает на пользовательскую папку Вашего приложения на любом устройстве и позволяет туда сохранять все что угодно.(подробнее здесь: https://docs.unity3d.com/ScriptReference/Application-persistentDataPath.html )

    void Start () {
        FileName = Application.persistentDataPath + "/fio.csv";
 
        string text = "Текст для проверки;2;3;"+System.DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss");
        string text1 = "Текст для проверки1;2;3";
        string text2 = "Текст для проверки2;2;3";
 
        try
        {
            StreamWriter sw = File.AppendText(FileName);
 
            sw.WriteLine(text);
            sw.WriteLine(text1);
            sw.WriteLine(text2);
 
            sw.Close();
        }
        catch (System.Exception e)
        {
            Debug.Log(e.ToString());
        }
 
    }

На сцене создаем UI->text (поле в которое будем выводить сообщение)
И кнопку на которую повесим функцию SendEmail()

	 public void SendEmail()
    {
        try
        {
            MailMessage mail = new MailMessage();
            SmtpClient SmtpServer = new SmtpClient("smtp.mail.ru", 25);
 
            mail.From = new MailAddress("вашапочта@mail.ru");
            mail.To.Add("почта_адресата@gmail.com");
 
            mail.Subject = "Test Mail from Unity";
            mail.Body = "This is for testing SMTP mail from Mail.ru";
 
            Attachment data = new Attachment(FileName, System.Net.Mime.MediaTypeNames.Application.Octet);
            // Add time stamp information for the file.
            System.Net.Mime.ContentDisposition disposition = data.ContentDisposition;
            disposition.CreationDate = System.IO.File.GetCreationTime(FileName);
            disposition.ModificationDate = System.IO.File.GetLastWriteTime(FileName);
            disposition.ReadDate = System.IO.File.GetLastAccessTime(FileName);
 
            mail.Attachments.Add(data);
 
            SmtpServer.Credentials = (ICredentialsByHost) new NetworkCredential("вашапочта@mail.ru", "ВашПароль");
 
            SmtpServer.EnableSsl = true;
            ServicePointManager.ServerCertificateValidationCallback =
                delegate (object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
                { return true; };
 
 
            SmtpServer.Send(mail);
 
            Debug.Log("mail Sent");
            GameObject.Find("Text").GetComponent<Text>().text = "mail Sent";
        }
        catch (Exception ex)
        {
            Debug.Log(ex.ToString());
            GameObject.Find("Text").GetComponent<Text>().text = ex.ToString();
        }
    }



Для того чтобы работала криптография и smtpsend, подключаем библиотеки

using System.IO;
using System.Net;
using System.Net.Mail;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System;
using UnityEngine.UI;


Первая проблема - с портами, у меня заработал только сервис mail.ru, поскольку поддерживает классический 25 порт.
По портам из помощи yandex'a и google'a не пошло.
(хотя в дальнейшем я разобрался, благодаря материалу на Хабре, чтобы работал 465 порт оставляете в SmtpClient 25 порт, затем пишете smtpClient.EnableSsl = true; тогда соединение устанавливается через 25 порт в незашифрованном виде, а затем переключается в защищенный режим.)

Готово, из самого Unity3D или windows-приложения все отправляется, но если собрать для мобильного устройства - не работает!

Получаем ошибку типа: Cannot implicitly convert type System.Net.NetworkCredential to System.Net.ICredentialsByHost

Дело в том, что для мобильного устройства по умолчанию собирается с .Net 2.0 Subset (это сделано для уменьшения размера собранного приложения, за счет отказа от ненужных функций фреймворка).

Таким образом нам нужно зайти в настройки плеера и поменять Api Compatibility Level на .Net 2.0. (File->Build Settings->Player Settings->Api Compatibility Level)

Ок. Теперь работает на Android. Из под iOS все равно не отправляется.
Получаем ошибку:
MissingMethodException: Method not found: 'Default constructor not found...ctor() of System.Net.Configuration.MailSettingsSectionGroup'

Оказывается это известный баг с 2015 года, который до сих пор не пофиксили: https://issuetracker.unity3d.com/issues/il2cpp-crashes-when-using-smtpclient

Решение простое: создать в корне папки assets файл link.xml со следующим содержимым:
<linker> <assembly fullname="System"> <type fullname="System.Net.Configuration.MailSettingsSectionGroup" preserve="all"/> <type fullname="System.Net.Configuration.SmtpSection" preserve="all"/> <type fullname="System.Net.Configuration.SmtpNetworkElement" preserve="all"/> <type fullname="System.Net.Configuration.SmtpSpecifiedPickupDirectoryElement" preserve="all"/> </assembly> </linker>

обратите внимание, если Вы возьмете этот код из приведенной ссылки на issuetracker - там в слове SmtpSpecifiedPickupDirectoryElement в слове Directory между t и o какой то какой то странный символ и с ним ничего не работает, поэтому лучше скопируйте у меня, либо скачайте у меня же готовый файл.

Пересоберите проект и все должно запуститься.
Если у Вас есть, что добавить - пишите в комментариях.

 

(3097)
(5)