Send Github Issue Reactions for a Repo to a Google Sheet
@dylburger
code:
data:privatelast updated:1 year ago
today
Build integrations remarkably fast!
You're viewing a public workflow template.
Sign up to customize, add steps, modify code and more.
Join 1,000,000+ developers using the Pipedream platform
steps.
trigger
Cron Scheduler
Deploy to configure a custom schedule
This workflow runs on Pipedream's servers and is triggered on a custom schedule.
steps.
fetch_issue_reactions_data
auth
to use OAuth tokens and API keys in code via theauths object
(auths.github)
params
Owner
 
string ·params.owner
Repo
 
string ·params.repo
code
Write any Node.jscodeand use anynpm package. You can alsoexport datafor use in later steps via return or this.key = 'value', pass input data to your code viaparams, and maintain state across executions with$checkpoint.
async (event, steps, params, auths) => {
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
}
83
// This step pulls all Github issues reactions, for all open issues,
// for the target repo, overwriting the data in the Google Sheet
// each run. This is slightly inefficient, but the Github
// reactions API endpoint has no way to filter reactions by date.
// Moreover, if only sent new reactions to Google sheets, we'd have a lot
// of reactions to issues that were closed. Pulling only reactions for 
// currently-opened issues removes this concern

const format = require('date-fns/format')
const parseISO = require('date-fns/parseISO')

// See https://octokit.github.io/rest.js/#automatic-retries
const { Octokit } = require("@octokit/rest");
const octokit = new Octokit({
  auth: auths.github.oauth_access_token,
  previews: ["squirrel-girl-preview"], // See https://developer.github.com/v3/previews/#reactions
  throttle: {
    onRateLimit: () => true,
    onAbuseLimit: () => true,
  }
})

const { owner, repo } = params

// List all the issues for our target repo, letting the
// octokit package handle pagination:
// https://octokit.github.io/rest.js/#pagination
//
// For params you can pass to the listForRepo method, see
// https://octokit.github.io/rest.js/#octokit-routes-issues
let options = octokit.issues.listForRepo.endpoint.merge({
  owner,
  repo,
})

const issues = await octokit.paginate(options)
this.issueCount = issues.length
this.sampleIssue = issues[0]

this.reactions = [['Repo Owner', 'Repo', 'Issue Title', 'URL', 'Opened By', 'Issue Created At', 'Reaction At', 'Reaction Type', 'Reaction By']]

const reactionRequests = []
for (const issue of issues) {
  // List the reactions for our issue and add the relevant
  // data for each reaction and associated issue to a list. See
  // https://octokit.github.io/rest.js/#octokit-routes-reactions
  options = octokit.reactions.listForIssue.endpoint.merge({
    owner,
    repo,
    issue_number: issue.number,
  })
  reactionRequests.push(octokit.paginate(options))
}

// Make requests for all reactions in parallel to speed up
// the data retrieval. octokit should handle rate limiting 🤞
const reactionResponses = await Promise.all(reactionRequests)
for (const [index, reactions] of reactionResponses.entries()) {
  if (!reactions.length) {
    continue
  }
  
  // Reaction responses are in the same order as the issues tied
  // to the reaction request. Grab the issue metadata from the same
  // index of the issues array
  const issue = issues[index]
  for (const reaction of reactions) {
    const { content, created_at } = reaction
    this.reactions.push([
      owner,
      repo,
      issue.title,
      issue.url,
      issue.user.login,
      format(parseISO(issue.created_at), 'MM/dd/yyyy'),
      format(parseISO(created_at), 'MM/dd/yyyy'),
      content,
      reaction.user.login,
    ])
  }
}
steps.
clear_existing_reactions
auth
to use OAuth tokens and API keys in code via theauths object
(auths.google_sheets)
params
Sheet Name

The A1 notation of the values to update, including the sheet to update. For example: “Sheet1!A1:B2”

Issue Data
string ·params.range
Spreadsheet ID

The ID of the spreadsheet to retrieve data from (found in the URL at docs.google.com/spreadsheets/d/{id})

 
string ·params.spreadsheetId
code
Write any Node.jscodeand use anynpm package. You can alsoexport datafor use in later steps via return or this.key = 'value', pass input data to your code viaparams, and maintain state across executions with$checkpoint.
async (event, steps, params, auths) => {
1
2
3
4
5
6
7
8
9
10
11
12
13
}
14
const data = {
  range: params.range,
}
const config = {
  method: "post",
  url: `https://sheets.googleapis.com/v4/spreadsheets/${params.spreadsheetId}/values/${params.range}:clear`,
  headers: {
    Authorization: `Bearer ${auths.google_sheets.oauth_access_token}`,
  },
}
return await require("@pipedreamhq/platform").axios(this, config)
steps.
add_new_reactions
Updates the values of the cells of the specified range, for the specified spreadsheet ID.
auth
(auths.google_sheets)
params
Range

The A1 notation of the values to update, including the sheet to update. For example: “Sheet1!A1:B2”

Issue Data!A1:Z1000
string ·params.range
Values

The array of new values to update the sheet with. Google Sheets requires an array of arrays here, representing the grid of values you'd like to update in your sheet (see the docs for more information).

{{steps.fetch_issue_reactions_data.reactions}}
array ·params.values
Spreadsheet ID

The ID of the spreadsheet to retrieve data from (found in the URL at docs.google.com/spreadsheets/d/{id})

 
string ·params.spreadsheetId
Optional
code
async (params, auths) => {
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
}
23
const data = {
  range: params.range,
  values: params.values,
  majorDimension: params.majorDimension,
}
const config = {
  method: "put",
  url: `https://sheets.googleapis.com/v4/spreadsheets/${params.spreadsheetId}/values/${params.range}`,
  params: {
    includeValuesInResponse: params.includeValuesInResponse,
    responseDateTimeRenderOption: params.responseDateTimeRenderOption,
    responseValueRenderOption: params.responseValueRenderOption,
    valueInputOption: params.valueInputOption || 'USER_ENTERED',
  },
  headers: {
    Authorization: `Bearer ${auths.google_sheets.oauth_access_token}`,
  },
  data,
}
return await require("@pipedreamhq/platform").axios(this, config)