Java에서 프로그래밍 방식으로 Gmail 연락처 가져오기

Google의 Gmail은 가장 인기 있고 일반적으로 사용되는 이메일 서비스입니다. Gmail은 캘린더, 채팅 등과 같은 이메일을 주고받는 것과 함께 다양한 기능을 제공합니다. 경우에 따라 Gmail에 연결하고 애플리케이션 내에서 프로그래밍 방식으로 연락처를 가져와야 할 수도 있습니다. 이를 달성하기 위해 이 문서에서는 Java를 사용하여 Gmail 연락처를 가져오는 방법을 보여줍니다. 또한 특정 이메일 그룹의 연락처에 액세스하는 방법을 다룹니다.

Gmail 연락처를 가져오는 Java API

Aspose.Email for Java는 이메일 클라이언트 애플리케이션을 생성하는 강력한 API입니다. 또한 연락처, 캘린더, 약속 등에 액세스하는 것과 같은 Gmail 작업을 지원합니다. 이 API를 사용하여 Gmail 계정에 액세스하고 연락처를 가져올 것입니다. API를 다운로드하거나 다음 Maven 구성을 사용하여 설치할 수 있습니다.

저장소:

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

의존:

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

Java의 Gmail에서 연락처 가져오기

시작하기 전에 Google 개발자 콘솔에서 코드를 실행할 수 있는 프로젝트를 만들어야 합니다. 생성하려면 이 가이드를 따르세요.

이제 Gmail 계정 인증을 처리하기 위해 GoogleOAuthHelper라는 도우미 클래스를 만듭니다. 또한 사용자 정보를 저장할 OAuthUser라는 클래스를 생성합니다. 다음은 두 클래스의 완전한 구현입니다.

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>
 * 개발자 콘솔 https://console.developers.google.com/projectselector/apis/credentials?pli=1 
 * 문서 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) {
            // 무시하다
        }
        return result.toString();
    }
}

Gmail 계정에서 연락처 가져오기

다음은 Java의 Gmail 계정에서 연락처를 가져오는 단계입니다.

  • OAuthUser 클래스의 객체를 생성하고 이메일, 클라이언트 ID 및 클라이언트 시크릿으로 초기화합니다.
  • 인증 코드와 코드 검증기를 저장할 두 개의 문자열 개체를 만듭니다.
  • 새로 고침 토큰과 액세스 토큰을 가져옵니다.
  • GmailClient.getInstance(String, String) 메소드를 사용하여 GmailClient 클래스의 인스턴스를 IGmailClient 객체로 가져옵니다.
  • IGmailClient.getAllContacts() 메서드를 사용하여 연락처를 배열로 읽습니다.
  • 배열을 통해 루프를 통해 각 연락처에 액세스합니다.

다음 코드 샘플은 Java 계정에서 Gmail 연락처를 가져오는 방법을 보여줍니다.

OAuthUser user = new OAuthUser();

// clientId, clientSecret 및 이메일 설정 
user.clientId = "<<clientID>>"; 
user.clientSecret = "<<clientSecret>>"; 
user.email = "<<email>>";

// 생성된 AuthorizationCodeUrl을 사용하여 AuthorizationCode를 수동으로 검색해야 합니다.
// 인증 코드 설정
String authorizationCode = "<<authCode>>";

// 이전 단계 출력에서 코드 검증기 복사
// codeVerifier 설정
String codeVerifier = "<<codeVerifier>>";

// 새로 고침 토큰 받기
String refreshToken = GoogleOAuthHelper.getAccessTokenByAuthCode(authorizationCode, codeVerifier, user);
user.refreshToken = refreshToken;

// 액세스 토큰 받기
String accessToken = GoogleOAuthHelper.getAccessTokenByRefreshToken(user);

// 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));

그룹에서 Gmail 연락처 가져오기

아래 단계에 따라 Gmail의 특정 이메일 그룹에서 연락처에 액세스할 수도 있습니다.

  • 이전 섹션에서 언급한 단계에 따라 IGmailClient를 초기화합니다.
  • IGmailClient.getAllGroups()를 호출하여 그룹을 ContactGroupCollection 객체로 가져옵니다.
  • 제목에 따라 필요한 그룹을 필터링합니다.
  • IGmailClient.getContactsFromGroup(String) 메서드를 사용하여 그룹에서 연락처에 액세스합니다.
  • 배열을 통해 루프를 통해 각 연락처에 액세스합니다.

다음 코드 샘플은 Java의 특정 Gmail 그룹에서 연락처를 가져오는 방법을 보여줍니다.

OAuthUser user = new OAuthUser();

// clientId, clientSecret 및 이메일 설정 
user.clientId = "<<clientID>>"; 
user.clientSecret = "<<clientSecret>>"; 
user.email = "<<email>>";

// 생성된 AuthorizationCodeUrl을 사용하여 AuthorizationCode를 수동으로 검색해야 합니다.
// 인증 코드 설정
String authorizationCode = "<<authCode>>";

// 이전 단계 출력에서 코드 검증기 복사
// codeVerifier 설정
String codeVerifier = "<<codeVerifier>>";

// 새로 고침 토큰 받기
String refreshToken = GoogleOAuthHelper.getAccessTokenByAuthCode(authorizationCode, codeVerifier, user);
user.refreshToken = refreshToken;

// 액세스 토큰 받기
String accessToken = GoogleOAuthHelper.getAccessTokenByRefreshToken(user);

// API에서 액세스 토큰 사용
IGmailClient client = GmailClient.getInstance(accessToken, user.email);

// 특정 그룹에서 연락처 가져오기
ContactGroupCollection groups = client.getAllGroups();
GoogleContactGroup group = null;
for (GoogleContactGroup g : groups) {
	if ("TestGroup".equals(g.getTitle())) {
		group = g;
	}
}

// 그룹에서 연락처 검색
if (group != null) {
	Contact[] contacts2 = client.getContactsFromGroup(group.getId());
	for (Contact con : contacts2)
		System.out.println(con.getDisplayName() + "," + con.getEmailAddresses().get_Item(0).toString());
}

무료 API 라이선스 받기

평가 제한 없이 Aspose.Email for Java를 사용할 수 있는 무료 임시 라이선스를 얻을 수 있습니다.

결론

이 기사에서는 Java에서 프로그래밍 방식으로 계정에서 Gmail 연락처를 가져오는 방법을 배웠습니다. 또한 Gmail에서 특정 이메일 그룹의 연락처에 액세스하는 방법을 살펴보았습니다. 그 외에도 문서를 탐색하여 Java용 Aspose.Email에 대해 자세히 알아볼 수 있습니다. 또한 포럼을 통해 질문할 수 있습니다.

또한보십시오