Skip to content

Instantly share code, notes, and snippets.

@pejalo
Created July 6, 2023 07:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pejalo/ad2df72ef78ce7ef46892406d5fe8ba0 to your computer and use it in GitHub Desktop.
Save pejalo/ad2df72ef78ce7ef46892406d5fe8ba0 to your computer and use it in GitHub Desktop.
Add email address to Google Sheet and log to Cloud Logger
const GoogleSheets = require('@googleapis/sheets');
const GoogleLogging = require('@google-cloud/logging');
// both google services below are authenticated via "Application Default Credentials" (ADC)
// https://googleapis.dev/nodejs/googleapis/latest/sheets/index.html#service-account-credentials
// this will automatically read contents of service account key json file
// as specified at path by environment variable GOOGLE_APPLICATION_CREDENTIALS.
// it would also be possible to specify path programmatically.
// steps to enable service account on google cloud:
// - created new Google Cloud project
// - enabled Google Sheets API
// - created new service account and downloaded key json file, and set GOOGLE_APPLICATION_CREDENTIALS to path
// - created spreadsheet and shared with service account email address, with edit access
// - enabled Cloud Logging API
// - on IAM page, grated Log Writer role to service account
// todo: handle situation where > 300 requests have been made within the last minute
const sheets = GoogleSheets.sheets({
version: 'v4',
auth: new GoogleSheets.auth.GoogleAuth({
// https://developers.google.com/identity/protocols/oauth2/scopes#sheets
scopes: ['https://www.googleapis.com/auth/spreadsheets']
})
})
const logging = new GoogleLogging.Logging().log("subscribes")
function log(severity, payload) {
const entry = logging.entry({ severity }, payload)
logging.write(entry, err => {
if (err)
console.error({
hint: "failed to write log to google logger",
message: err.message,
severity,
...payload,
})
})
}
module.exports = {
subscribe: async (email, ip) => {
const date = new Date().toISOString() // like: 2023-07-04T06:32:45.564Z
const request = {
spreadsheetId: '<MY_SPREADSHEET_ID>',
range: 'Sheet1',
valueInputOption: 'RAW', // don't automatically try to change format (like when user taps "enter")
//insertDataOption: '', // included in all examples but apparently not needed
resource: { "values": [ [email, date, ip] ] },
};
const logPayload = { email, date, ip }
try {
// add row to spreadsheet
const response = (await sheets.spreadsheets.values.append(request)).data;
if (response.updates && response.updates.updatedRows === 1)
log('INFO', logPayload)
else
log('ERROR', {
...logPayload,
hint: "expected google sheets API to have responded with updatedRows: 1"
})
} catch (err) {
log('ERROR', {
...logPayload,
...(err.code && { errorCode: err.code }),
...((err.errors && err.errors[0]) && { firstErrorMessage: err.errors[0].message })
})
throw err
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment