Sendgrid not sending email in an on demand azure webjob running as console application

545 views Asked by At

I have an on-demand azure webjob running as a console application.

Objective is send emails to customers.

Issue is it does not send emails.

My code is heavily lifted from msdn section How to: Send an Email. Following is my code snippet.

class Program
{
  static void Main(string[] args)
    {
Execute(Environment.GetEnvironmentVariable("WEBJOBS_COMMAND_ARGUMENTS")).Wait();
    }

    static async Task Execute(string email)
    {
        DeserializedCustomer customer = JsonConvert.DeserializeObject<DeserializedCustomer>(email);
        var apiKey = Environment.GetEnvironmentVariable("SENDGRID_APIKEY");
        var client = new SendGridClient(apiKey);
        SendGridMessage msg = new SendGridMessage()
        {
            From = new EmailAddress(customer.Email, "From Email"),
            Subject = $"Inquiry by - {customer.FirstName} {customer.LastName}",
            PlainTextContent = customer.Comments + Environment.NewLine + $"Phone : {customer.Phone}",
        };
        msg.AddTo(new EmailAddress(ToMail, ToMailName));

        if (!String.IsNullOrWhiteSpace(customer.Attachment))
        {
            List<Attachment> attachments = new List<Attachment>()
            {
                new Attachment()
                {
                    Content = customer.Attachment,
                    Type = customer.AttachmentType,
                    Filename = customer.AttachmentFileName,
                    Disposition = "inline",
                    ContentId = customer.AttachmentFileName + Guid.NewGuid()
                }
            };
            msg.Attachments = attachments;
        }
        await client.SendEmailAsync(msg);

    }
}

Searching I found an SO post where giving time to sendgrid to send email in a console application

Adding time did not help either.

If there are some quirkiness about sending emails from azure webjobs running as console applications then I'm unaware.

Searching further I found this SO post where they successfully tested sending emails in console application so I thought it might help but it did not send emails.

All the above examples are more than a year old and none of them work currently.

I tried using an earlier version of SendGrid library but I am stuck on

var transportWeb = new Web(credentials);
transportWeb.DeliverAsync(myMessage);

as SendGrid library has been updated.

On github I found this which clearly states that console apps only work with transportWeb.DeliverAsync(myMessage).Wait

therefore I am trying with transportWeb.

Is there an amalgamation of azure with on demand webjob running as console application?

Can anyone help?

Update

After Randy Minder's help I updated the code to the following

       static async Task Execute(string email)
    {
        try
        {

            DeserializedCustomer customer = new DeserializedCustomer();
            customer = JsonConvert.DeserializeObject<DeserializedCustomer>(email);
            Console.WriteLine(customer);
            SendGridMessage msg = new SendGridMessage();
            msg.From = new MailAddress(customer.EmailAddress, "From Email");
            msg.Subject = $"Inquiry by - {customer.FirstName} {customer.LastName}";
            msg.Text = customer.Comments + Environment.NewLine + $"Phone : {customer.Phone}";

            msg.AddTo(ToMail);

            // Create a network credentials object
            var credentials = new NetworkCredential(Environment.GetEnvironmentVariable("UserName"), Environment.GetEnvironmentVariable("Password"));

            var transportWeb = new SendGrid.Web(credentials);
            transportWeb.DeliverAsync(msg).Wait();
        }
        catch (Exception ex)
        {
            DateTime now = DateTime.Now;
            Trace.TraceError($"{now.ToLongDateString()} {now.ToLongTimeString()}" + Environment.NewLine + new ExceptionSerializer(ex));
        }
    }

I'm using SendGrid 6.1.0

 <package id="Sendgrid" version="6.1.0" targetFramework="net47" />

I do not get any exception and my webjob runs to success


[09/06/2017 17:48:42 > 1a8d37: SYS INFO] Run script 'SaSRizqTechCloudWhizEngineering.Backgr.exe' with script host - 'WindowsScriptHost'
[09/06/2017 17:48:42 > 1a8d37: SYS INFO] Status changed to Running
[09/06/2017 17:48:42 > 1a8d37: INFO] SerializedEmail - {"FirstName":"adsfkh","LastName":"adfkjladf","EmailAddress":"[email protected]","Phone":"","Comments":"lkjadf ","AttachmentType":"","AttachmentFileName":"","Attachment":null}
[09/06/2017 17:48:42 > 1a8d37: INFO] FirstName adsfkh - LastName adfkjladf - EmailAddress [email protected] - Phone  - Comments lkjadf  - Attachment  - AttachmentType -  - AttachmentFileName 
[09/06/2017 17:48:44 > 1a8d37: SYS INFO] Status changed to Success

However I do not get any email

2

There are 2 answers

4
Randy Minder On

When attempting to send an email via SendGrid in a console app, you have to do it a bit differently. Here is a method I have that works in a console app:

/// <summary>
/// Send the email async in a console app.
/// </summary>
public async Task SendAsync()
{
    // Create a network credentials object
    var credentials = new NetworkCredential(azureUserName, azurePassword);

    // Create an Web transport for sending the email
    var transportWeb = new Web(credentials);

    transportWeb.DeliverAsync(this._email).Wait();
}

This is what I use in a non-console app:

    /// <summary>
    /// Send the email async in backend or MVC code.
    /// </summary>
    public async Task SendAsync()
    {
        // Create a network credentials object
        var credentials = new NetworkCredential(azureUserName, azurePassword);

    // Create an Web transport for sending the email
    var transportWeb = new Web(credentials);

    await transportWeb.DeliverAsync(this._email).ConfigureAwait(false);
}

The actual email object is contained in this._email.

3
Brando Zhang On

According to your description, I have also create a test demo on my side, it works well. I used the sendgird SDK is 9.90.

The details codes is like as below:

class Program
{
    static void Main(string[] args)
    {

         string  serializedEmail = args[0];

        Console.WriteLine($"SerializedEmail - {serializedEmail}");

        Customer customer = JsonConvert.DeserializeObject<Customer>(args[0]);

        //Customer customer = new Customer() { Name = "aaaa" };
        Execute(customer).Wait();
        Console.WriteLine(customer.Name);
        Console.ReadLine();

    }


    static async Task Execute(Customer customer)
    {

        var client = new SendGridClient("apikey");
        var from = new EmailAddress("[email protected]", "Example User");
        var subject = "Sending with SendGrid is Fun";
        var to = new EmailAddress("[email protected]", "Example User");
        var plainTextContent = $"Name : {customer.Name}";
        var htmlContent = "<strong>and easy to do anywhere, even with C#</strong>";
        var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);
        var response = await client.SendEmailAsync(msg);
    }


}

public class Customer
{
    public string Name { get; set; }
}

However I do not get any email

I suggest you could firstly access this url to check the sendgird has already send the email to right email address.

The result is like this:

enter image description here