Skip to content

Commit 128f207

Browse files
committed
feat: add Gmail list messages sample
Add Gmail sample for listing messages and corresponding unit test. Based on the `list_messages` sample from Python.
1 parent 19db17d commit 128f207

File tree

2 files changed

+231
-0
lines changed

2 files changed

+231
-0
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// [START gmail_list_messages]
16+
17+
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
18+
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
19+
import com.google.api.client.http.HttpRequestInitializer;
20+
import com.google.api.client.json.gson.GsonFactory;
21+
import com.google.api.services.gmail.Gmail;
22+
import com.google.api.services.gmail.GmailScopes;
23+
import com.google.api.services.gmail.model.ListMessagesResponse;
24+
import com.google.api.services.gmail.model.Message;
25+
import com.google.auth.http.HttpCredentialsAdapter;
26+
import com.google.auth.oauth2.GoogleCredentials;
27+
28+
import java.io.IOException;
29+
import java.security.GeneralSecurityException;
30+
import java.util.Collections;
31+
import java.util.List;
32+
33+
/*
34+
* Class to demonstrate the use of Gmail List Messages API
35+
*/
36+
public class ListMessages {
37+
38+
/**
39+
* Lists the user's Gmail messages.
40+
*
41+
* @param service Authorized Gmail API instance.
42+
* @return List of Messages in the user's mailbox.
43+
* @throws IOException if the request to retrieve messages fails.
44+
* @throws GoogleJsonResponseException if the execution of the request fails.
45+
*/
46+
public static List<Message> listMessages(Gmail service) throws IOException {
47+
48+
try {
49+
final long maxMessages = 10L;
50+
final String userId = "me";
51+
ListMessagesResponse results =
52+
service
53+
.users()
54+
.messages()
55+
.list(userId)
56+
.setLabelIds(Collections.singletonList("INBOX"))
57+
.setMaxResults(maxMessages)
58+
.execute();
59+
60+
List<Message> messages = results.getMessages();
61+
62+
if (messages == null || messages.isEmpty()) {
63+
System.out.println("No messages found.");
64+
return messages;
65+
}
66+
67+
System.out.println("Messages:");
68+
for (Message message : messages) {
69+
/*TODO(developer) - Consider batch requests if you need to retrieve many messages at once.
70+
See https://developers.google.com/workspace/gmail/api/guides/batch for implementation guides. */
71+
Message msg = service.users().messages().get(userId, message.getId()).execute();
72+
73+
System.out.printf("- Message ID: %s%n Snippet: %s%n", message.getId(), msg.getSnippet());
74+
}
75+
return messages;
76+
} catch (GoogleJsonResponseException e) {
77+
// TODO(developer) - handle error appropriately
78+
System.err.println("An error occurred: " + e);
79+
throw e;
80+
}
81+
}
82+
83+
private static Gmail getGmailService() throws IOException, GeneralSecurityException {
84+
/* Load pre-authorized user credentials from the environment.
85+
TODO(developer) - See https://developers.google.com/identity for
86+
guides on implementing OAuth2 for your application. */
87+
GoogleCredentials credentials =
88+
GoogleCredentials.getApplicationDefault().createScoped(GmailScopes.GMAIL_READONLY);
89+
HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials);
90+
91+
// Create the gmail API client
92+
return new Gmail.Builder(
93+
GoogleNetHttpTransport.newTrustedTransport(),
94+
GsonFactory.getDefaultInstance(),
95+
requestInitializer)
96+
.setApplicationName("Gmail samples")
97+
.build();
98+
}
99+
}
100+
101+
// [END gmail_list_messages]
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
16+
import com.google.api.client.http.HttpTransport;
17+
import com.google.api.client.http.LowLevelHttpRequest;
18+
import com.google.api.client.http.LowLevelHttpResponse;
19+
import com.google.api.client.json.Json;
20+
import com.google.api.client.json.gson.GsonFactory;
21+
import com.google.api.client.testing.http.MockHttpTransport;
22+
import com.google.api.client.testing.http.MockLowLevelHttpRequest;
23+
import com.google.api.client.testing.http.MockLowLevelHttpResponse;
24+
import com.google.api.services.gmail.Gmail;
25+
import com.google.api.services.gmail.model.Message;
26+
import org.junit.Test;
27+
28+
import java.io.IOException;
29+
import java.util.List;
30+
31+
import static org.junit.Assert.assertEquals;
32+
import static org.junit.Assert.assertNotNull;
33+
import static org.junit.Assert.assertThrows;
34+
import static org.junit.Assert.assertTrue;
35+
36+
// Unit test case for gmail list messages snippet
37+
public class TestListMessages {
38+
39+
@Test
40+
public void testListMessagesReturnsMessages() throws IOException {
41+
HttpTransport transport =
42+
new MockHttpTransport() {
43+
@Override
44+
public LowLevelHttpRequest buildRequest(String method, String url) {
45+
return new MockLowLevelHttpRequest() {
46+
@Override
47+
public LowLevelHttpResponse execute() {
48+
MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
49+
response.setStatusCode(200);
50+
response.setContentType(Json.MEDIA_TYPE);
51+
52+
// Mock response for listing messages in the inbox
53+
if (url.contains("/messages") && url.contains("labelIds=INBOX")) {
54+
response.setContent("{\"messages\": [{\"id\": \"12345\"}]}");
55+
} else if (url.contains("/messages/12345")) {
56+
response.setContent(
57+
"{\"id\": \"12345\", \"snippet\": \"This is a test snippet.\"}");
58+
} else {
59+
response.setStatusCode(404);
60+
}
61+
return response;
62+
}
63+
};
64+
}
65+
};
66+
67+
Gmail service = getMockGmailService(transport);
68+
List<Message> result = ListMessages.listMessages(service);
69+
70+
assertNotNull("The returned message list should not be null", result);
71+
assertEquals("The returned list should contain exactly one message", 1, result.size());
72+
assertEquals("The message ID should match the mock data", "12345", result.get(0).getId());
73+
}
74+
75+
@Test
76+
public void testListMessagesHandlesApiError() {
77+
// Mock transport simulates a 404 Not Found error
78+
HttpTransport errorTransport =
79+
new MockHttpTransport() {
80+
@Override
81+
public LowLevelHttpRequest buildRequest(String method, String url) {
82+
return new MockLowLevelHttpRequest() {
83+
@Override
84+
public LowLevelHttpResponse execute() {
85+
MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
86+
response.setStatusCode(404);
87+
response.setContentType(Json.MEDIA_TYPE);
88+
response.setContent("{\"error\": {\"code\": 404, \"message\": \"Not Found\"}}");
89+
return response;
90+
}
91+
};
92+
}
93+
};
94+
95+
Gmail service = getMockGmailService(errorTransport);
96+
assertThrows(GoogleJsonResponseException.class, () -> ListMessages.listMessages(service));
97+
}
98+
99+
@Test
100+
public void testListMessagesHandlesEmptyResults() throws IOException {
101+
// Mock transport returns empty messages array
102+
HttpTransport emptyTransport =
103+
new MockHttpTransport() {
104+
@Override
105+
public LowLevelHttpRequest buildRequest(String method, String url) {
106+
return new MockLowLevelHttpRequest() {
107+
@Override
108+
public LowLevelHttpResponse execute() {
109+
MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
110+
response.setStatusCode(200);
111+
response.setContentType(Json.MEDIA_TYPE);
112+
response.setContent("{\"messages\": []}");
113+
return response;
114+
}
115+
};
116+
}
117+
};
118+
119+
Gmail service = getMockGmailService(emptyTransport);
120+
List<Message> result = ListMessages.listMessages(service);
121+
assertNotNull("Should return an empty list when no messages found", result);
122+
assertTrue("Returned list should be empty", result.isEmpty());
123+
}
124+
125+
private Gmail getMockGmailService(HttpTransport transport) {
126+
return new Gmail.Builder(transport, GsonFactory.getDefaultInstance(), request -> {})
127+
.setApplicationName("Gmail API Snippets")
128+
.build();
129+
}
130+
}

0 commit comments

Comments
 (0)