Skip to content

Commit d492e92

Browse files
committed
Feat: Meet API quickstart
1 parent e3102ab commit d492e92

File tree

4 files changed

+210
-0
lines changed

4 files changed

+210
-0
lines changed

meet/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Additional samples can be found at https://github.com/googleapis/google-cloud-java/tree/main/java-meet/google-cloud-meet

meet/quickstart/build.gradle

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
apply plugin: 'java'
2+
apply plugin: 'application'
3+
4+
mainClassName = 'MeetQuickstart'
5+
sourceCompatibility = 11
6+
targetCompatibility = 11
7+
version = '1.0'
8+
9+
repositories {
10+
mavenCentral()
11+
}
12+
13+
dependencies {
14+
implementation 'com.google.cloud:google-cloud-meet:0.3.0'
15+
implementation 'com.google.auth:google-auth-library-oauth2-http:1.19.0'
16+
implementation 'com.google.oauth-client:google-oauth-client-jetty:1.34.1'
17+
}

meet/quickstart/settings.gradle

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* This settings file was generated by the Gradle 'init' task.
3+
*
4+
* The settings file is used to specify which projects to include in your build.
5+
* In a single project build this file can be empty or even removed.
6+
*
7+
* Detailed information about configuring a multi-project build in Gradle can be found
8+
* in the user guide at https://docs.gradle.org/3.5/userguide/multi_project_builds.html
9+
*/
10+
11+
/*
12+
// To declare projects as part of a multi-project build use the 'include' method
13+
include 'shared'
14+
include 'api'
15+
include 'services:webservice'
16+
*/
17+
18+
rootProject.name = 'quickstart'
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
// Copyright 2024 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+
// http://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 meet_quickstart]
16+
17+
import java.awt.Desktop;
18+
import java.io.FileNotFoundException;
19+
import java.io.IOException;
20+
import java.io.InputStream;
21+
import java.net.URI;
22+
import java.net.URL;
23+
import java.nio.file.Files;
24+
import java.nio.file.Path;
25+
import java.nio.file.Paths;
26+
import java.util.Collections;
27+
import java.util.List;
28+
29+
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
30+
import com.google.api.gax.core.FixedCredentialsProvider;
31+
import com.google.apps.meet.v2.CreateSpaceRequest;
32+
import com.google.apps.meet.v2.Space;
33+
import com.google.apps.meet.v2.SpacesServiceClient;
34+
import com.google.apps.meet.v2.SpacesServiceSettings;
35+
import com.google.auth.Credentials;
36+
import com.google.auth.oauth2.ClientId;
37+
import com.google.auth.oauth2.DefaultPKCEProvider;
38+
import com.google.auth.oauth2.TokenStore;
39+
import com.google.auth.oauth2.UserAuthorizer;
40+
41+
/* class to demonstrate use of Drive files list API */
42+
public class MeetQuickstart {
43+
/**
44+
* Directory to store authorization tokens for this application.
45+
*/
46+
private static final String TOKENS_DIRECTORY_PATH = "tokens";
47+
48+
/**
49+
* Global instance of the scopes required by this quickstart.
50+
* If modifying these scopes, delete your previously saved tokens/ folder.
51+
*/
52+
private static final List<String> SCOPES = Collections
53+
.singletonList("https://www.googleapis.com/auth/meetings.space.created");
54+
55+
private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
56+
57+
private static final String USER = "default";
58+
59+
// Simple file-based token storage for storing oauth tokens
60+
private static final TokenStore TOKEN_STORE = new TokenStore() {
61+
private Path pathFor(String id) {
62+
return Paths.get(".", TOKENS_DIRECTORY_PATH, id + ".json");
63+
}
64+
65+
@Override
66+
public String load(String id) throws IOException {
67+
if (!Files.exists(pathFor(id))) {
68+
return null;
69+
}
70+
return Files.readString(pathFor(id));
71+
}
72+
73+
@Override
74+
public void store(String id, String token) throws IOException {
75+
Files.createDirectories(Paths.get(".", TOKENS_DIRECTORY_PATH));
76+
Files.writeString(pathFor(id), token);
77+
}
78+
79+
@Override
80+
public void delete(String id) throws IOException {
81+
if (!Files.exists(pathFor(id))) {
82+
return;
83+
}
84+
Files.delete(pathFor(id));
85+
}
86+
};
87+
88+
/**
89+
* Initialize a UserAuthorizer for local authorization.
90+
*
91+
* @param callbackUri
92+
* @return
93+
*/
94+
private static UserAuthorizer getAuthorizer(URI callbackUri) throws IOException {
95+
// Load client secrets.
96+
try (InputStream in = MeetQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH)) {
97+
if (in == null) {
98+
throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
99+
}
100+
101+
ClientId clientId = ClientId.fromStream(in);
102+
103+
UserAuthorizer authorizer = UserAuthorizer.newBuilder()
104+
.setClientId(clientId)
105+
.setCallbackUri(callbackUri)
106+
.setScopes(SCOPES)
107+
.setPKCEProvider(new DefaultPKCEProvider() {
108+
// Temporary fix for https://github.com/googleapis/google-auth-library-java/issues/1373
109+
@Override
110+
public String getCodeChallenge() {
111+
return super.getCodeChallenge().split("=")[0];
112+
}
113+
})
114+
.setTokenStore(TOKEN_STORE).build();
115+
return authorizer;
116+
}
117+
}
118+
119+
/**
120+
* Run the OAuth2 flow for local/installed app.
121+
*
122+
* @return An authorized Credential object.
123+
* @throws IOException If the credentials.json file cannot be found.
124+
*/
125+
private static Credentials getCredentials()
126+
throws Exception {
127+
128+
LocalServerReceiver receiver = new LocalServerReceiver.Builder().build();
129+
try {
130+
URI callbackUri = URI.create(receiver.getRedirectUri());
131+
UserAuthorizer authorizer = getAuthorizer(callbackUri);
132+
133+
Credentials credentials = authorizer.getCredentials(USER);
134+
if (credentials != null) {
135+
return credentials;
136+
}
137+
138+
URL authorizationUrl = authorizer.getAuthorizationUrl(USER, "", null);
139+
if (Desktop.isDesktopSupported() &&
140+
Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
141+
Desktop.getDesktop().browse(authorizationUrl.toURI());
142+
} else {
143+
System.out.printf("Open the following URL to authorize access: %s\n",
144+
authorizationUrl.toExternalForm());
145+
}
146+
147+
String code = receiver.waitForCode();
148+
credentials = authorizer.getAndStoreCredentialsFromCode(USER, code, callbackUri);
149+
return credentials;
150+
} finally {
151+
receiver.stop();
152+
}
153+
}
154+
155+
public static void main(String... args) throws Exception {
156+
// Override default service settings to supply user credentials.
157+
Credentials credentials = getCredentials();
158+
SpacesServiceSettings settings = SpacesServiceSettings.newBuilder()
159+
.setCredentialsProvider(FixedCredentialsProvider.create(credentials))
160+
.build();
161+
162+
try (SpacesServiceClient spacesServiceClient = SpacesServiceClient.create(settings)) {
163+
CreateSpaceRequest request = CreateSpaceRequest.newBuilder()
164+
.setSpace(Space.newBuilder().build())
165+
.build();
166+
Space response = spacesServiceClient.createSpace(request);
167+
System.out.printf("Space created: %s\n", response.getMeetingUri());
168+
} catch (IOException e) {
169+
// TODO(developer): Handle errors
170+
e.printStackTrace();
171+
}
172+
}
173+
}
174+
// [END meet_quickstart]

0 commit comments

Comments
 (0)