did you get this fixed?
@rehema.zoom i am having same issue below is my code
package edu4all.service;
import java.sql.Date;
import java.util.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
@Service
public class ZoomAuthService {
@Value("${zoom.client.id}")
private String clientId; // Your Zoom OAuth Client ID
@Value("${zoom.client.secret}")
private String clientSecret; // Your Zoom OAuth Client Secret
@Value("${zoom.redirect.uri}")
private String redirectUri; // Your Zoom OAuth Redirect URI
@Value("${zoom.access.token}")
private String storedAccessToken; // The stored access token from properties file
@Value("${zoom.refresh.token}")
private String storedRefreshToken; // The stored refresh token from properties file
private static final String ZOOM_OAUTH_TOKEN_URL = "https://zoom.us/oauth/token";
private static final String ZOOM_CREATE_MEETING_URL = "https://api.zoom.us/v2/users/me/meetings";
// Step 1: Create Zoom Meeting using JWT
public String createZoomMeeting() {
String accessToken = storedAccessToken; // Use the stored access token
// If the access token is expired, refresh it
if (isAccessTokenExpired()) {
accessToken = refreshAccessToken(storedRefreshToken);
}
String meetingUrl = ZOOM_CREATE_MEETING_URL;
// Create the body for the meeting creation request
String requestBody = "{\n" +
"\"topic\": \"LAKSHAN\",\n" +
"\"type\": 2,\n" +
"\"start_time\": \"2025-05-15T15:00:00Z\",\n" +
"\"duration\": 30,\n" +
"\"timezone\": \"UTC\",\n" +
"\"agenda\": \"Session Agenda\"\n" +
"}";
// Prepare headers with the access token
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + accessToken);
headers.set("Content-Type", "application/json");
// Make the request to create the meeting
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange(meetingUrl, HttpMethod.POST, new HttpEntity<>(requestBody, headers), String.class);
// Log the entire response
System.out.println("Zoom Meeting Creation Response: " + response.getBody());
// Extract the meeting number from the response (meeting ID)
String meetingNumber = extractMeetingId(response.getBody());
// Log the meeting number
System.out.println("Meeting Number (ID): " + meetingNumber);
return response.getBody();
}
// Helper method to extract the meeting ID (meeting number) from the response
private String extractMeetingId(String responseBody) {
try {
String meetingId = responseBody.split("\"id\":")[1].split(",")[0];
return meetingId;
} catch (Exception e) {
e.printStackTrace();
return null; // Return null if extraction fails
}
}
// Helper method to check if the access token is expired
private boolean isAccessTokenExpired() {
// You can implement token expiration check here (e.g., compare the expiration timestamp with current time)
return false;
}
// Step 2: Refresh the access token using the stored refresh token
private String refreshAccessToken(String refreshToken) {
String tokenUrl = ZOOM_OAUTH_TOKEN_URL;
// Construct the Basic Authorization header
String authHeader = "Basic " + Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes());
// Prepare the body for refreshing the access token
String body = "grant_type=refresh_token&refresh_token=" + refreshToken;
// Prepare the HTTP request headers
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", authHeader);
headers.set("Content-Type", "application/x-www-form-urlencoded");
// Send the request to Zoom's OAuth endpoint
RestTemplate restTemplate = new RestTemplate();
HttpEntity<String> entity = new HttpEntity<>(body, headers);
ResponseEntity<String> response = restTemplate.exchange(tokenUrl, HttpMethod.POST, entity, String.class);
// Log and return the response from Zoom (contains the new access token)
System.out.println("Zoom OAuth Token Refresh Response: " + response.getBody());
// Extract and return the new access token from the response
return extractAccessToken(response.getBody());
}
// Helper method to extract the access token from the response
private String extractAccessToken(String responseBody) {
String accessToken = responseBody.split("\"access_token\":\"")[1].split("\"")[0];
return accessToken;
}
// Method to generate a JWT signature for Zoom Meeting
public String generateJWT(String meetingNumber, String role) {
try {
// Current time and expiration
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
Date exp = new Date(nowMillis + 10 * 60 * 1000); // 10 minutes expiration
// Build JWT claims
JWTClaimsSet claims = new JWTClaimsSet.Builder()
.claim("sdkKey", clientId)
.claim("appKey", clientId)
.claim("mn", Long.parseLong(meetingNumber))
.claim("role", Integer.parseInt(role))
.issueTime(now)
.expirationTime(exp)
.claim("tokenExp", exp.getTime() / 1000) // tokenExp in seconds
.build();
// Create HMAC signer
JWSSigner signer = new MACSigner(clientSecret.getBytes());
// Prepare JWS object with HS256 algorithm
SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.HS256), claims);
// Apply the HMAC protection
signedJWT.sign(signer);
// Serialize to compact form, this is your JWT token (signature)
return signedJWT.serialize();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// Method to generate the JWT signature using HMAC SHA256
private String HmacSHA256(String payload, String key) {
try {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] bytes = sha256_HMAC.doFinal(payload.getBytes());
return Base64.getEncoder().encodeToString(bytes);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}