Azure Function SendGrid

1.7k Views Asked by At

Hi I'm basically executing a query which returns x amount of emails that exist on a specific day and I want to send an email to all of these emails using sendgrid's api here is my code - I am running into alot of errors listed below could anyone shed some light?

[code]

**#r "System.Data"
#r "SendGrid"

using System;
using System.Data;
using SendGrid.Helpers.Mail;

using System.Data.SqlClient;
using System.Text.RegularExpressions;
using Microsoft.SqlServer.Server;
using SendGrid;

        private SqlConnection conn = null;
        private SqlDataAdapter da = null;
        private SqlCommandBuilder cb = null;
        private DataSet ds = null;
        private String location = null;

public void Run(TimerInfo myTimer, TraceWriter log)
    {
        log.Info($"C# Timer trigger function executed at: {DateTime.Now}");
        string connStr = "Data Source=sdc-hwsb.database.windows.net;Initial Catalog=SDC-HotelWSBooking;Integrated Security=False;User ID=sdchwsb;Password=Trivago17!;Connect Timeout=15;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False";
        SqlConnection conn = new SqlConnection(connStr);
        conn.Open();
        string query = "SELECT email FROM dbo.test_bookings2 WHERE startDate = @startDate";
        SqlCommand cmd = new SqlCommand(query, conn);
        cmd.Parameters.AddWithValue("@startDate", DateTime.Today.ToShortDateString());
        int k = 0;
        int f = Convert.ToInt32(cmd.ExecuteNonQuery());
        while (f > 0 & k < f)
        {
            conn = new SqlConnection(connStr);
            da = new SqlDataAdapter(query, conn);
            cb = new SqlCommandBuilder(da);
            ds = new DataSet();
            da.Fill(ds);
            String Email = Convert.ToString(ds.Tables[0].Rows[k]);
            Run1(Email,message);
            k++;

        }

    }


    public static void Run1(string email, out Mail message)
{
      message = new Mail
        {        
        Subject = "Azure news"          
    };
var personalization = new Personalization();
// change to email of recipient
personalization.AddTo(new Email(email));   

Content content = new Content
{
    Type = "text/plain",
    Value = "DD"
};
message.AddContent(content);
message.AddPersonalization(personalization);

}

**

I Am getting errors reffering to the Message object sendgrid is using such as:

    2017-09-25T18:50:37.754 Function started (Id=067b32b9-7bc3-47ca-9f32-b8b92c3b57e9)
2017-09-25T18:50:37.770 Function compilation error
2017-09-25T18:50:37.770 run.csx(38,28): error CS0103: The name 'message' does not exist in the current context
2017-09-25T18:50:37.807 Exception while executing function: Functions.TimerTriggerCSharp1. Microsoft.Azure.WebJobs.Script: Script compilation failed.
2017-09-25T18:50:37.948 Function completed (Failure, Id=067b32b9-7bc3-47ca-9f32-b8b92c3b57e9, Duration=196ms)
2

There are 2 best solutions below

7
On

Some of those errors are compilation errors - fix those first. For example, you're missing a ')' on line 28.

You can also author functions in Visual Studio - which will give you the power of a real IDE with C# intellisense and error checking. That would catch the errors above. That's useful as soon as your functions are non-trivial. Check out details here: https://blogs.msdn.microsoft.com/appserviceteam/2017/08/14/azure-functions-tools-released-for-visual-studio-2017-update-3/

The SendGrid binding should be on your Run() function.

public void Run(TimerInfo myTimer, TraceWriter log, out Mail message)

And then Run1 is just an internal helper to generate the message.

If you need to send multiple messages, use ICollector / IAsyncCollector. That has an 'add' method.

0
On

As Mike S mentioned about sending multiple emails via use an ICollector, I checked the official document about SendGrid output binding and did not find any sample, then I followed the code sample from Queue output sample in C# to test this feature as follows:

run.csx

#r "SendGrid"

using System;
using SendGrid.Helpers.Mail;

public static void Run(TimerInfo myTimer, TraceWriter log, ICollector<Mail> mails)
{
    log.Info($"C# Timer trigger function executed at: {DateTime.Now}");

    for(int i=0;i<3;i++)
    {
        Mail message = new Mail()
        {
            Subject = $"Hello world from the SendGrid C# TimerTrigger!"
        };

        var personalization = new Personalization();
        personalization.AddTo(new Email("the-email-address-of-recipient"));  

        Content content = new Content
        {
            Type = "text/plain",
            Value = $"Hello world!{i}"
        };

        message.AddContent(content);  
        message.AddPersonalization(personalization); 
        mails.Add(message);
    }
}

function.json

{
  "bindings": [
    {
      "name": "myTimer",
      "type": "timerTrigger",
      "direction": "in",
      "schedule": "0 */5 * * * *"
    },
    {
      "type": "sendGrid",
      "name": "mails",
      "apiKey": "sendgrid-apikey",
      "direction": "out",
      "from":"<the-email-address-of-sender>"
    }
  ],
  "disabled": false
}

Result:

enter image description here

Additionally, for creating Functions class library project via VS2017, you could refer to this tutorial about SendGrid output.