Archivo de la etiqueta: c-sharp

Obtener las IPs (IPv4 e IPv6) del usuario y mostrar solo las IPv4 usando .NET (Core) [Código para Visual Basic y C#]

Pues eso… aquí tienes un ejemplo que son 2 (o cuatro si tenemos en cuenta que el código que te voy a mostrar es tanto para Visual Basic como para C#/CSharp) y es para obtener las IPs del usuario (o donde se ejecute el código) y de esas IPs (que contendrá las IPv6 y las IPv4) extraer solo las IPv4.

Este código utiliza expresiones regulares (RegEx) y por tanto necesitas añadir una importación del espacio de nombres System.Text.RegularExpressions, también utiliza métodos para acceder al nombre del equipo (host name) y obtener las direcciones IP, por tanto, necesitarás una importación al espacio de nombres System.Net.

Este código sirve tanto para aplicaciones de escritorio (los ejemplos están hechos para aplicaciones de consola para todas las plataformas), aplicaciones móviles y aplicaciones WEB.

Yo lo he probado en las dos primeras, y cuando lo haga en la tercera, te mostraré el código usado (o lo pondré en el repositorio de GitHub que crearé para poner el código de ejemplo) y las cosas que debas tener en cuenta, siempre y cuando tengas algo que tener en cuenta 😉

Nota 01-sep-2021:
Ya he publicado una página ASPX (asp-net) para probar el código.
Para esa página he creado una DLL con idea de ponerla en el directorio BIN del hosting donde tengo alojado «mi sitio» www.elguille.info.
En GitHub también está el código de esa DLL (del proyecto, que en este caso lo he creado con VB).
Este es el enlace de la página de prueba: ComoNET: Utils IP (.NET Core) (elguille.info)

Nota:
Las dos funciones principales: la que obtiene las IPs y la otra que extrae las IPv4 de esas IPs están en una clase estática (compartida sería en VB, pero en este caso no es necesario indicar Shared) con métodos estáticos (así debe ser en C#), esos métodos en Visual Basic están declarados con Shared, mientras que en C# se utiliza static.

En realidad, en Visual Basic podría haber usado un módulo (Module) en vez de una clase y definir expresamente los métodos de forma compartida, pero la diferencia de declarar los métodos como compartidos en una clase y usar esos métodos desde un módulo es que «tras las bambalinas» hay más código si se define un módulo. Me refiero al código IL generado, aunque en realidad solo hay más código en el constructor del módulo, ya que el código IL de los métodos es el mismo en ambos casos.
Después te pongo algo sobre esto (seguramente en otro post).

Otro detalle es que en la medida de lo posible he usado declaraciones de variables explícitas en lugar de usar inferencia de tipos, para que así te resulte más fácil ver (o saber) de qué tipo de datos estoy hablando (o utilizando).

Obtener las direcciones IP del usuario actual

En esta primera parte del ejemplo, echaremos mano de los métodos GetHostName y GetHostAddresses de la clase Dns definida en System.Net.

El nombre del host es necesario para saber las IPs, ya que GetHostAddresses utiliza el nombre del host (¿anfitrión?), pero mejor ve el código y después ya veremos si hay algo que aclarar.

Empiezo con el de C# y después te muestro el de Visual Basic.

public static string ObtenerIPs()
{
    StringBuilder sb = new StringBuilder();
    string ipAddresses;

    try
    {
        var hostName = Dns.GetHostName();
        IPAddress[] addresses = Dns.GetHostAddresses(hostName);

        foreach (IPAddress address in addresses)
            sb.Append($"{address}, ");

        ipAddresses = sb.ToString().TrimEnd(", ".ToCharArray());
    }
    catch (Exception ex)
    {
        ipAddresses = "ERROR: " + ex.Message;
    }
    return ipAddresses;
}

 

Public Shared Function ObtenerIPs()

    Dim sb As New StringBuilder()
    Dim ipAddresses As String

    Try
        Dim hostName = Dns.GetHostName()
        Dim addresses As IPAddress() = Dns.GetHostAddresses(hostName)

        For Each address As IPAddress In addresses
            sb.Append($"{address}, ")
        Next

        ipAddresses = sb.ToString().TrimEnd(", ".ToCharArray())
    Catch ex As Exception
        ipAddresses = "ERROR: " & ex.Message
    End Try
    Return ipAddresses
End Function

 

Un par de cosas (tips) a destacar de ese código:
1- La variable addresses es un array del tipo IPAddress, para obtener cada una de las direcciones IP utilizo un bucle foreach (For Each) y las agrego al StringBuilder (por aquello de que consume menos recursos que si las concateno).
2- Como le voy añadiendo a cada IP una coma y un espacio al final (para separarlas), es necesario quitar esa coma del final, para ello utilizo TrimEnd() indicándole qué caracteres quiero quitar del final. Los caracteres indicados al método de la familia Trim deben ser caracteres, no una cadena, por eso utilizo una cadena con los caracteres a quitar del final y la convierto en array de tipo Char con ToCharArray.

Extraer las IPv4 de una cadena con otras cosas usando expresiones regulares

En el método que se encarga de hacer eso, utilizo la clase RegEx para mediante una cadena con «expresiones regulares» (que resultan ser buenas y no regulares 😉 ) y los casos en que ha tenido éxito, los voy agregando a un StringBuilder que después usaré (tras quitar lo que no haya que usar) para devolver como resultado de las direcciones IPv4 de esa cadena entrante.

El código regex para obtener las IPv4 lo he adaptado de un ejemplo del sitio programador clic: Expresión regular de dirección IP.

Aquí tienes el código de ese método para Visual Basic y C#.

Public Shared Function LasIPv4(ipAdresses As String) As String
    Dim sb As New StringBuilder()

    Dim sRegExIPv4 As String = "((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)"
    Dim r As Regex = New Regex(sRegExIPv4)

    For Each m As Match In r.Matches(ipAdresses)
        If m.Success Then
            sb.Append($"{m.Value}, ")
        End If
    Next

    Return sb.ToString().TrimEnd(", ".ToCharArray())
End Function

 

public static string LasIPv4(string ipAdresses)
{
    StringBuilder sb = new();

    string sRegExIPv4 = @"((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)";
    Regex r = new Regex(sRegExIPv4);
    foreach (Match m in r.Matches(ipAdresses))
    {
        if(m.Success)
        {
            sb.Append($"{m.Value}, ");
        }
    }

    return sb.ToString().TrimEnd(", ".ToCharArray());
}

Y esto es todo… ¡Ah! ¡No! que falta el código de cómo usar estos dos métodos.

Cómo usar los métodos anteriores

Eso está en el método Main del «programa» de consola.

Aquí tienes el método Main que los utiliza.

static void Main(string[] args)
{
    //Console.WriteLine("Hello World!");
    Console.WriteLine("Ejemplo en C# usando .NET 5.0 para obtener las IPs y extraer con RegEx solo las IPv4.");
    Console.WriteLine();

    string ipAdresses = Utils.ObtenerIPs();

    Console.WriteLine("La cadena con todas las IPs:");
    Console.WriteLine(ipAdresses);
    string ret = Utils.LasIPv4(ipAdresses);

    Console.WriteLine();
    Console.WriteLine("Direcciones IPv4:");
    Console.WriteLine(ret);

    Console.WriteLine();
    Console.WriteLine("Pulsa INTRO para terminar.");
    Console.ReadLine();
}

 

Sub Main(args As String())
    'Console.WriteLine("Hello World!")
    Console.WriteLine("Ejemplo en Visual Basic usando .NET 5.0 para obtener las IPs y extraer con RegEx solo las IPv4.")
    Console.WriteLine()

    Dim ipAdresses As String = Utils.ObtenerIPs()

    Console.WriteLine("La cadena con todas las IPs:")
    Console.WriteLine(ipAdresses)
    Dim ret As String = Utils.LasIPv4(ipAdresses)

    Console.WriteLine()
    Console.WriteLine("Direcciones IPv4:")
    Console.WriteLine(ret)

    Console.WriteLine()
    Console.WriteLine("Pulsa INTRO para terminar.")
    Console.ReadLine()
End Sub

 

Aquí te dejo una captura del programa en ejecución.

 

Ahora sí, esto ha sido todo amigos… 😉

Nos vemos.
Guillermo

P.S.
Aquí tienes el enlace al repositorio de GitHub con el código de ejemplo completo, tanto para Visual Basic como C# (con sus proyectos respectivos para usar con Visual Studio 2019 o superior, incluso puede que anterior, pero no lo he comprobado).
elGuille-info/Obtener-IP-y-extraer-IPv4: Ejemplo en C# y Visual Basic de cómo obtener las IP (IPv4 e IPv6) y extraer solo las IPv4 (github.com)

Acceder a la página maestra (Master page) desde una página en ASP.NET para .NET Framework (con C# y VB)

Pues eso… el otro día estaba escribiendo código para un nuevo sitio web de un colega (ConservasYoga.com.es) y me decidí a hacerlo en C# , por aquello de que creía que ya no existen plantillas (o eso creo ) en Visual Studio 2019 para ASP.NET con Visual Basic, pero sí existen, de las que no existen es para usar ASP.NET Core.

La cuestión es que quería acceder a ciertas propiedades (y/o métodos) de la master page y lo hice (o lo intenté) tal como lo hago con Visual Basic, es decir, usando Master.Propiedad, pero nada… daba error… después de muchas pruebas lo conseguí… algo rebuscado, pero… probando, probando… lo pude encontrar, y es que en C# para acceder a las cosas definidas en una página maestra hay que usar el nombre de la página maestra (en minúsculas) seguida de un guón bajo y la palabra master (también en minúsculas), es decir, si la página maestra se llama Site.master para acceder al código desde C# hay que usarlo de esta forma: site_master.

Un ejemplo de sitio usando Master Page en VB y C#

Para este ejemplo he optado por seleccionar un sitio en blanco: ASP.NET Empty Web Site (ver figura 1), ya que si se elige el tipo ASP.NET Web Forms Site te añade un montón de código y página, etc., que… en los hosting de ASP.NET que hay por esta zona no funcionan… y si intento que sea de ASP.NET Core ya ni te digo, ninguna de las empresas de hosting con las que he probado (Axarnet, IONOS, acens) lo soportan, incluso una de ellas me dijo que como es código abierto por eso no lo soportan… pero sí venden servidores con Linux, WordPress, PHP… que… ¡lo mismo no son de código abierto! 😉

En fin…

Figura 1. Crear un nuevo proyecto de C# (Empty Web Site)

Cuando trabajo con sitios de ASP.NET no me gusta usar el code behind, si no que prefiero que cada página tenga su código, de esa forma no es necesario compilar la aplicación, si no que se usa el código directamente en el sitio hospedado y ya está… el ASP.NET de IIS se encarga de compilar las páginas y el código a usar. Y lo mejor es que si haces cambios, solo tienes que subir la página o el fichero de código modificado y ya está… ¡a compilarlo tocan! pero… ¡que lo compile otro! 😉

En el segundo tipo de proyecto todo lo que añade el Visual Studio usa el code behind, mientras que en el proyecto vacío, cuando añadas una nueva página (maestra o normal) puedes indicar que no se incluya el código de forma separada (que es lo que viene a significar el code behind o separación entre el diseño y el código).

Si elegimos añadir una nueva página con el código incrustado en la propia página tendremos que hacer algo como lo mostrado en la figura 2.

Figura 2. Añadir nueva página con el código separado de la página aspx

En ese caso, se indica también seleccionar una página maestra para esa página aspx.

Y si decidimos que el código esté separado lo haremos como se muestra en la figura 3.

Figura 3. Nueva página con el código en la propia página.

Es decir, quitamos la marca de la casilla Place code in separate file.

Al añadir una página de esa forma tendremos esto en la página:

<% @ Page Title="" Language="VB" MasterPageFile="~/MasterPage.master" AutoEventWireup="false" 
    CodeFile="Prueba.aspx.vb" Inherits="Prueba" %>

Donde CodeFile indica qué página es la que tiene el código y el Inherits es el nombre de la clase.

Si esto lo has hecho por error… puedes arreglarlo.
¿Cómo?
Simplemente quitando todo lo que se indica en CodeFile y en Inherits y poniendo el código aparte, tal como te muestro a continuación:

<% @ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master"  %>

<script runat="server">

</script>

Nota:
Por cierto, esa página la he añadido al proyecto de C#, pero está usando el código de VB, y es porque yo, por error, he seleccionado una página de Visual Basic (tal como ves en la figura 3).
Pero en el código mostrado lo he cambiado a C#.

Decir o aclarar que en un sitio web hecho con ASP.NET para .NET Framework podemos usar tanto código de VB como de C#, aunque no revueltos.

En este sitio que he creado, en el proyecto de C# uso una página con código de VB y otras dos con el código de C#.

En la página maestre he definido una propiedad con el título de la aplicación.
En C# quedaría de esta forma:

<script runat="server">

    public static string AppName { get; set; } = "Web Site Master C#";

</script>

En la de Visual Basic, esa misma propiedad la definimos como te muestro a continuación:

<script runat="server">

    Public Shared Property AppName As String = "Web Site Master VB"

</script>

Como es una propiedad compartida, en C# se utiliza static y en VB se usa Shared.

Y para usarla desde C# lo haríamos de esta forma, por ejemplo para poner el título de la página 2:

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    <h2>Prueba2 en C# para <%= masterpage_master.AppName  %> </h2>
</asp:Content>

Como dije al principio, en VB podemos usar Master para acceder al código de la página maestra, en C# no sepuede.
Lo que también se puede en VB es usar la clase de la página maestra, es decir, tal como se hace en C#.
Decirte que esto último hará que en VB no te muestre un warning que sí muestra cuando se accede a la página maestra usando Master (ver la figura 4).

Nota:
No sé porque ahora me muestra ese warning, ya que siempre lo he usado así (con Master.Propiedad) y nunca había salido esa advertencia, pero bueno… si queremos compatibilidad entre los dos lenguajes, podemos hacerlo usando el nombre de la clase.

Figura 4. Desde C# no se puede usar Master si no el nombre de la clase de la página maestra

Resumiendo el acceso a las páginas maestras desde código

Mejor usar el nombre de la clase, tanto en C# (que es la única forma de ahcerlo, al menos que yo sepa) como en VB.

Te iba a comentar que, aparte de lo que ya hemos visto, desde un sitio web de asp.net con .NET Framework se puede usar tanto código de VB y de C# en conjunto, solo hay que poner dicho código en carpetas diferentes e indicarlo en el fichero Web.Config.

Esto ya lo expliqué cuando salió ASP.NET 2.0 y por tanto las páginas maestras.
Este es el enlace en elguille.info: Usar clases de VB y C# en una misma aplicación Web.

Pero te lo resumo brevemente.

Usar código de VB y C# en un mismo sitio de ASP.NET Framework

Crea la carpeta de código App_Code, decide qué lenguaje será el que use las clases puestas en esa carpeta (normalmente el lenguaje con el que has creado el proyecto), crea una nueva carpeta (dentro de App_Code) para poner las clases del otro lenguaje.

Por ejemplo, si queremos que en la carpeta App_Code estén las clases de VB y en la carpeta c-sharp (App_Code\c-sharp), pondremos esto en el fichero web.config:

<compilation debug="true" strict="true" explicit="true" targetFramework="4.7">
    <codeSubDirectories>
        <add directoryName="c-sharp" />
    </codeSubDirectories>
 </compilation>

Este código estará dentro de la rama: <configuration><system.web>.

Para acceder a las clases o el código se hace de la forma habitual, en este ejemplo, he definido una propiedad estática/compartida para que se pueda acceder desde el código ASP.

Hay que tener en cuenta que C# distingue entre mayúsculas y minúculas, mientras que a VB le da igual como la escribamos.

<p>Usando el código definido en la carpeta <b>App_Code</b></p>
<p>Acceso al código de C# (class1.Nombre):  <% = Class1.Nombre  %> </p>
<p>Acceso al código de VB (class2.Nombre): <% = Class2.Nombre %> </p>
<p>En C# hay que usar correctamente el nombre: Class1 y Class2 (no class1/class2 como en VB).</p>

Y esto es todo… este es el código en GitHub por si le quieres echar un vistazo.

 

 

Cambios en el código de C# para que compile con C# 5.0

Al limpiar el proyecto de los «packages» que añade el Visual Studio, empiezan los errores, uno de ellos es que C# 5.0 no permite asignar valores a las auto-propiedades, por tanto, el código mostrado antes hay que sustituirlo por este otro:

El de la clase Class1.cs: (tanto en el proyecto de VB como en el de C#)

public static string Nombre 
{ 
    get { return "¡Hola Mundo de C#!"; }
} 

El de la página maestra:

<script runat="server">

    public static string AppName 
    { 
        get {return "Web Site Master C#"; } 
    }

</script>

El código de VB no hay que modificarlo, se ve que el compilador usado reconoce la autodefinición de propiedades con asignación de valores.

En el código de GuitHub ya está rectificado.

Nos vemos.
Guillermo

gsNotasNET.Android release v2.0.0.32

gsNotasNET.Android v2.0.0.32

Utilidad para dispositivos móviles Android para tomar notas y guardarlas localmente o en una base de datos externa.

En esta versión (v2.0.0.32) la utilidad/aplicación hace lo siguiente:

Permite crear notas y marcarlas con estos atributos/propiedades:

  • Indicar a qué grupo (tag/etiqueta) pertenece.

  • Se pueden crear tantos grupos como se deseen.

  • El programa recordará el último nombre de grupo utilizado al guardar una nota.

  • Se pueden ver los grupos que hay creados, mostrando la información de las notas que contiene.

  • Al mostrar los grupos se muestra la información de las notas que contiene.

  • Al seleccionar un grupo (clic o tap) te muestra la información de tallada de las notas que contiene, así como la lista de esas notas pertenecientes a ese grupo. Desde esa lista puedes editar las notas.

Atributos /Propiedades de cada nota:

  • Favorita, al mostrar las notas (de la base de datos externa) las notas favoritas se muestran al principio.

  • Notificar, las notas marcadas para notificar se pueden usar para que al hacer login se muestren automáticamente, ahí puedes anotar los recordatorios que necesites ver cada vez que inicias sesión.

  • Archivada, esto hará que la nota no se muestre al mostrar las notas activas.

  • Eliminada, es otra forma de ocultar las notas, ya que nunca se eliminan físicamente de la base de datos (tanto local como externa).

  • Sincronizada, esta propiedad indica si la nota está sincronizada entre las bases local y externa. Las notas siempre se sincronizan entre las dos bases de datos.

Para mostrar las notas hay varios apartados en el menú o pantalla principal, pudiendo mostrar las notas según el atributo o propiedad seleccionado.

  • En la lista de notas se muestra la siguiente información:

  • El título de la nota que consiste en los primeros 50 caracteres o si hay cambios de líneas en la nota, la primera línea.

  • El nombre del grupo, la fecha de modificación y una letra cn el nombre del atributo y si está marcado (True) o no lo está (False).

  • Las abreviaturas de los atributos son:

    Favorita, Notificar, Archivada y Eliminada.

  • En una nueva actualización añadiré Sincronizada, aunque se supone que siempre deben estar sincronizadas.

  • Seguramente también añadiré una página (opción) para mostrar las notas sincronizadas y poder asegurarte que si no está sincronizada, lo haga.

En la configuración puedes indicar:

  • Recordar el usuario con el que se ha hecho Login.
  • Recordar el password usado.
  • Iniciar la aplicación con el último usuario.
  • Mantener las notas sincronizadas (siempre está activada esta opción).
  • Mostrar las notas a Notificar al iniciar el programa (o hacer Login).
  • Usar las notas locales (cuando se activa) o usar las notas de la base externa.

En la información del Perfil te muestra los datos de la cuenta con la que has hecho Login.

  • Ahí puedes cambiar la cuenta de correo y el password.

  • Si cambias la cuenta de correo, se enviarán 2 mensajes, uno a cada cuenta pidiendo confirmación.

  • Te muestra la inforamción de la fecha de alta, último acceso, cuántas notas de la base externa puedes escribir:

  • Para los primeros 90 usuarios que se registren tienen una cuota de 1.000 notas, a partir del usuario 100 (los otros 10 los tengo reservados para mí) tendrán 100 notas como máximo de forma totalmente gratuita.

  • En esa cantidad, se cuentan todas las notas, estén o no eliminadas (ya que nunca se eliminan las notas).

  • El importe por cada 1.000 notas será de una donación anual de 12$ USD (unos 10€).

  • En esa cuota no se cuentan las notas ofrecidas gratuitamente.

  • El importe indicado en Pagos será el importe que hayas ido pagando.

  • Ya te digo que solamente debes pagar si quieres más cantidad de notas. La aplicación es totalmente gratuita. Salvo que prefieras hacer un donativo voluntario.

  • El donativo lo puedes hacer mediante este enlace: Donativo para elGuille.

  • Todos los donativos serán siempre bienvenidos 🙂

Puedes realizar búsquedas en las notas (tanto en la base local como en la externa).

  • La búsqueda se realiza sin tener en cuenta el case (no diferencia entre mayúsculas y minúsculas).

  • Por ahora solo hace la búsqueda en el Texto de las notas.

  • En una nueva actualización incluiré que se pueda hacer tanbién (o solo) en los nombres de los grupos).

  • En el resultado de la búsqueda puedes pulsar (hacer clic o tap) en la nota para editarla.

  • Aunque estés usando las notas de la base de datos remota (de SQL Server) puedes mostrar las notas de la base de datos loca, en este caso las notas no son editables, solo se muestran en la lista y haciendo tap o clic en ellas no se muestran. ??? Si quieres editar una nota local, debes cambiarlo en la configuración seleccionando la opción Usar las notas locales.

En la pantalla principal además te encontrarás con estas opciones:

  • Validar Email. Esto tendrás que usarlo cuando te registres con un nuevo usuario. O al crear un nuevo usuario.
  • Sincronizar. Esta opción te sirve para comprobar si las notas están sincronizadas (deberían estarlo), pero en caso de que no lo estuvieran, puedes sincronizar las locales al romoto o al revés.
  • Comentarios. Por si quieres enviarme alguna sugerencia, bug o cualquier cosa que me quieras decir. Esta opción te permite indicar un comentario y al pulsar en el botón de ENVIAR… abrirá una cuenta de email que tengas configurada en tu dispositivo para poder enviar el mensaje. El texto que hayas escritor aparecerá en el cuerpo del mensaje.
  • Acerca de Abre una ventana con un poco de ayuda sobre la aplicación. Seguramente añadiré un enlace a esta página descriptiva, ya que tanto texto no se puede poner en ese tipo de páginas… o al menos no se vería bien.
  • Cambiar de usuario. Desde ahí puedes hacer login, si no lo has hecho ya, o bien poder registrar un nuevo usuario.

En todas (o casi todas) existe un botón POLÍTICA DE PRIVACIDAD que al pulsarlo te muestra (en el navegador) la política de privacidad, es decir, qué datos personales se recogen.

Ahora muestra el contenido de elguillemola.com: Política de privacidad en elguillemola.com pero seguramente lo cambiaré a una que sea específica de esta aplicación.

De todas formas, comentarte que con los datos que facilitas o las notas que escribe yo no hago nada, ni cambairé nada, salvo que tú me lo pidas expresamente, bien porque no tengas acceso o cualquier otra circunstancia que te impida acceder a las notas o tu cuenta de usuario.

Bueno y creo que esto es todo…

He escrito tanto con idea de crear una página en elguillemola.com y así poder usarla como ayuda de la aplicación.

También crearé un video explicativo con las cosas que debes saber sobre la aplicación.

Si has llegado leyendo hasta aquí… ¡muchas gracias! 🙂

Y como estamos en las fechas que estamos (30 de diciembre de 2020) te deseo ¡FELICES FIESTAS!

 

Galería de fotos / capturas de la versión 2.0.0.32
(al menos en las que hay cambios, el resto es de la v2.0.0.31)

 

Puedes descargar el "paquete" de instalación desde GitHub:

Este enlace es para la versión v2.0.0.31.

Este otro es para la versión v2.0.0.32 (si no te funciona el enlace es que lo has pulsado antes de que yo lo haya publicado 😉 )

 

NOTA

Hay una nueva vaersión: v2.0.0.33

Usa este enlace para no perderte lo último: gsNotasNET.Android v2.0.0.33

 

Nos vemos.
Guillermo

Tutorial Google APIs – Código para acceder a los contactos con People API

Ya estás en la segunda entrega de este Tutorial sobre el uso de las APIs de Google.
Aquí te mostraré el código de Visual Basic y C# para acceder a los contactos de Google usando People API. Como te comenté en la priumera entrega sobre cómo crear un proyecto en Google Cloud, el API que usaremos es People API, no te confundas con Contacts API (como a mí me ocurrió) ya que parece que será la más adecuada, pero además de que Google no recomienda que se use Contacts API, la he probado y no he conseguido sacar prácticamente nada de información, y al que he sacado es de unos pocos contactos (que ni recordaba que los tenía creados).

Nota:
Está uno acostumbrado a que te marquen los errores horrográficos que esto de que no te los marque es un Orror! 😛

Bueno vamos empezar con el código de C# que es lo que la gente suele ver en internet (de VB no he visto ni un ejemplo, así que… ya mismo lo verás en primicia).

Después de escribir el párrafo anterior he cambiado de opinión y te voy a enseñar conjuntamente el código de los dos lenguajes, para que vayas comparando.

Código de C# y VB para mostrar los contactos de una cuenta de Google usando People API

Nota:
Debo decir que parte de este código lo he visto en algunos ejemplosencontrados tanto en la documentación de Google como en foros de C#. Pero principalmente de la documentación (escasa) de Google y en agunos casos, los ejemplos eran de java, ni siquiera de C#.

Como te comenté en el preámbulo del tutorial, debes añadir las referencias a los paquetes de NuGet que instalarán las APIs en tu proyecto. Yo he añadido todas las que te indiqué en esa primera página del tutorial. Por supuesto si quieres acceder, por ejemplo al calendario o a GMail, tendrás que añadir referencias a esas APIs, además de añadirlas al proyecto creado en Google Cloud Platform.

Veamos el código inicial (con las importaciones de los espacios de nombres) que será básicamente el mismo en todas las apliocaciones que hagas para acceder a las APIs de Google.

// Genéricas
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Util.Store;
// People API
using Google.Apis.People.v1;
using Google.Apis.People.v1.Data;
// Docs API
using Google.Apis.Docs.v1;
using Google.Apis.Docs.v1.Data;
// Drive API
using Google.Apis.Drive.v3;
using Google.Apis.Drive.v3.Data; // Para el tipo File

using System;
using System.Collections.Generic;
//using System.IO;
using System.Threading;
using System.Text;
using System.Linq;
'// Genéricas
Imports Google.Apis.Auth.OAuth2
Imports Google.Apis.Services
Imports Google.Apis.Util.Store
'// People API
Imports Google.Apis.People.v1
Imports Google.Apis.People.v1.Data
'// Docs API
Imports Google.Apis.Docs.v1
Imports Google.Apis.Docs.v1.Data
'// Drive API
Imports Google.Apis.Drive.v3
Imports Google.Apis.Drive.v3.Data '// Para el tipo File

Imports System
Imports System.Collections.Generic
Imports System.Threading
Imports System.Text
Imports System.Linq

Ahora vamos a crear una serie de campos estáticos/compartidos (static en C#, shared en VB) que usaremos también de forma genérica en todos los proyectos de acceso a Google APIs.

class Program
{
    // If modifying these scopes, delete your previously saved credentials
    // at ~/.credentials/docs.googleapis.com-dotnet-quickstart.json
    static string[] Scopes = { DocsService.Scope.Documents, 
                               DocsService.Scope.DriveFile, 
                               PeopleService.Scope.ContactsReadonly };

    static string ApplicationName = "Tutorial Google APIs VB";

    // Los datos del proyecto creado para VB
    static ClientSecrets secrets = new ClientSecrets()
    {
        ClientId = "430211665266-t68vl99t2q40v3lbctgbph23j2644bpj.apps.googleusercontent.com",
        ClientSecret = "Xqexl0FMPedNc1KYs0iJt22A"
    };

    static DocsService docService;
    static DriveService driveService;
    static PeopleService peopleService;

    static UserCredential Credential;
Class Program

    Shared Scopes As String() =
        {
            DocsService.Scope.Documents,
            DocsService.Scope.DriveFile,
            PeopleService.Scope.ContactsReadonly
        }

    Shared ApplicationName As String = "Tutorial Google APIs VB"

    Shared secrets As ClientSecrets = New ClientSecrets() With
        {
            .ClientId = "430211665266-t68vl99t2q40v3lbctgbph23j2644bpj.apps.googleusercontent.com",
            .ClientSecret = "Xqexl0FMPedNc1KYs0iJt22A"
        }

    Shared docService As DocsService
    Shared driveService As DriveService
    Shared peopleService As PeopleService

    Shared Credential As UserCredential

Lo que ese primer comentario indica (es de un quickstart de Google) es que si cambias los valores del array Scopes debes eliminar el directorio creado en Documentos\.credentials (ahora verás porqué).

El array Scopes contiene los ámbitos de la aplicación, es a qué estamos pidiendo permiso para acceder. Ahí he añadido los tres ámbitos que usaré en este tutorial, pero si solo quieres acceder a los contactos con People API, añadiendo PeopleService.Scope.ContactsReadonly sería suficiente. Si te fijas, estás pidiendo autorización (a OAuth) para acceder de forma de solo lectura a los contactos.
En realidad estás pidiendo permisos para acceder a los Documentos y al Drive sin restricciones, pero a los contactos solo para leerlos. Estos dos últimos necesitan más permisos porque queremos crear ficheros, eliminarlos, lo mismo con los documentos.

Lo importante (también) es la asignación de ClientSecrets, ahí tendás que poner los datos que te haya generado al configurar el OAuth de la aplicación. Eso que te muestro son los valores que en mi proyecto para este tutorial he pedido, el que se indique que la aplicación se llama Tutorial Google APis VB no significa que no se pueda usar para C#, ese título o nombre de aplicación no es restrictivo para nada.

Nota:
Normalmente esos valores se recomienda que no se hagan públicos… ¡vaya el caso que hago! jejejeje… pero para este caso, me fio de ti, y sé que no se lo dirás a nadie y así lo mantenemos en secreto… 😉

Las tres declaraciones después de asignar el valor a secrets son para acceder a los servicios de las tres APIs que usaré en estos tutoriales, las defino a nivel de clase para que se puedan usar en todos los métodos que sean necesarios y no tener que pasarlas como argumento de llamada al método que lo necesite.

La última declaración (Credential) es para crear las credenciales del usuario. La asignación la haré en el método Main, y como es un valor compartido, también se podrá usar en cualquier parte de la clase.

El siguiente código es el método Main, en el que llamaremos al método que accede a los contactos y los muestra.

Y como verás en las capturas el correo que he usado no tenía ningún contacto y he tenido que crear uno para comprobar que funciona… las cosas del Guille…

static void Main(string[] args)
{
    Console.WriteLine("Tutorial Google APIs con C#");

    string credPath = System.Environment.GetFolderPath(
        Environment.SpecialFolder.Personal);
    
    // Directorio donde se guardarán las credenciales
    credPath = System.IO.Path.Combine(credPath, ".credentials/Tutorial-Google-APIs-VB");

    Credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
        secrets,
        Scopes,
        "user",
        CancellationToken.None,
        new FileDataStore(credPath, true)).Result;
    //Console.WriteLine("Credential file saved to: " + credPath);

    // Mostrar los contactos
    MostrarContactos();

    Console.WriteLine();
    Console.WriteLine("Pulsa una tecla.");
    Console.Read();
}
Public Shared Sub Main(ByVal args As String())

    Console.WriteLine("Tutorial Google APIs con Visual Basic")

    Dim credPath As String = System.Environment.GetFolderPath(
        Environment.SpecialFolder.Personal)

    '// Directorio donde se guardarán las credenciales
    credPath = System.IO.Path.Combine(credPath, ".credentials/Tutorial-Google-APIs-VB")

    Credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
        secrets,
        Scopes,
        "user",
        CancellationToken.None,
        New FileDataStore(credPath, True)).Result

    '// Mostrar los contactos
    MostrarContactos()

    Console.WriteLine()
    Console.WriteLine("Pulsa una tecla.")
    Console.Read()
End Sub

El valor de credPath es el direcorio donde se crearán las credenciales que vamos a usar en este programa. Se guardará en los documentos del usuario en una carpeta llamada Tutorial-Google-APIs-VB que estará incluida en .credentials.

Si haces cambios en los permisos o te han faltado permisos en la configuración de OAuth y los modificas, debes eliminar la carpeta del tutorial, a de .credentials la puedes dejar, por si la usas para almacenar las credenciales de otros programas que use el usuario.
También tendrás que borrarla si decides usar otra cuenta de Google (GMail) para acceder a esos contactos. Si solo tienes una cuenta de GMail, no hará falta que la borres salvo para los dos primeros casos.

Cuando ejecutemos la aplicación verás qué es lo que se guarda en esa carpeta.

A Credentials le asignamos las credenciales que queremos usar.

Aquí tengo que hacer una puntuialización.
El valor de secrets se asigna con los valores que hemos indicado (de foirma llana y clara) antes, pero también se puede hacer accediendo a un fichero que contiene esos valores, al menos así no se mostrarán directamente en el código los valores secretos. Aunque seguirán estando al alcance del usuario de la aplicación.

La forma de hacerlo lo pondré en otro ejemplo de este tutorial.

Ahora solo nos falta ver qué código contiene elmétodo MostrarContactos.

¡Vamos a ello!

private static void MostrarContactos()
{
    // Create Drive API service.
    peopleService = new PeopleService(new BaseClientService.Initializer()
    {
        HttpClientInitializer = Credential,
        ApplicationName = ApplicationName,
    });

    // Lista de los contactos (People)
    Console.WriteLine("Contactos:");

    // Este muestra todos los contactos
    GetPeople(peopleService, null);

    Console.WriteLine();
    Console.WriteLine($"Hay {total} contactos / People");
    Console.WriteLine();
}
Private Shared Sub MostrarContactos()
    peopleService = New PeopleService(New BaseClientService.Initializer() With
    {
        .HttpClientInitializer = Credential,
        .ApplicationName = ApplicationName
    })

    Console.WriteLine("Contactos:")

    GetPeople(peopleService, Nothing)

    Console.WriteLine()
    Console.WriteLine($"Hay {total} contactos / People")
    Console.WriteLine()
End Sub

Le asignamos el valor a peopleService para que pida esos permisos a Google, como ves se usa el protocolo HTTP.
Eso lo que hará es abrir una página en el navegador pidiendo permiso para acceder a los datos de una cuenta de GMail (ver la figura 1)

Figura 1. Seleccionar la cunta que queremos usar para acceder a sus contactos.

Esa primera pantalla nos pide que indiquemos a qué contactos queremos acceder, es decir, solo accederá a los contactos de la cuenta que indiques, y para indicar esa cuenta debes tener el password, si no… no hay nada que hacer.
Por tanto, esto que vamos a hacer es seguro, en el sentido de que yo no voy a acceder (ni puedo) a tus contactos… otra cosa es que mi aplicación se comunicara conmigo o guardara esa información en algún sitio… pero no te preocupes, no lo hace, además lo puedes comprobar por ti mismo viendo el código.

Una vez elegida la cuenta, te mostrará un aviso de que la aplicación no es segura o, en realidad, que no se ha verificado (ver la figura 2).
Tendrás que autorizarla para que pueda seguir.

Figura 2. DEbes mostrar la información oculta para permitir ir a la aplicación

Una vez hechoi esto, Google te pedirá confirmación para dejar que la aplicación haga lo que se ha indicado en Scopes. Así que… otras tres pantallitas más de autorización (ver figuras 3 a 5).

Figura 3. Permiso para ver los contactos.
Figura 4. Acceder al Drive.
Figura 5. Acceder a los documentos.

Y una vez permitido estas cosas, debes terminar de aceptarlo (ver la figura 6 en la está el resumen de los permisos que le darás a la aplicación).

Figura 6. Confirmación final de los permisos.

Después de pulsar en Permitir, el navegador te mostrará un mensaje de que puedes cerrar la página.

Estos permisos no te los volverá a pedir para usar esta aplicación. Y por tanto, siempre accederá a la cuenta de GMail que has indicado.

Si quieres usar otra cuenta diferente, borra la carpeta esa que te comenté antes (o el fichero que contiene) y eso hará que te vuelva a mostrar todas estas pantallas.

Antes de seguir, espera un poco que me estoy meando de la risa… ¡ay!

Es que te dije que definí la variable peopleService (y las otras dos) a nivel de clase para no tener que usarla como argumento a un método y voy y pongo como argumento el valor de esa variable compartida… en fin… la cabeza del Guille…

Bueno, ya.

Sigamos con el código que accede a los contactos.

private static int total = 0;

static void GetPeople(PeopleService service, string pageToken)
{
    // Define parameters of request.
    PeopleResource.ConnectionsResource.ListRequest peopleRequest =
            service.People.Connections.List("people/me");

    //
    // Lista de campos a usar en RequestMaskIncludeField:
    // https://developers.google.com/people/api/rest/v1/people/get
    //

    peopleRequest.RequestMaskIncludeField = new List<string>()
            {"person.names", "person.phoneNumbers", "person.emailAddresses",
              "person.birthdays", "person.Addresses"
            };


    if (pageToken != null)
    {
        peopleRequest.PageToken = pageToken;
    }

    ListConnectionsResponse people = peopleRequest.Execute();

    if (people != null && people.Connections != null && people.Connections.Count > 0)
    {
        total += people.Connections.Count;
        foreach (var person in people.Connections)
        {
            Console.Write(person.Names != null ? ($"{person.Names.FirstOrDefault().DisplayName} - ") : "");
            Console.Write(person.PhoneNumbers != null ? ($"{person.PhoneNumbers.FirstOrDefault().Value} - ") : "");
            Console.Write(person.EmailAddresses != null ? ($"{person.EmailAddresses.FirstOrDefault().Value} - ") : "");
            Console.Write(person.Addresses != null ? ($"{person.Addresses.FirstOrDefault()?.City} - ") : "");
            if (person.Birthdays != null)
            {
                var fecha = "";
                var b = person.Birthdays.FirstOrDefault()?.Date;
                if (b != null)
                    fecha = $"{b.Day}/{b.Month}/{b.Year}";
                Console.Write($"{fecha}");
            }
            Console.WriteLine();
        }

        if (people.NextPageToken != null)
        {
            Console.WriteLine();
            Console.WriteLine($"{total} contactos mostrados hasta ahora. Pulsa una tecla para seguir mostrando contactos.");
            Console.WriteLine();
            Console.ReadKey();

            GetPeople(service, people.NextPageToken);
        }
    }
    else
    {
        Console.WriteLine("No se han encontrado contactos.");
        return;
    }
}
Private Shared total As Integer = 0

Private Shared Sub GetPeople(service As PeopleService, pageToken As String)

    Dim peopleRequest As PeopleResource.ConnectionsResource.ListRequest =
        service.People.Connections.List("people/me")

    peopleRequest.RequestMaskIncludeField = New List(Of String)() From {
            "person.names",
            "person.phoneNumbers",
            "person.emailAddresses",
            "person.birthdays",
            "person.Addresses"
        }

    If pageToken IsNot Nothing Then
        peopleRequest.PageToken = pageToken
    End If

    Dim people As ListConnectionsResponse = peopleRequest.Execute()

    If people IsNot Nothing AndAlso
            people.Connections IsNot Nothing AndAlso
            people.Connections.Count > 0 Then
        total += people.Connections.Count

        For Each person In people.Connections
            Console.Write(If(person.Names IsNot Nothing,
                          ($"{person.Names.FirstOrDefault().DisplayName} - "), ""))
            Console.Write(If(person.PhoneNumbers IsNot Nothing,
                          ($"{person.PhoneNumbers.FirstOrDefault().Value} - "), ""))
            Console.Write(If(person.EmailAddresses IsNot Nothing,
                          ($"{person.EmailAddresses.FirstOrDefault().Value} - "), ""))
            Console.Write(If(person.Addresses IsNot Nothing,
                          ($"{person.Addresses.FirstOrDefault()?.City} - "), ""))

            If person.Birthdays IsNot Nothing Then
                Dim fecha = ""
                Dim b = person.Birthdays.FirstOrDefault()?.Date
                If b IsNot Nothing Then fecha = $"{b.Day}/{b.Month}/{b.Year}"
                Console.Write($"{fecha}")
            End If

            Console.WriteLine()
        Next

        If people.NextPageToken IsNot Nothing Then
            Console.WriteLine()
            Console.WriteLine($"{total} contactos mostrados hasta ahora. " &
                              "Pulsa una tecla para seguir mostrando contactos.")
            Console.WriteLine()
            Console.ReadKey()
            GetPeople(service, people.NextPageToken)
        End If
    Else
        Console.WriteLine("No se han encontrado contactos.")
        Return
    End If
End Sub

El valor de peopleRequest debe ser siempre people/me o bien si te sabes el ID de otro usuario lo podrías indicar en lugar de «me«. Ese me significa que accedes a tus contactos.
He buscado por todas partes, y no he averiguado como saber ese famoso ID, ni siquiera de una de mis cuentas para poder saber si se puede acceder a la cuenta de alguien que no seas tú.
Cuando lo averigüe te lo cuento.

Los valores asigndos a la lista RequestMaskIncludeField serán a los datos que queremos acceder y siempre deben empezar con person. seguido del campo al que queremos acceder. En este ejemplo estamos indicando que queremos acceder a: los nombres, teléfonos, emails, cumpleaños y domicilios.

Y como esos valores pueden ser nulos (y normalmente son una colección de valores), comprobamos si es nulo y en el caso de las colecciones accedemos al primero o al predeterminado, si hay algo lo mostramos y si no, se usa una cadena vacía.

Con el valor de Birtdays debemos hacer una comprobación más elaborada e incluso te recomendaría que usaras un try/catch si quieres acceder a los valores de la fecha, porque de las pruebas que he heco, en un caso me dio error al querer acceder al año… se ve que el contacto ese no quería dar su año de nacimiento y dio error al querer convertirlo a entero… en fin…

El NextPageToken nos indica que hay más págins de datos, así que… si las hay volvemos a llamar a este método y seguimos mostrando los contactos que falten por acceder.

Y esto es todo lo que hay que hacer para mostrar los contactos usando People API. Otra cosa es que quieras crear contactos o modificarlos, en esos casos tendrás que modificar el valor del Scope de los contatos.
Si hago pruebas de crear o modificar te los pondré por aquí.

Para terminar, la captura del programa en funcionamiento. Ver la figura 7.

Figura 7. La cuenta que he usado para acceder a los contactos, ¡no tiene contactos!

Pues la sorpresa que me llevé… pensé que lo mismo fallaba algo, así que… me fui a google, creé un contacto y volvía a probar… ¡Esta vez sí que sí! (ver la figira 8).

Figura 8. Un contacto tengo en la cuenta que he usado para esta prueba.

Y esto es todo por ahora.

Ahora a esperar a la siguiente entrega.

Este código está publicado en GitHub: Tutorial-APIs-Google.

Nos vemos.
Guillermo

P.S.
Versión en inglés / English version.

Tutorial Google APIs – Crear Proyecto en Google Cloud

Aquí tienes la primera entrega del tutorial sobre el uso de las APIs de Google para acceder a Drive, Contactos y Documentos.

Si quieres crer una cuenta y un proyecto para poder acceder a esos APIs de Google, lo primero es acceder a Google Cloud Platform y crear una cuenta, o mejor dicho, activarla con Google Cloud.

Una vez que tengas la cuenta, tendrás que crear un proyecto y configurarlo para que pueda acceder a esas APIs.

En este tutorial te explico paso a paso cómo hacerlo, y con un montón de capturas para que no te líes y yo no me olvide de contarte los paso, que todo hay que decirlo. 🙂

Nota:
Por ahora te voy dejar las capturas y en otra ocasión, si hace falta, te explico lo que cada captura significa.
Es que quiero pasar a mostrarte el código para acceder al API de People (contactos) que ya lo tengo hecho tanto con C# como con Visual Basic.

Figura 1. Crear un nuevo proyecto

 

Figura 2.

 

Figura 3.

 

Figura 4.

 

Figura 5.

 

Figura 6. En la ficha G Suite están las de Docs API y drive API

 

Figura 7. Tienes que elegir y habilitar una por una.

 

Figura 8.

 

Figura 9. Añadir más librerías (bibliotecas)

 

Figura 10. Elige People API. No elijas Contacts API, que aparte de estar obsoleta, no vale para nada…

 

Figura 11. Esta es la parte más importnte, sin la autorización OAuth no podrás acceder a nada.

 

Figura 12. Siempre debe ser External

 

Figura 13.

 

Figura 14.

 

Figura 15. Añadir las características que tu aplicación usará de cada API que has añadido.

 

Figura 16.

 

Figura 17.

Nota:
Los permisos debes ir probándolos a ver qué error te da, según lo que quieras hacer.
Pero básicamente necesitas acceso de lectura, salvo que quieras modificar un contacto, un documento o algún fichero del Drive.

Figura 18. No te olvides de darle a UPDATE ya que al estar tan abajo en la pantalla emergente ni se ve, y so no le das a Update, no se guardan los cambios.

 

Figura 19.

 

Figura 20.

 

Figura 21. Aquí tienes que añadir los usuarios autorizados para que usen la aplicación. El máximo es 100 y una vez que aades uno, ya no lo puedes eliminar.

 

Figura 22.

 

Figura 23. Los tipos de credenciales que crearemos

 

Figura 24.

 

Figura 25. Estas so las APIs que usaremos con este proyecto.

 

Figura 26. El tipo de aplicación que vamos a crear.

 

Figura 27.

 

Figura 28. Estas son las dos claves que necesitarás en tu código

 

Figura 29.

 

Figura 30.

 

Figura 31. Si no hs copiado las credenciales de acceso, descarga el fichero .json y ahí las tienes.

 

 

Pues esto es todo lo que debes saber para crear un proyecto.
En la siguiente entrega voy a mostrarte el código de una aplicación de consola para acceder a los contactos (People API). Sí, en C# y en VB.

 

 

Nos vemos.
Guillermo

Tutorial para usar las APIs de Google con C# y Visual Basic

Pues eso… que como yo me he encontrado con problemas a la hora de implementar las APIs de Google y de encontrar ejemplos (que de haberlos solo eran para C#), me he decido a escribir esta especie de tutorial para poder acceder a las siguientes APIs de Google: Drive, Docs y People. Es decir, poder manipular el contenido de Google Drive, los documentos y los contactos de Google que están asociados tu cuenta (o la cuenta que decidas usar) de GMail.

Lo primero que necesitas (salvo que uses las que yo voy a crear para este tutorial) es crearte una cuenta en Google Cloud Platform, es gratuito al menos sino usas recursos que son de pago.
La cuenta a usar será la que tengas ya de GMail o bien puedes crear una nueva cuenta y asociarla con Google Cloud.

Cuandoi asocias una cuenta por primera vez, te darán una oferta de 300$ (US $) para que pruebes de forma gratuita los recursos de pago (siempre que no te pases de esos 300 dólares). Pero como te digo, para las cosas que te voy a explicar no te hace falta.

Por ahora me voy a saltar el paso de crear tus propios poyectos en Google Cloud, eso lo dejaré para el final (salvo que cambie de opinión), lo que sí te digo es que si quieres utilizar los ejemplos que te voy a mostrar usando mis claves o las que yo indique en el código) antes debes decírmelo para poder añadir tu correo de GMail a los usuarios que pueden usar esas claves.

Esto ultimo lo puedes hacer dejando un comentario en este mismo post y yo te agregaré, esto puede que no lo haga pasado unos meses, ya que solo quiero que la gente lo pruebe en este tiempo reciente, mientras publico los tutoriales. Y dejando, como mucho, unos tres meses de desde la publicación original, así que… si estás leyendo este tutorial después del 15 de marzo de 2021, es posible que o bien no admita más usuarios o simplemente que no lo siga «soportando», además de que hay un límite de 100 usuarios por proyecto, y si ya están esos usuarios registrados con la aplciación, es posible que, incluso antes del 15 de marzo del 2021 no pueda admitir más usuarios.

Dicho esto, empecemos.

Nota:
Los ejemplos los voy a hacer con .NET 5.0.1 pero son válidos para .NET Framework v4.5 y superiores, .NET Standard y .NET Core.

Crear un proyecto en C# o Visual Basic

Crea un proyecto de consola para C# o VB y ve a Tools>NuGet Package Manager>Manage NuGet Packages for Solution… (en español es: Herramientas>Administrador de paquetes NuGet>Administrar paquetes NuGet para la solución…)

Busca y añade los siguientes paquetes de NuGet (entre paréntesis te indico las versiones que estoy usando al escribir este tutorial):

Nota:
Los enlaces son por si quieres ir a la página de NuGet y descargarlas desde allí o ver cómo instalarlas según estés usando Visual Studio 2019 o Visual Studio Code o simplemente creando los proyectos desde la consola con dotnet.
Eso sí, necesitarás tener instlado el SDK de dotnet 5 para poder compilar el código.

Esto añadirá las referencias necesarias para usar el código que te mostraré.

Nota:
Si te interesa ver el código fuente de las APIs de google puedes verlas en el siguiente enlace: google-api-dotnet-client.

Las entregas

  1. Entrega 1: Crear Proyecto en Google Cloud
  2. Entrega 2: Código para acceder a los contactos con People API
  3. Entrega 3: Código para acceder a los documentos con Drive API y Docs API
  4. Entrega 4: Código para crear un documento con Docs API

Nota:
Voy a publicar ahora este post mientras creo el protyecto de prueba, escribo el código, lo convierto de C# a VB (ya tengo código escrito en C#) y lo publico, así podrás solicitar tu «permiso» para usar estos ejemplos con mi ID y clave secreta (que después de publicarla no será tan secreta 😉 )

Nos vemos.
Guillermo