Search code examples
c#google-apigmail-api

Obtaining Google e-mail signature block for signed-in user using c#


Converting a VB.Net application to c#. Having an issue with the following code. The function authenticates a user with the Google web service and attempts to obtain the user's e-mail address and signature block to be used in later code.

In VB.Net this all seems to work correctly. In c#, the line foreach (var itm in result.SendAs) generates an error

'Func' does not contain a definition for 'SendAs' and no accessible extension method 'SendAs' accepting a first argument of type 'Func' could be found.

What am I missing?

    using System;
    using System.IO;
    using System.Threading;
    using System.Threading.Tasks;
    using Google.Apis.Auth.OAuth2;
    using Google.Apis.Calendar.v3;
    using Google.Apis.Calendar.v3.Data;
    using Google.Apis.Gmail.v1;
    using Google.Apis.Services;
    using Google.Apis.Util.Store;
    ...

public static async Task<bool> DoAuthenticationAsync()
    {
        ClientSecrets secrets;

        using (var strm = new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
        {
            secrets = GoogleClientSecrets.FromStream(strm).Secrets;
        }

        try
        {

            // this is the magic black box that does the authenticating.
            Common.credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(secrets, Common.googleScopes, "user", CancellationToken.None, new FileDataStore("Google.API.Auth", false));

            var init = new BaseClientService.Initializer();
            init.HttpClientInitializer = Common.credential;

            var svc = new GmailService(init);

            // this grabs the list of all e-mail aliases for the signed-in user and selects the primary
            var result = svc.Users.Settings.SendAs.List("me").Execute;

            foreach (var itm in result.SendAs)
            {
                if (itm.IsPrimary.HasValue)
                {
                    if (itm.IsPrimary)
                    {
                        // save as the signature blob to use.
                        Common.mySignature = itm.Signature;
                        Common.myEMail = itm.SendAsEmail;
                        break;
                    }
                }
            }
        }
        catch (Exception)
        {
            return false;
        }

        return true;
    }

Solution

  • Not entirely sure why this works, but, I modified the above code block by as follows and the problem resolved itself.

       public static async Task<bool> DoAuthenticationAsync()
    {
        ClientSecrets secrets;
    
        // this obtains the application secrets data we need to indicate our application is asking to authenticate.
        using (var strm = new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
        {
            secrets = GoogleClientSecrets.FromStream(strm).Secrets;
        }
    
        try
        {
    
            // this is the magic black box that does the authenticating.
            Common.credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(secrets, Common.googleScopes, "user", CancellationToken.None, new FileDataStore("Google.API.Auth", false));
    
            var init = new BaseClientService.Initializer();
            init.HttpClientInitializer = Common.credential;
    
            var svc = new GmailService(init);
    
            // this grabs the list of all e-mail aliases for the signed-in user and selects the primary
            ListSendAsResponse result = svc.Users.Settings.SendAs.List("me").Execute();
    
            foreach (SendAs itm in result.SendAs)
            {
                if (itm.IsPrimary.HasValue)
                {
                    if (itm.IsPrimary == true)
                    {
                        // save as the signature blob to use.
                        Common.mySignature = itm.Signature;
                        Common.myEMail = itm.SendAsEmail;
                        break;
                    }
                }
            }
        }
        catch (Exception)
        {
            return false;
        }
    
        return true;
    }
    

    This change is simply a forcing of a couple variables into concrete types instead of using the "var" declarations.