Skip to content

Commit 8c8c13c

Browse files
authored
Use parameterized configuration (#1029)
1 parent 2e1e001 commit 8c8c13c

File tree

1 file changed

+63
-20
lines changed
  • 2nd-gen/app-distribution-feedback-to-jira/functions

1 file changed

+63
-20
lines changed

2nd-gen/app-distribution-feedback-to-jira/functions/index.js

+63-20
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,45 @@
11
import {
22
onInAppFeedbackPublished} from "firebase-functions/v2/alerts/appDistribution";
3+
import {defineInt, defineSecret, defineString} from "firebase-functions/params";
4+
import logger from "firebase-functions/logger";
35
import fetch from "node-fetch";
46
import {FormData} from "formdata-polyfill/esm.min.js";
5-
import logger from "firebase-functions/logger";
67

7-
const JIRA_URI = "https://mysite.atlassian.net";
8-
const PROJECT_KEY = "XY";
9-
const ISSUE_TYPE_ID = "10001";
10-
const ISSUE_LABELS = ["in-app"];
11-
const API_KEY_OWNER = "user@e,mail";
12-
const API_KEY = "am9zaHVhIHBhc3N3b3JkMTIz";
13-
const AUTH_HEADER = "Basic " +
14-
Buffer.from(`${API_KEY_OWNER}:${API_KEY}`).toString("base64");
8+
// The keys are either defined in .env or they are created
9+
// via prompt in the CLI before deploying
10+
const jiraUriConfig = defineString("JIRA_URI", {
11+
description: "URI of your Jira instance (e.g. 'https://mysite.atlassian.net')",
12+
input: {
13+
text: {
14+
validationRegex: /^https:\/\/.*/,
15+
validationErrorMessage: "Please enter an 'https://' URI",
16+
},
17+
},
18+
});
19+
const projectKeyConfig = defineString("PROJECT_KEY", {
20+
description: "Project key of your Jira instance (e.g. 'XY')",
21+
});
22+
const issueTypeIdConfig = defineInt("ISSUE_TYPE_ID", {
23+
description: "Issue type ID for the Jira issues being created",
24+
default: 10001,
25+
});
26+
const issueLabelConfig = defineString("ISSUE_LABEL", {
27+
description: "Label for the Jira issues being created",
28+
default: "in-app",
29+
});
30+
const apiKeyOwnerConfig = defineString("API_KEY_OWNER", {
31+
description: "Owner of the Jira API key",
32+
input: {
33+
text: {
34+
validationRegex:
35+
/^[a-zA-Z0-9.!#$%&*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/,
36+
validationErrorMessage: "Please enter a valid email address",
37+
},
38+
},
39+
});
40+
const apiKeyConfig = defineSecret("API_KEY", {
41+
description: "Jira API key",
42+
});
1543

1644
export const handleInAppFeedback = async (event) => {
1745
const issueUri = await createIssue(event);
@@ -21,7 +49,18 @@ export const handleInAppFeedback = async (event) => {
2149
return true;
2250
};
2351

24-
export const feedbacktojira = onInAppFeedbackPublished(handleInAppFeedback);
52+
export const feedbacktojira =
53+
onInAppFeedbackPublished({secrets: [apiKeyConfig]}, handleInAppFeedback);
54+
55+
/**
56+
* Creates "Authorization" header value.
57+
* @return {string} Basic, base64-encoded "Authorization" header value
58+
*/
59+
function authHeader() {
60+
return "Basic " + Buffer
61+
.from(apiKeyOwnerConfig.value() + ":" + apiKeyConfig.value())
62+
.toString("base64");
63+
}
2564

2665
/**
2766
* Creates new issue in Jira.
@@ -31,10 +70,10 @@ async function createIssue(event) {
3170
const requestJson = await buildCreateIssueRequest(event);
3271
const requestBody = JSON.stringify(requestJson);
3372
const response =
34-
await fetch("https://eventarc.atlassian.net/rest/api/3/issue", {
73+
await fetch(`${jiraUriConfig.value()}/rest/api/3/issue`, {
3574
method: "POST",
3675
headers: {
37-
"Authorization": AUTH_HEADER,
76+
"Authorization": authHeader(),
3877
"Accept": "application/json",
3978
"Content-Type": "application/json",
4079
},
@@ -68,7 +107,7 @@ async function uploadScreenshot(issueUri, screenshotUri) {
68107
method: "POST",
69108
body: form,
70109
headers: {
71-
"Authorization": AUTH_HEADER,
110+
"Authorization": authHeader(),
72111
"Accept": "application/json",
73112
"X-Atlassian-Token": "no-check",
74113
},
@@ -85,10 +124,14 @@ async function uploadScreenshot(issueUri, screenshotUri) {
85124
*/
86125
async function lookupReporter(testerEmail) {
87126
const response =
88-
await fetch(`${JIRA_URI}/rest/api/3/user/search?query=${testerEmail}`, {
89-
method: "GET",
90-
headers: {"Authorization": AUTH_HEADER, "Accept": "application/json"},
91-
});
127+
await fetch(
128+
`${jiraUriConfig.value()}/rest/api/3/user/search` +
129+
`?query=${testerEmail}`, {
130+
method: "GET",
131+
headers: {
132+
"Authorization": authHeader(),
133+
"Accept": "application/json",
134+
}});
92135
if (!response.ok) {
93136
logger.info(`Failed to find Jira user for '${testerEmail}':` +
94137
`${response.status} ${response.statusText}`);
@@ -112,10 +155,10 @@ async function buildCreateIssueRequest(event) {
112155
"fields": {
113156
"summary": summary,
114157
"issuetype": {
115-
"id": ISSUE_TYPE_ID,
158+
"id": issueTypeIdConfig.value(),
116159
},
117160
"project": {
118-
"key": PROJECT_KEY,
161+
"key": projectKeyConfig.value(),
119162
},
120163
"description": {
121164
"type": "doc",
@@ -231,7 +274,7 @@ async function buildCreateIssueRequest(event) {
231274
},
232275
],
233276
},
234-
"labels": ISSUE_LABELS,
277+
"labels": [issueLabelConfig.value()],
235278
},
236279
};
237280
const reporter = await lookupReporter(event.data.payload.testerEmail);

0 commit comments

Comments
 (0)