Importar contactos de Gmail mediante programación en Java

Gmail de Google se encuentra entre los servicios de correo electrónico más populares y utilizados. Gmail proporciona una variedad de funciones además de enviar y recibir correos electrónicos, como calendarios, chats, etc. En ciertos casos, es posible que deba conectarse a Gmail e importar contactos mediante programación desde sus aplicaciones. Para lograrlo, este artículo muestra cómo importar contactos de Gmail usando Java. Además, cubriremos cómo acceder a los contactos en un grupo de correo electrónico específico.

API de Java para importar contactos de Gmail

Aspose.Email for Java es una potente API para crear aplicaciones de cliente de correo electrónico. Además, admite trabajar con Gmail, como acceder a contactos, calendarios, citas, etc. Usaremos esta API para acceder e importar contactos desde cuentas de Gmail. Puede descargar la API o instalarla usando las siguientes configuraciones de Maven.

Repositorio:

<repository>
    <id>AsposeJavaAPI</id>
    <name>Aspose Java API</name>
    <url>http://repository.aspose.com/repo/</url>
</repository>

Dependencia:

<dependency>
    <groupId>com.aspose</groupId>
    <artifactId>aspose-email</artifactId>
    <version>22.2</version>
    <classifier>jdk16</classifier>
</dependency>

Importar contactos de Gmail en Java

Antes de comenzar, debe crear un proyecto en Google Developer Console, que le permitirá ejecutar el código. Para crear uno, puede seguir esta guía.

Ahora, cree una clase auxiliar llamada GoogleOAuthHelper para encargarse de la autenticación de una cuenta de Gmail. Además, cree una clase denominada OAuthUser para almacenar la información del usuario. La siguiente es la implementación completa de ambas clases.

public class OAuthUser {
        String email;
        String clientId;
        String clientSecret;
        String refreshToken;
    }
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.xml.bind.DatatypeConverter;

/**
 * <p>
 * Consola de desarrolladores https://console.developers.google.com/projectselector/apis/credentials?pli=1 
 * Documentación https://developers.google.com/identity/protocols/OAuth2InstalledApp
 * </p>
 */
class GoogleOAuthHelper {
    public static final String AUTHORIZATION_URL = "https://accounts.google.com/o/oauth2/v2/auth";
    public static final String TOKEN_REQUEST_URL = "https://oauth2.googleapis.com/token";
    public static final String REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
    public static final String REDIRECT_TYPE = "code";
    public static final String SCOPE = "https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar" // Calendar
            + "+https%3A%2F%2Fwww.google.com%2Fm8%2Ffeeds%2F" // Contacts
            + "+https%3A%2F%2Fmail.google.com%2F"; // IMAP & SMTP

    static String createCodeChalange() {
        String verifierStr = UUID.randomUUID().toString() + "-" + UUID.randomUUID().toString();
        System.out.println("Code Verifier: " + verifierStr);

        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("SHA-256");
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalAccessError(e.getMessage());
        }
        byte[] hash = digest.digest(verifierStr.getBytes(StandardCharsets.UTF_8));
        String base64Hash = DatatypeConverter.printBase64Binary(hash);

