ارسال ایمیل در وب سایت با استفاده از سرویس gmail

6/30/2022 MVC Core
94

ارسال ایمیل با در وب سایت ها یک مطلب عادی است ، مثلا نیاز پیدا میکنیم که ایمیل در وب سایتی که با زبان برنامه نویسی  #C نوشته شده و با golan ویا هندل کردن ارسال ایمیل در قسمت بک اند نرم افزار زمانی که کاربر ثبت نام میکنم و یا در صفحه تماس با ما ایمیلی ارسال میکند ضروری خواهد بود .

شاید در پستهای قبلی هم خوانده باشید ، معمولا کمتر از کتایخانه ها استفاده میکنم مگر اینکه آن کتابخانه بسیار کار راه انداز باشد

برای کارهای که نیا به استفاده از یک کتابخانه بزرگتر باشد به اجبار  از کتابخانه ها استفاده کنیم ، در این پست قصدندارم در مورد مزایا و معایب کتابخانه ها صحبتی کرده باشم شاید پستی دیگر

برای ارسال در پروژ های های که قبلا با استفاده #C کد میزدم(الان بیشتر تمرکز روی گولنگ دارم) از خود SMTP استفاده میکردم و از آنجایی که یکی از رایج ترین سرویسهای ایمیل gmail هست از SMTP جی میل استفاده میکردم 

در حال حاضر خود ماکروسافت هم در مستنداات مربوط به netcore. توصیه میکند از mailkit استفاده شود

برای ارسال ایمیل در یکی از وب سایتهای از mailkit استفاده کردم در چند روز اول پس از ارسال مطالب مربوط به قسمت تماس با ما ایمیل به خوبی به سمت مدیر وب سایت ارسال میشد اما بعد از چند روز مدیر وب سایت اعلام کرد که زمانی کاربر بر روی دکمه ارسال  کلیک میکند با کد 500 موجهه میشود بررسی که کردم خطا به این صورت بود 

An unhandled exception occurred while processing the request.
SmtpCommandException: 5.7.8 Username and Password not accepted. Learn more at
5.7.8 https://support.google.com/mail/?p=BadCredentials e13-20020a05651c038d00b00258f1e0fb32sm2021766ljp.23 - gsmtp
Unknown location

AuthenticationException: 535: 5.7.8 Username and Password not accepted. Learn more at
5.7.8 https://support.google.com/mail/?p=BadCredentials e13-20020a05651c038d00b00258f1e0fb32sm2021766ljp.23 - gsmtp

خوب تا اینجا باید مربوط به سیستم امنیتی گوگل بوده باشد

گوگل برای ارسال ایمیل های ناتیفیکشن و ایمیلهایی که به صورت جمعی ارسال میشود و اگر از smtp استفاده  کنید گزینه مناسبی نیست 

بگذارید اینجا یک نکته دیگر هم بگم که:

ارسل ایمیل از سوی ایمیل های سازمانی نیز مستلزم تنظیمات زیادی در سرور هست،   که ایمیلی برای کاربر ارسال میشود به عنوان هرزنامه (spam) شناخته نشود که از حوصله این پست به در است 

من برای استفاده از mailkit این کدها رو نوشتم 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
using MimeKit.Text;
using Microsoft.Extensions.Options;


namespace Lib.Business
{
    public interface IEmailService
    {
        Task<string> SendEmailAsync(string recipientEmail, string recipientFirstName, string Link);
    }


    public class SmtpSettings
    {
        public string Server { get; set; }
        public int Port { get; set; }
        public string SenderName { get; set; }
        public string SenderEmail { get; set; }
        public string Password { get; set; }
    }
    public class EmailSenderService : IEmailService
    {
        private readonly SmtpSettings _smtpSettings;

        public EmailSenderService(IOptions<SmtpSettings> smtpSettings)
        {
            _smtpSettings = smtpSettings.Value;
        }
        /// <summary>
        /// send email to cinet use mailkit
        /// </summary>
        /// <param name="recipientEmail">to</param>
        /// <param name="recipientFirstName">recipiant Name</param>
        /// <param name="Link">link end of email text</param>
        /// <returns></returns>
        public async Task<string> SendEmailAsync(string recipientEmail, string recipientFirstName, string requerstCode)
        {
            var email = new MimeMessage();
            email.From.Add(MailboxAddress.Parse("myemail@gmail.com"));
            email.To.Add(MailboxAddress.Parse(recipientEmail));
            email.Subject = "پاسخ درخواست ....";
            email.Body = new TextPart(TextFormat.Html) { Text = "<h1>دریافت درخواست در سایت ...</h1>"+
               $"<p> درخواست شما با کد{requerstCode} دریافت گردید </p>"+
               "<p>پاسخ درخواست شما برای شما ایمیل خواهد شد</p>"+
               "<p>این ایمیل به صورت اتوماتیک برای شما ارسال شده است لطفا آن را پاسخ ندهید</p>"
            };

            // send email
            using var smtp = new SmtpClient();

            try
            {
                await smtp.ConnectAsync("smtp.gmail.com", 587, false);
                await smtp.AuthenticateAsync("myemail@gmail.com", "******");
                await smtp.SendAsync(email);
                await smtp.DisconnectAsync(true);

                return "email send successfully";
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                smtp.Dispose();
            }
            //smtp.ConnectAsync("smtp.gmail.com", 587, SecureSocketOptions.StartTls);

        }
    }
}

اگر کدهای بالا را نگاه کنید در قسمت password ما **** گذاشته ایم ، مشکل همینجاست 

در مرحله اول که خدمت شما عرض کردم من فقط در تنظیمات قسمت استفاده از نرم افزارهای خارجی برای دسترسی به ارسال ایمیل را تیک زده بودم و در کد ها مستقیم کلمه عبوری که برای استفاده از جی میل بود استفاده میشد، (فکر کنم این ایتم تازگی ها غیر فعال شده است)

راستش غیر فعال کردن این قسمت کار خوبی بود چون باید پسوورد ایمیل را در نرم افزار در دسترس دوستان دیگری که به کد دسترسی داشته اند قرار میدادم، از طرفی خود گول هم اعلام میکرد که این کار امنیت پایینی دارد

در بحث که خیلی وقت قبل هم فعال شده لازم بود تا برای هر نرم افزار خارجی شما کلمه عبور اختصاصی ایجاد کنیم که این مورد رو بیشتر میپسندیدم، این که نوشتم قبلا چون چند سال قبل هم برای استفاد gmail در outlook همین روش جدید را استفاده کردم 

مراحل به این صورت بود:

لازم بود تا وارد قسمت مدیریت حساب بشیم 

و در قسمت security و بعد apppasswords برای نرم افزار های که میخواهید با استفاده از gmail  ایمیل ارسال کنند کلمه عبور جدید اضافه کنید 

مطلب تکمیلی اینکه اگر appPassword برای شماغیر فعال است لازم است تا ورود دورحله ای را با استفاد از ادرس فعال کردن عبور دومرحله ای فعال کنید و سپس برای استفاده در پروژه از کلمه عبوری که ایجاد شده (بعد از انتخاب نوع نرم افزار ی که میخواهد از gmail شما استفاده کند کلمه عبور به صورت اتوماتیک برای شما ایجاد میشود  ) استفاده کنید

این کلمه عبور را در قسمت **** در کد بالا قرار دهید مشکل بر طرف خواهد شد