Skip to content

Commit ad92857

Browse files
authored
For issues with certain labels, closing triggers a CSAT survey comment to gather customer satisfaction. (#1704)
1 parent 81ec9fc commit ad92857

File tree

5 files changed

+127
-0
lines changed

5 files changed

+127
-0
lines changed

.github/workflows/csat.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: 'CSAT survey'
2+
on:
3+
issues:
4+
types:
5+
- closed
6+
7+
permissions:
8+
contents: read
9+
issues: write
10+
pull-requests: write
11+
12+
jobs:
13+
welcome:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v3
17+
- uses: actions/github-script@v6
18+
with:
19+
script: |
20+
const script = require('./\.github/workflows/scripts/csat.js')
21+
script({github, context})

.github/workflows/scripts/constant.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
let CONSTANT_VALUES = {
2+
MODULE: {
3+
CSAT: {
4+
YES:'Yes',
5+
NO:'No',
6+
BASE_URL: 'https://docs.google.com/forms/d/e/1FAIpQLSdHag0RVFS7UXzZkKcsFCKOcX8raCupKK9RHSlYxp5U8lSJbQ/viewform?',
7+
SATISFACTION_PARAM: 'entry.492125872=',
8+
ISSUEID_PARAM: '&entry.243948740=',
9+
MSG: 'Are you satisfied with the resolution of your issue?',
10+
CSAT_LABELS: ['type:bug', 'type:build/install', 'type:support', 'type:others', 'type:docs-bug', 'type:performance', 'type:feature']
11+
}
12+
}
13+
};
14+
module.exports = CONSTANT_VALUES;

.github/workflows/scripts/csat.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
const CONSTANT_VALUES = require('./constant');
3+
/**
4+
* Invoked from staleCSAT.js and CSAT.yaml file to
5+
* post survey link in closed issue.
6+
* @param {!object} Object - gitHub and context contains the information about the
7+
* current and context and github APIs using their built-in library functions.
8+
*/
9+
module.exports = async ({ github, context }) => {
10+
const issue = context.payload.issue.html_url;
11+
let base_url = CONSTANT_VALUES.MODULE.CSAT.BASE_URL;
12+
//Loop over all ths label present in issue and check if specific label is present for survey link.
13+
for (const label of context.payload.issue.labels) {
14+
if (CONSTANT_VALUES.MODULE.CSAT.CSAT_LABELS.includes(label.name)) {
15+
console.log(`label-${label.name}, posting CSAT survey for issue =${issue}`);
16+
const yesCsat = `<a href="${base_url + CONSTANT_VALUES.MODULE.CSAT.SATISFACTION_PARAM +
17+
CONSTANT_VALUES.MODULE.CSAT.YES +
18+
CONSTANT_VALUES.MODULE.CSAT.ISSUEID_PARAM + issue}"> ${CONSTANT_VALUES.MODULE.CSAT.YES}</a>`;
19+
20+
const noCsat = `<a href="${base_url + CONSTANT_VALUES.MODULE.CSAT.SATISFACTION_PARAM +
21+
CONSTANT_VALUES.MODULE.CSAT.NO +
22+
CONSTANT_VALUES.MODULE.CSAT.ISSUEID_PARAM + issue}"> ${CONSTANT_VALUES.MODULE.CSAT.NO}</a>`;
23+
const comment = CONSTANT_VALUES.MODULE.CSAT.MSG + '\n' + yesCsat + '\n' +
24+
noCsat + '\n';
25+
let issueNumber = context.issue.number ?? context.payload.issue.number;
26+
await github.rest.issues.createComment({
27+
issue_number: issueNumber,
28+
owner: context.repo.owner,
29+
repo: context.repo.repo,
30+
body: comment
31+
});
32+
}
33+
}
34+
};
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
2+
const csat = require('./csat.js');
3+
const CONSTANT = require("./constant.js");
4+
/**
5+
*When stale bot closes the issue this function will
6+
*invoke and post CSAT link on the issue.
7+
*This function will fetch all the issues closed within 10 minutes and
8+
*post the survey link if survey link is not posted already.
9+
* @param {!object} Object - gitHub and context contains the information about
10+
*the current and context and github APIs using their built-in library
11+
*functions.
12+
*/
13+
module.exports = async ({ github, context }) => {
14+
let date = new Date();
15+
let totalMilliSeconds = date.getTime();
16+
let minutes = 10;
17+
let millisecondsToSubtract = minutes * 60 * 1000;
18+
let closeTime = totalMilliSeconds-millisecondsToSubtract;
19+
let newDate = new Date(closeTime);
20+
let ISOCloseTime = newDate.toISOString();
21+
// Fetch all the issue closed with in 10 mins.
22+
let closeTimeIssues = await github.rest.issues.listForRepo({
23+
owner: context.repo.owner,
24+
repo: context.repo.repo,
25+
state:"closed",
26+
labels:"stale",
27+
since:ISOCloseTime
28+
});
29+
let ISSUESLIST = closeTimeIssues.data;
30+
console.log(`Fetching all the closed within ${minutes} minutes.`);
31+
console.log(ISSUESLIST);
32+
for(let i=0;i<ISSUESLIST.length;i++){
33+
if(ISSUESLIST[i].node_id && ISSUESLIST[i].node_id.indexOf("PR") !=-1)
34+
continue;
35+
// Fetch last comments for the issues.
36+
let comments = await github.rest.issues.listComments({
37+
owner: context.repo.owner,
38+
repo: context.repo.repo,
39+
issue_number: ISSUESLIST[i].number
40+
});
41+
let noOfComments = comments.data.length;
42+
let lastComment = comments.data[noOfComments-1];
43+
let strCom = JSON.stringify(lastComment);
44+
if(strCom.indexOf(CONSTANT.MODULE.CSAT.MSG) == -1){
45+
context.payload.issue = {};
46+
context.payload.issue.number = ISSUESLIST[i].number;
47+
context.payload.issue.labels = ISSUESLIST[i].labels;
48+
context.payload.issue.html_url = ISSUESLIST[i].html_url;
49+
csat({github, context});
50+
}
51+
}
52+
};

.github/workflows/stale-issues-pr.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,9 @@ jobs:
4848
close-issue-message: >
4949
This issue was closed because it has been inactive for more than 1 year.
5050
repo-token: ${{ secrets.GITHUB_TOKEN }}
51+
- uses: actions/checkout@v3
52+
- uses: actions/github-script@v6
53+
with:
54+
script: |
55+
const script = require('./\.github/workflows/scripts/stale_csat.js')
56+
script({github, context})

0 commit comments

Comments
 (0)