        base64Hash = base64Hash.split("=")[0];
        base64Hash = base64Hash.replace('+', '-').replace('/', '_');
        return base64Hash;
    }

    static String getAuthorizationCodeUrl(OAuthUser acc) {
        return getAuthorizationCodeUrl(acc, SCOPE, REDIRECT_URI, REDIRECT_TYPE);
    }

    static String getAuthorizationCodeUrl(OAuthUser acc, String scope, String redirectUri, String responseType) {
        System.out.println("---------------------------------------------------------");
        System.out.println("------------- OAuth 2.0 AuthorizationCodeUrl -------------");
        System.out.println("---------------------------------------------------------");
        System.out.println("Login: " + acc.email);
        String codeChallenge = createCodeChalange();

        String state = urlEncode(UUID.randomUUID().toString());
        String approveUrl = AUTHORIZATION_URL + "?client_id=" + acc.clientId + "&redirect_uri=" + redirectUri + "&response_type=" + responseType + "&scope=" + scope
                + "&code_challenge=" + codeChallenge + "&code_challenge_method=S256&state=" + state;

        System.out.println("Approve Url: " + approveUrl);
        return approveUrl;
    }

    static String urlEncode(String value) {
        try {
            return URLEncoder.encode(value, StandardCharsets.UTF_8.toString());
        } catch (UnsupportedEncodingException e) {
            throw new IllegalAccessError(e.getMessage());
        }
    }

    static String urlDecode(String value) {
        try {
            return URLDecoder.decode(value, StandardCharsets.UTF_8.toString());
        } catch (UnsupportedEncodingException e) {
            throw new IllegalAccessError(e.getMessage());
        }
    }

    static String getAccessTokenByAuthCode(String authorizationCode, String codeVerifier, OAuthUser user) {
        String encodedParameters = "client_id=" + urlEncode(user.clientId) + "&client_secret=" + urlEncode(user.clientSecret) + "&code=" + urlEncode(authorizationCode)
                + "&code_verifier=" + codeVerifier + "&redirect_uri=" + urlEncode(REDIRECT_URI) + "&grant_type=authorization_code";
        System.out.println("---------------------------------------------------------");
        System.out.println("------------- OAuth 2.0 AccessTokenByAuthCode -------------");
        System.out.println("---------------------------------------------------------");
        System.out.println("Authorization code: " + authorizationCode);

        String result = "";
        Map<String, String> token = geToken(encodedParameters);
        for (String key : token.keySet()) {
            System.out.println(key + ": " + token.get(key));
            if (key.equals("refresh_token")) {
                result = token.get(key);
            }
        }

        System.out.println("---------------------------------------------------------");

        return result;
    }

    static String getAccessTokenByRefreshToken(OAuthUser user) {
        String encodedParameters = "client_id=" + urlEncode(user.clientId) + "&client_secret=" + urlEncode(user.clientSecret) + "&refresh_token=" + urlEncode(user.refreshToken)
                + "&grant_type=refresh_token";
        System.out.println("---------------------------------------------------------");
        System.out.println("----------- OAuth 2.0 AccessTokenByRefreshToken -----------");
        System.out.println("---------------------------------------------------------");
        System.out.println("Login: " + user.email);

        String result = "";
        Map<String, String> token = geToken(encodedParameters);
        for (String key : token.keySet()) {
            System.out.println(key + ": " + token.get(key));
            if (key.equals("access_token")) {
                result = token.get(key);
            }
        }

        System.out.println("---------------------------------------------------------");

        return result;
    }

    static Map<String, String> geToken(String encodedParameters) {
        try {
            HttpURLConnection connection = (HttpURLConnection) new URL(TOKEN_REQUEST_URL).openConnection();
            connection.setRequestMethod("POST");

            byte[] requestData = encodedParameters.getBytes(StandardCharsets.UTF_8);

            connection.setUseCaches(false);
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.setRequestProperty("Content-Length", "" + requestData.length);

            final OutputStream st = connection.getOutputStream();
            try {
                st.write(requestData, 0, requestData.length);
            } finally {
                st.flush();
                st.close();
            }

            connection.connect();

            if (connection.getResponseCode() >= HttpURLConnection.HTTP_BAD_REQUEST) {
                throw new IllegalAccessError("Operation failed: " + connection.getResponseCode() + "/" + connection.getResponseMessage() + "\r\nDetails:\r\n{2}"
                        + readInputStream(connection.getErrorStream()));
            }

            String responseText = readInputStream(connection.getInputStream());

            Map<String, String> result = new HashMap<String, String>();
            System.out.println(responseText);
            String[] strs = responseText.replace("{", "").replace("}", "").replace("\"", "").replace("\r", "").replace("\n", "").split(",");
            for (String sPair : strs) {
                String[] pair = sPair.split(":");
                String name = pair[0].trim().toLowerCase();
                String value = urlDecode(pair[1].trim());
                result.put(name, value);
            }

            return result;
        } catch (IOException e) {
            throw new IllegalAccessError(e.getMessage());
        }
    }

    static String readInputStream(InputStream is) {
        if (is == null)
            return "";

        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder result = new StringBuilder();
        String line;
        try {
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }
        } catch (IOException e) {
            // pasar por alto
        }
        return result.toString();
    }
}

Importar contactos desde una cuenta de Gmail

