fsander wrote:Hello,
I have a plugin that is a custom form. After the customer fills in he will receive a personalized email as an example "Thank you for your registration". Can you help me with this?
why isn't you using default project code to send email?
for example, i am sending one email to customer and one email to store owner from plugin from custom contact us form submit
1. first insert one message template while install the plugin
/// <summary>
/// Install the plugin
/// </summary>
/// <returns>A task that represents the asynchronous operation</returns>
public override async Task InstallAsync()
{
var eaGeneral = _emailAccountRepository.Table.FirstOrDefault();
if (eaGeneral == null)
throw new Exception("Default email account cannot be loaded");
//settings
var settings = new ContactCallUsSettings
{
EnableCallUs = true,
EnableContactUs = true
};
await _settingService.SaveSettingAsync(settings);
//store owner email template
var templates = (await _messageTemplateService.GetMessageTemplatesByNameAsync(ContactCallUsDefaults.StoreOwnerEmailTemplateSystemName)).FirstOrDefault();
var template = new MessageTemplate
{
Name = ContactCallUsDefaults.StoreOwnerEmailTemplateSystemName,
Subject = "%Message.Subject%",
Body = $"<p>Product Name: %ContactCallUs.ProductName%<br/>Sku: %ContactCallUs.Sku%<br/>Name: %ContactCallUs.Name%<br/>Company Name: %ContactCallUs.CompanyName%" +
$"<br/>Phone: %ContactCallUs.Phone%<br/>Email: %ContactCallUs.Email%<br/>Comment: %ContactCallUs.Message%<br/></p>{Environment.NewLine}",
IsActive = true,
EmailAccountId = eaGeneral.Id
};
if (templates == null)
await _messageTemplateService.InsertMessageTemplateAsync(template);
else
throw new NopException("Message Template Already Exist");
//customer email template
templates = (await _messageTemplateService.GetMessageTemplatesByNameAsync(ContactCallUsDefaults.CustomerEmailTemplateSystemName)).FirstOrDefault();
template = new MessageTemplate
{
Name = ContactCallUsDefaults.CustomerEmailTemplateSystemName,
Subject = "%Message.Subject%",
Body = $"Your request is submitted for <br/><p>Product Name: %ContactCallUs.ProductName%<br/>Sku: %ContactCallUs.Sku%</p>{Environment.NewLine}",
IsActive = true,
EmailAccountId = eaGeneral.Id
};
if (templates == null)
await _messageTemplateService.InsertMessageTemplateAsync(template);
else
throw new NopException("Message Template Already Exist");
//.... your more insertion
await base.InstallAsync();
}
2. create your service that contain mail sending code
#region mail
public virtual async Task<IList<int>> SendContactCallUsMessageToStoreOwnerAsync(int languageId, string senderEmail,
string senderName, string subject, ContactCallUsRecordsModel callbackModel)
{
var model = callbackModel.ToEntity<ContactCallUsRecords>();
var store = await _storeContext.GetCurrentStoreAsync();
languageId = await EnsureLanguageIsActiveAsync(languageId, store.Id);
var product = await _productService.GetProductByIdAsync(callbackModel.ProductId);
var messageTemplates = await GetActiveMessageTemplatesAsync(ContactCallUsDefaults.StoreOwnerEmailTemplateSystemName, store.Id);
if (!messageTemplates.Any())
return new List<int>();
//tokens
var commonTokens = new List<Token>
{
new Token("ContactUs.SenderEmail", senderEmail),
new Token("ContactUs.SenderName", senderName),
new Token("Message.Subject", subject, true),
new Token("ContactCallUs.ProductName", product.Name),
new Token("ContactCallUs.Sku", product.Sku),
new Token("ContactCallUs.Name", callbackModel.Name ),
new Token("ContactCallUs.Phone", callbackModel.Phone),
new Token("ContactCallUs.CompanyName", callbackModel.CompanyName),
new Token("ContactCallUs.Email", callbackModel.Email),
new Token("ContactCallUs.Message", callbackModel.Message)
};
return await messageTemplates.SelectAwait(async messageTemplate =>
{
//email account
var emailAccount = await GetEmailAccountOfMessageTemplateAsync(messageTemplate, languageId);
var toEmail = emailAccount.Email;
var toName = emailAccount.DisplayName;
return await SendNotificationAsync(messageTemplate, emailAccount, languageId, commonTokens, toEmail, toName,
fromEmail: senderEmail,
fromName: senderName,
subject: subject,
replyToEmailAddress: senderEmail,
replyToName: senderName);
}).ToListAsync();
}
public virtual async Task<IList<int>> SendContactCallUsMessageToCustomerAsync(int languageId, string senderEmail,
string senderName, string subject, ContactCallUsRecordsModel callbackModel)
{
var model = callbackModel.ToEntity<ContactCallUsRecords>();
var store = await _storeContext.GetCurrentStoreAsync();
languageId = await EnsureLanguageIsActiveAsync(languageId, store.Id);
var product = await _productService.GetProductByIdAsync(callbackModel.ProductId);
var messageTemplates = await GetActiveMessageTemplatesAsync(ContactCallUsDefaults.CustomerEmailTemplateSystemName, store.Id);
if (!messageTemplates.Any())
return new List<int>();
//tokens
var commonTokens = new List<Token>
{
new Token("ContactUs.SenderEmail", senderEmail),
new Token("ContactUs.SenderName", senderName),
new Token("Message.Subject", subject, true),
new Token("ContactCallUs.ProductName", product.Name),
new Token("ContactCallUs.Sku", product.Sku),
new Token("ContactCallUs.Name", callbackModel.Name ),
new Token("ContactCallUs.Phone", callbackModel.Phone),
new Token("ContactCallUs.CompanyName", callbackModel.CompanyName),
new Token("ContactCallUs.Email", callbackModel.Email),
new Token("ContactCallUs.Message", callbackModel.Message)
};
return await messageTemplates.SelectAwait(async messageTemplate =>
{
//email account
var emailAccount = await GetEmailAccountOfMessageTemplateAsync(messageTemplate, languageId);
return await SendNotificationAsync(messageTemplate, emailAccount, languageId, commonTokens, senderEmail, senderName,
fromEmail: emailAccount.Email,
fromName: emailAccount.DisplayName,
subject: subject,
replyToEmailAddress: emailAccount.Email,
replyToName: emailAccount.DisplayName);
}).ToListAsync();
}
public virtual async Task<int> EnsureLanguageIsActiveAsync(int languageId, int storeId)
{
//load language by specified ID
var language = await _languageService.GetLanguageByIdAsync(languageId);
if (language == null || !language.Published)
{
//load any language from the specified store
language = (await _languageService.GetAllLanguagesAsync(storeId: storeId)).FirstOrDefault();
}
if (language == null || !language.Published)
{
//load any language
language = (await _languageService.GetAllLanguagesAsync()).FirstOrDefault();
}
if (language == null)
throw new Exception("No active language could be loaded");
return language.Id;
}
public virtual async Task<EmailAccount> GetEmailAccountOfMessageTemplateAsync(MessageTemplate messageTemplate, int languageId)
{
var emailAccountId = await _localizationService.GetLocalizedAsync(messageTemplate, mt => mt.EmailAccountId, languageId);
//some 0 validation (for localizable "Email account" dropdownlist which saves 0 if "Standard" value is chosen)
if (emailAccountId == 0)
emailAccountId = messageTemplate.EmailAccountId;
var emailAccount = (await _emailAccountService.GetEmailAccountByIdAsync(emailAccountId) ?? await _emailAccountService.GetEmailAccountByIdAsync(_emailAccountSettings.DefaultEmailAccountId)) ??
(await _emailAccountService.GetAllEmailAccountsAsync()).FirstOrDefault();
return emailAccount;
}
public virtual async Task<IList<MessageTemplate>> GetActiveMessageTemplatesAsync(string messageTemplateName, int storeId)
{
//get message templates by the name
var messageTemplates = await _messageTemplateService.GetMessageTemplatesByNameAsync(messageTemplateName, storeId);
//no template found
if (!messageTemplates?.Any() ?? true)
return new List<MessageTemplate>();
//filter active templates
messageTemplates = messageTemplates.Where(messageTemplate => messageTemplate.IsActive).ToList();
return messageTemplates;
}
public virtual async Task<int> SendNotificationAsync(MessageTemplate messageTemplate,
EmailAccount emailAccount, int languageId, IList<Token> tokens,
string toEmailAddress, string toName,
string attachmentFilePath = null, string attachmentFileName = null,
string replyToEmailAddress = null, string replyToName = null,
string fromEmail = null, string fromName = null, string subject = null)
{
if (messageTemplate == null)
throw new ArgumentNullException(nameof(messageTemplate));
if (emailAccount == null)
throw new ArgumentNullException(nameof(emailAccount));
//retrieve localized message template data
var bcc = await _localizationService.GetLocalizedAsync(messageTemplate, mt => mt.BccEmailAddresses, languageId);
if (string.IsNullOrEmpty(subject))
subject = await _localizationService.GetLocalizedAsync(messageTemplate, mt => mt.Subject, languageId);
var body = await _localizationService.GetLocalizedAsync(messageTemplate, mt => mt.Body, languageId);
//Replace subject and body tokens
var subjectReplaced = _tokenizer.Replace(subject, tokens, false);
var bodyReplaced = _tokenizer.Replace(body, tokens, true);
//limit name length
toName = CommonHelper.EnsureMaximumLength(toName, 300);
var email = new QueuedEmail
{
Priority = QueuedEmailPriority.High,
From = !string.IsNullOrEmpty(fromEmail) ? fromEmail : emailAccount.Email,
FromName = !string.IsNullOrEmpty(fromName) ? fromName : emailAccount.DisplayName,
To = toEmailAddress,
ToName = toName,
ReplyTo = replyToEmailAddress,
ReplyToName = replyToName,
CC = string.Empty,
Bcc = bcc,
Subject = subjectReplaced,
Body = bodyReplaced,
AttachmentFilePath = attachmentFilePath,
AttachmentFileName = attachmentFileName,
AttachedDownloadId = messageTemplate.AttachedDownloadId,
CreatedOnUtc = DateTime.UtcNow,
EmailAccountId = emailAccount.Id,
DontSendBeforeDateUtc = !messageTemplate.DelayBeforeSend.HasValue ? null
: (DateTime?)(DateTime.UtcNow + TimeSpan.FromHours(messageTemplate.DelayPeriod.ToHours(messageTemplate.DelayBeforeSend.Value)))
};
await _queuedEmailService.InsertQueuedEmailAsync(email);
return email.Id;
}
#endregion
3. make your controller to call service
[HttpPost]
public virtual async Task<IActionResult> InsertContactCallUs(ContactCallUsRecordsModel contactCallUsModel)
{
if (ModelState.IsValid)
{
var model = contactCallUsModel.ToEntity<ContactCallUsRecords>();
await _contactCallUsService.InsertRequestAsync(model);
contactCallUsModel.Message = _contactCallUsService.FormatPostText(contactCallUsModel.Message);
SendingMessage(contactCallUsModel);
}
return Ok(contactCallUsModel);
}
public virtual async void SendingMessage(ContactCallUsRecordsModel contactCallUsModel)
{
if (ModelState.IsValid)
{
var subject =
subject = await _localizationService.GetResourceAsync("OwnerEmail.Subject");
//send email to store owner
await _contactCallUsService.SendContactCallUsMessageToStoreOwnerAsync((await _workContext.GetWorkingLanguageAsync()).Id,
contactCallUsModel.Email.Trim(), contactCallUsModel.Name , subject, contactCallUsModel);
//send email to customer
await _contactCallUsService.SendContactCallUsMessageToCustomerAsync((await _workContext.GetWorkingLanguageAsync()).Id,
contactCallUsModel.Email.Trim(), contactCallUsModel.Name, await _localizationService.GetResourceAsync("CustomerMail.Subject"), contactCallUsModel);
}
}