Skip to content

Commit

Permalink
Store scores to a Google Sheet
Browse files Browse the repository at this point in the history
  • Loading branch information
samie committed Jun 29, 2023
1 parent 81b65ea commit 9008fc9
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 0 deletions.
127 changes: 127 additions & 0 deletions demo/src/main/java/com/example/application/data/FeedbackSheet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package com.example.application.data;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.sheets.v4.Sheets;
import com.google.api.services.sheets.v4.SheetsScopes;
import com.google.api.services.sheets.v4.model.ValueRange;
import com.google.auth.oauth2.ServiceAccountCredentials;

/* Class to store feedack into a Google Sheet.
*
* This needs a Google Service Account to be set up first and give 'editor'
* permissions to that account in the specified sheet.
*
*
*/
public class FeedbackSheet {

private static final String APPLICATION_NAME = "NPS Feedback App";

private static final List<String> AUTH_SCOPES = List.of(SheetsScopes.SPREADSHEETS);

private static final String RANGE = "Sheet1";

private static final GsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();

private String credentialsFilePath;
private ServiceAccountCredentials loadedCredentials;
private Sheets loadedService;

private String sheetId;

public FeedbackSheet(String sheetId, String credentialsFilePath) {
this.sheetId = sheetId;
this.credentialsFilePath = credentialsFilePath;
}

/**
* Append a user score to the spreadsheet.
*
* Adds a new row in the first sheet in a Google Spreadsheet
* with timestamp userId and given NPS score.
*
* <code>2023-06-26 11:09:44,1687640813, 10</code>
*
* @param anonymousUserId Unique but anonymous I
* @param score NPS score
*/
public void append(String anonymousUserId, int score) {
try {
List<List<Object>> values = Arrays.asList(
Arrays.asList(LocalDateTime.now().toString(), anonymousUserId, score));

ValueRange newEntry = new ValueRange().setValues(values);
Sheets service = getSheetsService();
service.spreadsheets().values()
.append(this.sheetId, RANGE, newEntry)
.setValueInputOption("USER_ENTERED")
.setAccessToken(getCredentials().getAccessToken().getTokenValue())
.execute();
} catch (Exception e) {
throw new RuntimeException("Failed to append Google Sheet", e);
}
}

/**
* Initialize and get Google Sheets service.
*
* @return Sheets service to perform operations.
* @throws IOException
* @throws GeneralSecurityException
*/
public Sheets getSheetsService() throws IOException, GeneralSecurityException {
if (this.loadedService == null) {
NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
this.loadedService = new Sheets.Builder(httpTransport, JSON_FACTORY, request -> {
})
.setApplicationName(APPLICATION_NAME)
.build();
}
return this.loadedService;
}

/**
* Load and create new ServiceAccountCredential instance.
*
* Loads the credentials from json file specified by
* <code>gapi.credentials.file.path</code>.
* Once successfully loaded, calling this will return the same credential
* instance.
*
* @return An authorized Credential object.
* @throws IOException If the credentials.json file cannot be found.
*/
protected ServiceAccountCredentials getCredentials() throws IOException {

if (this.loadedCredentials != null) {
if (this.loadedCredentials.getAccessToken().getExpirationTime().before(new Date())) {
this.loadedCredentials.refresh();
}
return this.loadedCredentials;
}

InputStream in = new FileInputStream(credentialsFilePath);
if (in == null) {
throw new FileNotFoundException("Credentials not found: " + credentialsFilePath);
}

this.loadedCredentials = (ServiceAccountCredentials) ServiceAccountCredentials
.fromStream(new FileInputStream(credentialsFilePath))
.createScoped(AUTH_SCOPES);
this.loadedCredentials.refresh();
return this.loadedCredentials;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ public FeedbackView() {
header.setText("Thank You");
replace(nps, thankYou);
add(closeLink);

// Store the results into a Google Sheet
FeedbackSheet feedbackSheet = new FeedbackSheet("1aTfU2_XuZU-HgUhSBu4_oB_gB4hhro-RzNsdN9_8YX8",
"/workspaces/nps/.devcontainer/local/service_account_credentials.json");
feedbackSheet.append("" + UI.getCurrent().hashCode(), e.getValue());
});

// Styling
Expand Down

0 comments on commit 9008fc9

Please sign in to comment.