Los siguientes son los pasos para importar contactos desde una cuenta de Gmail en Java.

  • Cree un objeto de la clase OAuthUser e inicialícelo con correo electrónico, ID de cliente y secreto de cliente.
  • Cree dos objetos de cadena para almacenar el código de autorización y el verificador de código.
  • Obtenga token de actualización y token de acceso.
  • Obtenga una instancia de la clase GmailClient en un objeto IGmailClient mediante el método GmailClient.getInstance(String, String).
  • Leer contactos en una matriz usando el método IGmailClient.getAllContacts().
  • Recorra la matriz para acceder a cada contacto.

El siguiente ejemplo de código muestra cómo importar contactos de Gmail desde una cuenta en Java.

OAuthUser user = new OAuthUser();

// Establezca clientId, clientSecret y correo electrónico 
user.clientId = "<<clientID>>"; 
user.clientSecret = "<<clientSecret>>"; 
user.email = "<<email>>";

// Debe recuperar AuthorizationCode manualmente con AuthorizationCodeUrl generado
// Establecer código de autorización
String authorizationCode = "<<authCode>>";

// Copie Code Verifier de la salida del paso anterior
// Establecer códigoVerificador
String codeVerifier = "<<codeVerifier>>";

// Obtener token de actualización
String refreshToken = GoogleOAuthHelper.getAccessTokenByAuthCode(authorizationCode, codeVerifier, user);
user.refreshToken = refreshToken;

// Obtener token de acceso
String accessToken = GoogleOAuthHelper.getAccessTokenByRefreshToken(user);

// Usar token de acceso en la API
IGmailClient client = GmailClient.getInstance(accessToken, user.email);

Contact[] contacts = client.getAllContacts();
for (Contact contact : contacts)
	System.out.println(contact.getDisplayName() + ", " + contact.getEmailAddresses().get_Item(0));

Importar contactos de Gmail desde un grupo

También puede acceder a los contactos de un grupo de correo electrónico específico en Gmail siguiendo los pasos a continuación.

  • Siga los pasos mencionados en la sección anterior para inicializar IGmailClient.
  • Llame a IGmailClient.getAllGroups() para obtener grupos en un objeto ContactGroupCollection.
  • Filtre los grupos requeridos según el título.
  • Acceda a los contactos de un grupo usando el método IGmailClient.getContactsFromGroup(String).
  • Recorra la matriz para acceder a cada contacto.

El siguiente ejemplo de código muestra cómo importar contactos de un grupo específico de Gmail en Java.

OAuthUser user = new OAuthUser();

// Establezca clientId, clientSecret y correo electrónico 
user.clientId = "<<clientID>>"; 
user.clientSecret = "<<clientSecret>>"; 
user.email = "<<email>>";

// Debe recuperar AuthorizationCode manualmente con AuthorizationCodeUrl generado
// Establecer código de autorización
String authorizationCode = "<<authCode>>";

// Copie Code Verifier de la salida del paso anterior
// Establecer códigoVerificador
String codeVerifier = "<<codeVerifier>>";

// Obtener token de actualización
String refreshToken = GoogleOAuthHelper.getAccessTokenByAuthCode(authorizationCode, codeVerifier, user);
user.refreshToken = refreshToken;

// Obtener token de acceso
String accessToken = GoogleOAuthHelper.getAccessTokenByRefreshToken(user);

// Usar token de acceso en la API
IGmailClient client = GmailClient.getInstance(accessToken, user.email);

// Obtener contactos de un grupo específico
ContactGroupCollection groups = client.getAllGroups();
GoogleContactGroup group = null;
for (GoogleContactGroup g : groups) {
	if ("TestGroup".equals(g.getTitle())) {
		group = g;
	}
}

// Recuperar contactos del Grupo
if (group != null) {
	Contact[] contacts2 = client.getContactsFromGroup(group.getId());
	for (Contact con : contacts2)
		System.out.println(con.getDisplayName() + "," + con.getEmailAddresses().get_Item(0).toString());
}

Obtenga una licencia de API gratuita

Puede obtener una licencia temporal gratuita para usar Aspose.Email for Java sin limitaciones de evaluación.

Conclusión

En este artículo, ha aprendido cómo importar contactos de Gmail desde una cuenta mediante programación en Java. Además, ha visto cómo acceder a los contactos de un grupo de correo electrónico en particular en Gmail. Aparte de eso, puede explorar la documentación para leer más sobre Aspose.Email for Java. Además, puede hacer sus preguntas a través de nuestro foro.

Ver también