This is my code, its working fine. but if refresh a page, getting 400 error.
and log shows code already redeemed. please suggest where is error. I used refresh token also even though getting error.
refresh token correctly used?
Thanks
HttpSession session = req.getSession(true); //create user session
try {
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JacksonFactory jsonFactory = JacksonFactory.getDefaultInstance();
//String redirectUrl = "urn:ietf:wg:oauth:2.0:oob";
String scope = "https://www.googleapis.com/auth/calendar";
String code = req.getParameter("code");
String eventid = req.getParameter("eventid");
if(eventid != null)
session.setAttribute("eventid", req.getParameter("eventid"));
GoogleTokenResponse response=null;
Credential credential=null;
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, jsonFactory, CLIENT_ID, CLIENT_SECRET, Collections.singleton(scope)).setAccessType("offline").setApprovalPrompt("force").build();
if(code == null){
String authorizationUrl = new GoogleAuthorizationCodeRequestUrl(CLIENT_ID,REDIRECT_URI,Collections.singleton(scope)).setState("").build();
resp.sendRedirect(authorizationUrl);
}else{
response = flow.newTokenRequest(code).setRedirectUri(REDIRECT_URI)
.execute();
// End of Step 2
flow.createAndStoreCredential(response, null);
}
// Step 2: Exchange
if(session.getAttribute("refresh") != null){
credential = new GoogleCredential.Builder().setTransport(httpTransport).setJsonFactory(jsonFactory).setClientSecrets(CLIENT_ID, CLIENT_SECRET)
.build().setFromTokenResponse((new TokenResponse().setRefreshToken(session.getAttribute("refresh").toString())));
credential.refreshToken();
}else{
credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setClientSecrets(CLIENT_ID, CLIENT_SECRET)
.build().setFromTokenResponse(response);
session.setAttribute("refresh", credential.getRefreshToken());
}
Calendar service = new Calendar.Builder(httpTransport, jsonFactory, credential)
.setApplicationName("Minutes Of Meeting").build();
List<CalEvent> lstEvent = new ArrayList<CalEvent>();
Date d1= getRelativeDate(java.util.Calendar.MONTH, -1);
String pageToken = null;
do {
Events events = service.events().list("primary").setTimeMin(new DateTime(d1,TimeZone.getTimeZone("IST"))).setPageToken(pageToken).execute();
List<Event> items = events.getItems();
for (Event event : items) {
//System.out.println("Event Name: " + event.getSummary() + " Event Organiser :"+event.getOrganizer()+" Event Guest"+event.getAttendees());
//lstEvent.put(event.getSummary(),event.getSummary());
//lstEvent.put(event.getOrganizer().getDisplayName(),event.getOrganizer().getDisplayName());
if(event.getStart().isEmpty()){
List attees = event.getAttendees();
lstEvent.add(new CalEvent(event.getId(),event.getSummary(),event.getOrganizer().getDisplayName(),event.getLocation(),"","",attees));
}else{
Long dt = event.getStart().getDateTime()==null?0:event.getStart().getDateTime().getValue();
Date dt11 = new Date(dt);
Long dt1 = event.getEnd().getDateTime()==null?0:event.getEnd().getDateTime().getValue();
Date dt111 = new Date(dt1);
List attees = event.getAttendees();
lstEvent.add(new CalEvent(event.getId(),event.getSummary(),event.getOrganizer().getDisplayName(),event.getLocation(),dt11.toString(),dt111.toString(),attees));
}
//Date returnd = new Date(dt11.getTime()+(330*60000));
//Date returned = new Date(dt111.getTime()+(330*60000));
}
pageToken = events.getNextPageToken();
} while (pageToken != null);
req.setAttribute("events", lstEvent);
RequestDispatcher rd = req.getRequestDispatcher("/Home.jsp");
try {
rd.forward(req, resp);
} catch (ServletException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
please help me solve this issue
Related
The application freezes while Google Calendar API authentication is in progress.
Below is my source code.
private final String APPLICATION_NAME = "Google Calendar API Java Quickstart";
private java.io.File DATA_STORE_DIR;
private FileDataStoreFactory DATA_STORE_FACTORY;
private final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private HttpTransport HTTP_TRANSPORT;
private final List<String> SCOPES = Arrays.asList(CalendarScopes.CALENDAR);
#Value("#{config['path.googleAuth']}")
private String googleAuthPath;
public void setGoogleData(String member_id_num) throws Exception{
String userHome = "";
if(System.getProperty("os.name").toLowerCase().indexOf("win") >= 0) {
userHome = System.getProperty("user.home");
}else if(System.getProperty("os.name").toLowerCase().indexOf("linux") >= 0) {
userHome = googleAuthPath;
}else {
userHome = System.getProperty("user.home");
}
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
DATA_STORE_DIR = new java.io.File(userHome,".credentials_sellers/calendar-java-quickstart_sellers"+File.separator+member_id_num);
DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
log.info("DATA_STORE_DIR=" + DATA_STORE_DIR);
}
public Credential authorize(String member_id_num) throws Exception {
setGoogleData(member_id_num);
InputStream in = GoogleCalendarService.class.getResourceAsStream("/client_secret.json");
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
log.info("clientSecrets = " + clientSecrets);
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY,
clientSecrets, SCOPES).setDataStoreFactory(DATA_STORE_FACTORY).setAccessType("offline").build();
Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
log.info("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
return credential;
}
my client_secret.json
{
"installed": {
"client_id": "459740830795-lm5pnqsule6jg4ufu3uvnufgr7tdajn6.apps.googleusercontent.com",
"project_id": "the-sellers-255504",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "L3kDYxfDoSDUG5wM3XEMDi9H",
"redirect_uris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost", "http://xxx.xxx.x.xxx", "http://xxx.xxx.x.xxx:8090", "http://xxx.xxx.x.xxx", "http://xxx.xxx.x.xxx:8090"]
}
}
In my local environment, the test was successful.
However, the website hangs because I try to link it to a Linux server.
help me please ....
Using ExchangeService I need to get Calendar folder and retrieve all events there
It's done by this piece of code
private List getRoomCalendar() throws Exception {
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
ExchangeCredentials credentials = new WebCredentials(username, password);
service.setCredentials(credentials);
service.setUrl(new URI(msExchangeUrl));
FolderView fv = new FolderView(100);
fv.setTraversal(FolderTraversal.Deep);
FolderId confRoomFolderId = new FolderId(WellKnownFolderName.Calendar, new Mailbox(username));
System.out.println(confRoomFolderId.getFolderName());
List events = new ArrayList();
Date date = new Date();
try {
CalendarFolder calendarFolder = CalendarFolder.bind(service, confRoomFolderId);
CalendarView cView = new CalendarView(new DateTime(date).minusDays(1).toDate(),
new DateTime(date).plusDays(1).toDate(), 100);
cView.setPropertySet(new PropertySet(AppointmentSchema.Subject,
AppointmentSchema.Start,
AppointmentSchema.End));
// we can set other properties as well depending upon our need.
FindItemsResults appointments = calendarFolder.findAppointments(cView);
List<Appointment> appList = appointments.getItems();
for (Appointment appointment : appList) {
Map event = readEvent(appointment);
events.add(event);
}
} catch (Exception e) {
e.printStackTrace();
}
return events;
}
private Map readEvent(Appointment appointment) {
Map appointmentData = new HashMap();
try {
DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
appointmentData.put("appointmentSubject", appointment.getSubject());
appointmentData.put("appointmentStartTime", df.format(appointment.getStart()));
appointmentData.put("appointmentEndTime", df.format(appointment.getEnd()));
} catch (ServiceLocalException e) {
e.printStackTrace();
}
return appointmentData;
}
Cool, it's working and returns these data
default MS Calendar
The question is: how can I get events for MY CUSTOM CALENDAR called name
see here
custom MS calendar
The solution is to create the folderView first. Afterwards, apply a search filter, find it using FindFolderResults.
PropertySet psPropset = new PropertySet(BasePropertySet.FirstClassProperties);
FolderView fvFolderView = new FolderView(1);
fvFolderView.setPropertySet(psPropset);
SearchFilter SfSearchFilter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName,"name");
FindFoldersResults findFoldersResults = service.findFolders(confRoomFolderId, SfSearchFilter, fvFolderView);
System.out.println(findFoldersResults.getFolders().get(0).getDisplayName());
I basically have a dynamic WEB-APP which through a servlet I am trying to retrieve a youtube video comments.
Although there is alot of article about it in the web but I don't know why none worked for me.
First Attempt:
private static int counter = 0;
private static YouTube youtube;
public static void getYoutubeOauth() throws Exception {
List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube.force-ssl");
Credential credential = Auth.authorize(scopes, "commentthreads");
youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential).build();
String videoId = "KIgxmV9xXBQ";
// Get video comments threads
CommentThreadListResponse commentsPage = prepareListRequest(videoId).execute();
while (true) {
handleCommentsThreads(commentsPage.getItems());
String nextPageToken = commentsPage.getNextPageToken();
if (nextPageToken == null)
break;
// Get next page of video comments threads
commentsPage = prepareListRequest(videoId).setPageToken(nextPageToken).execute();
}
System.out.println("Total: " + counter);
}
With this I am getting nullpointerexception at line: Credential credential = Auth.authorize(scopes, "commentthreads");
If you can please explain what is scope and where do you get it from.
Second Attempt I tried creating a different function for getting credentials.
Second Attempt:
public static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
public static final JsonFactory JSON_FACTORY = new JacksonFactory();
private static final String CREDENTIALS_DIRECTORY = ".oauth-credentials";
public static Credential authorize(List<String> scopes, String credentialDatastore) throws IOException {
// Load client secrets.
Reader clientSecretReader = new InputStreamReader(
Auth.class.getResourceAsStream("/home/hazrat/Documents/eclipse-jee-neon-3-linux-gtk-x86_64/eclipse/client_secrets.json"));
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, clientSecretReader);
// Checks that the defaults have been replaced (Default = "Enter X here").
if (clientSecrets.getDetails().getClientId().startsWith("Enter")
|| clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.out.println(
"Enter Client ID and Secret from https://console.developers.google.com/project/_/apiui/credential "
+ "into src/main/resources/client_secrets.json");
return null;
}
// This creates the credentials datastore at ~/.oauth-credentials/${credentialDatastore}
FileDataStoreFactory fileDataStoreFactory = new FileDataStoreFactory(new File(System.getProperty("user.home") + "/" + CREDENTIALS_DIRECTORY));
DataStore<StoredCredential> datastore = fileDataStoreFactory.getDataStore(credentialDatastore);
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, scopes).setCredentialDataStore(datastore)
.build();
// Build the local server and bind it to port 8080
LocalServerReceiver localReceiver = new LocalServerReceiver.Builder().setPort(8080).build();
// Authorize.
return new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user");
}
Here also Im getting an nullpointerexception at line Reader clientSecretReader = new InputStreamReader(... although If I would try nano /home/hazrat/Documents/eclipse-jee-neon-3-linux-gtk-x86_64/eclipse/client_secrets.json in my terminal I can access the file.
Question: How to authorize my web-app and read client_secrets.json from an external directory.
Was a bit painful but made the second solution working.
So what I was doing wrong was that I was calling Auth.class.getResourceAsStream which it requires the data to be available to classLoader but to my classLoader it was not.
so what I had to do is to request my client_secrets.json from an external directory which then you have to use FileInputStream other than getResourceAsStream.
Both FileInputStream and getResourceAsStream works fine but they differ on your situation and different code.
public static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
public static final JsonFactory JSON_FACTORY = new JacksonFactory();
private static final String CREDENTIALS_DIRECTORY = ".oauth-credentials";
public static Credential authorize(List<String> scopes, String credentialDatastore) throws IOException {
Reader clientSecretReader = new InputStreamReader(
new FileInputStream("/client_secrets.json"));
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, clientSecretReader);
System.out.println(clientSecretReader.toString());
if (clientSecrets.getDetails().getClientId().startsWith("Enter")
|| clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.out.println(
"Enter Client ID and Secret from https://console.developers.google.com/project/_/apiui/credential "
+ "into src/main/resources/client_secrets.json");
return null;
}
FileDataStoreFactory fileDataStoreFactory = new FileDataStoreFactory(new File(System.getProperty("user.home") + "/" + CREDENTIALS_DIRECTORY));
DataStore<StoredCredential> datastore = fileDataStoreFactory.getDataStore(credentialDatastore);
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, scopes).setCredentialDataStore(datastore)
.build();
LocalServerReceiver localReceiver = new LocalServerReceiver.Builder().setPort(8081).build();
return new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user");
}
private static int counter = 0;
private static YouTube youtube;
public static void getYoutubeOauth() throws Exception {
List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube.force-ssl");
Credential credential = authorize(scopes, "commentthreads");
youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential).build();
String videoId = "KIgxmV9xXBQ";
// Get video comments threads
CommentThreadListResponse commentsPage = prepareListRequest(videoId).execute();
while (true) {
handleCommentsThreads(commentsPage.getItems());
String nextPageToken = commentsPage.getNextPageToken();
if (nextPageToken == null)
break;
commentsPage = prepareListRequest(videoId).setPageToken(nextPageToken).execute();
}
System.out.println("Total: " + counter);
}
private static YouTube.CommentThreads.List prepareListRequest(String videoId) throws Exception {
return youtube.commentThreads()
.list("snippet,replies")
.setVideoId(videoId)
.setMaxResults(100L)
.setModerationStatus("published")
.setTextFormat("plainText");
}
private static void handleCommentsThreads(List<CommentThread> commentThreads) {
for (CommentThread commentThread : commentThreads) {
List<Comment> comments = Lists.newArrayList();
comments.add(commentThread.getSnippet().getTopLevelComment());
CommentThreadReplies replies = commentThread.getReplies();
if (replies != null)
comments.addAll(replies.getComments());
System.out.println("Found " + comments.size() + " comments.");
// Do your comments logic here
counter += comments.size();
}
}
Note: change FileInputStream location to your own location.
Then you can call getYoutubeOauth and hope for getting a working response :)
HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory )
.setAudience(Arrays.asList("Client_ID"))
.setIssuer("https://accounts.google.com")
.build();
GoogleIdToken idToken = verifier.verify(tokenId);
logger.info("ID token:"+idToken);
if (idToken != null) {
Payload payload = idToken.getPayload();
// Print user identifier
String userId = payload.getSubject();
logger.info("User ID: " + userId);
// Get profile information from payload
String email = payload.getEmail();
boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
String name = (String) payload.get("name");
String pictureUrl = (String) payload.get("picture");
String locale = (String) payload.get("locale");
String familyName = (String) payload.get("family_name");
String givenName = (String) payload.get("given_name");
logger.info(email+":"+name+":"+pictureUrl+":"+familyName+":"+givenName);
// Use or store profile information
// ...
} else {
System.out.println("Invalid ID token.");
use : .setIssuer("accounts.google.com") instead of setIssuer("https://accounts.google.com")
I want to list all events all events from Google calendar using this code:
public class GoogleCalendarImpl
{
private static final String APPLICATION_NAME = "";
private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"), ".store/calendar_sample");
private static FileDataStoreFactory dataStoreFactory;
private static HttpTransport httpTransport;
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static com.google.api.services.calendar.Calendar client;
static final java.util.List<Calendar> addedCalendarsUsingBatch = Lists.newArrayList();
private static final String calId = "edrhrtherherh#development-1384.iam.gserviceaccount.com";
private static Credential authorize() throws Exception
{
// load client secrets
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,
new InputStreamReader(GoogleCalendarImpl.class.getResourceAsStream("/development-241a19899242.json")));
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, JSON_FACTORY, clientSecrets,
Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(dataStoreFactory).build();
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
public static void main(String[] args)
{
try
{
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
Credential credential = authorize();
client = new com.google.api.services.calendar.Calendar.Builder(
httpTransport, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME).build();
getAllEvents();
}
catch (IOException e)
{
System.err.println(e.getMessage());
}
catch (Throwable t)
{
t.printStackTrace();
}
System.exit(1);
}
private static List<Event> getAllEvents() throws IOException
{
List<Event> events = new ArrayList<>();
String nextPageToken = null;
do
{
System.out.println("Loading page " + nextPageToken);
Events feed = client.events().list(calId).setPageToken(nextPageToken).execute();
events.addAll(feed.getItems());
nextPageToken = feed.getNextPageToken();
}
while (nextPageToken != null);
return events;
}
}
But when I run the code Firefox(default web browser) is started and I'm redirected to page:
Error: redirect_uri_mismatch
The redirect URI in the request, http://localhost:56345/Callback, does not match the ones authorized for the OAuth client. Visit https://console.developers.google.com/apis/credentials/oauthclient/1024206104045435454813?project=762076316631 to update the authorized redirect URIs.
I would like to get all entried from Google calendar configured into my account.
How I can fix this issue?
How to fix Error: redirect_uri_mismatch
Go to your GDC and check what you specified as URI redirect. It should be
http://localhost:portnumber/oauth2callback.
Don't forget the 'oauth2' part.