Skip to content

Commit 941e694

Browse files
authored
Merge pull request #149 from imcaizheng/new-endpoint-team-email
add new endpoint `POST /taas-teams/email`
2 parents c887a76 + 1a5d2de commit 941e694

File tree

10 files changed

+281
-4
lines changed

10 files changed

+281
-4
lines changed

config/default.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,5 +105,14 @@ module.exports = {
105105
// the update resource booking entity Kafka message topic
106106
TAAS_RESOURCE_BOOKING_UPDATE_TOPIC: process.env.TAAS_RESOURCE_BOOKING_UPDATE_TOPIC || 'taas.resourcebooking.update',
107107
// the delete resource booking entity Kafka message topic
108-
TAAS_RESOURCE_BOOKING_DELETE_TOPIC: process.env.TAAS_RESOURCE_BOOKING_DELETE_TOPIC || 'taas.resourcebooking.delete'
108+
TAAS_RESOURCE_BOOKING_DELETE_TOPIC: process.env.TAAS_RESOURCE_BOOKING_DELETE_TOPIC || 'taas.resourcebooking.delete',
109+
110+
// the Kafka message topic for sending email
111+
EMAIL_TOPIC: process.env.EMAIL_TOPIC || 'external.action.email',
112+
// the email address for receiving the issue report
113+
REPORT_ISSUE_EMAIL: process.env.REPORT_ISSUE_EMAIL || '[email protected]',
114+
// SendGrid email template ID for reporting issue
115+
REPORT_ISSUE_SENDGRID_TEMPLATE_ID: process.env.REPORT_ISSUE_SENDGRID_TEMPLATE_ID || 'aaaaaaa-bbbb-cccc-dddd-asdfsdfsdfsd',
116+
// the URL where TaaS App is hosted
117+
TAAS_APP_URL: process.env.TAAS_APP_URL || 'https://platform.topcoder-dev.com/taas/myteams'
109118
}

config/email_template.config.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Configure email templates.
3+
* Variables can be used inside the subject and the message of a template(enclosed in double curly braces).
4+
*/
5+
6+
const config = require('config')
7+
8+
module.exports = {
9+
/* Report a general issue for a team.
10+
*
11+
* - projectId: the project ID. Example: 123412
12+
* - projectName: the project name. Example: "TaaS API Misc Updates"
13+
* - reportText: the body of reported issue. Example: "I have issue with ... \n ... Thank you in advance!"
14+
*/
15+
'team-issue-report': {
16+
subject: 'Issue Reported on TaaS Team {{projectName}} ({{projectId}}).',
17+
message: 'Project Name: {{projectName}}' + '\n' +
18+
'Project ID: {{projectId}}' + '\n' +
19+
`Project URL: ${config.TAAS_APP_URL}/{{projectId}}` + '\n' +
20+
'\n' +
21+
'{{reportText}}',
22+
recipients: [
23+
config.REPORT_ISSUE_EMAIL
24+
],
25+
sendgridTemplateId: config.REPORT_ISSUE_SENDGRID_TEMPLATE_ID
26+
},
27+
/* Report issue for a particular member
28+
*
29+
* - userHandle: the user handle. Example: "bili_2021"
30+
* - projectId: the project ID. Example: 123412
31+
* - projectName: the project name. Example: "TaaS API Misc Updates"
32+
* - reportText: the body of reported issue. Example: "I have issue with ... \n ... Thank you in advance!"
33+
*/
34+
'member-issue-report': {
35+
subject: 'Issue Reported for member {{userHandle}} on TaaS Team {{projectName}} ({{projectId}}).',
36+
message: 'User Handle: {{userHandle}}' + '\n' +
37+
'Project Name: {{projectName}}' + '\n' +
38+
'Project ID: {{projectId}}' + '\n' +
39+
`Project URL: ${config.TAAS_APP_URL}/{{projectId}}` + '\n' +
40+
'\n' +
41+
'{{reportText}}',
42+
recipients: [
43+
config.REPORT_ISSUE_EMAIL
44+
],
45+
sendgridTemplateId: config.REPORT_ISSUE_SENDGRID_TEMPLATE_ID
46+
}
47+
}

docs/Topcoder-bookings-api.postman_collection.json

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4406,6 +4406,82 @@
44064406
}
44074407
},
44084408
"response": []
4409+
},
4410+
{
4411+
"name": "POST /taas-teams/email - team-issue-report",
4412+
"request": {
4413+
"method": "POST",
4414+
"header": [
4415+
{
4416+
"key": "Authorization",
4417+
"value": "Bearer {{token_member}}",
4418+
"type": "text"
4419+
},
4420+
{
4421+
"key": "Content-Type",
4422+
"value": "application/json",
4423+
"type": "text"
4424+
}
4425+
],
4426+
"body": {
4427+
"mode": "raw",
4428+
"raw": "{\n \"template\": \"team-issue-report\",\n \"data\": {\n \"projectName\": \"TaaS Project Name\",\n \"projectId\": 12345,\n \"reportText\": \"I have issue with ...\"\n }\n}",
4429+
"options": {
4430+
"raw": {
4431+
"language": "json"
4432+
}
4433+
}
4434+
},
4435+
"url": {
4436+
"raw": "{{URL}}/taas-teams/email",
4437+
"host": [
4438+
"{{URL}}"
4439+
],
4440+
"path": [
4441+
"taas-teams",
4442+
"email"
4443+
]
4444+
}
4445+
},
4446+
"response": []
4447+
},
4448+
{
4449+
"name": "POST /taas-teams/email - member-issue-report",
4450+
"request": {
4451+
"method": "POST",
4452+
"header": [
4453+
{
4454+
"key": "Authorization",
4455+
"type": "text",
4456+
"value": "Bearer {{token_member}}"
4457+
},
4458+
{
4459+
"key": "Content-Type",
4460+
"type": "text",
4461+
"value": "application/json"
4462+
}
4463+
],
4464+
"body": {
4465+
"mode": "raw",
4466+
"raw": "{\n \"template\": \"member-issue-report\",\n \"data\": {\n \"projectName\": \"TaaS Project Name\",\n \"projectId\": 12345,\n \"userHandle\": \"pshah_manager\",\n \"reportText\": \"I have issue with ...\"\n }\n}",
4467+
"options": {
4468+
"raw": {
4469+
"language": "json"
4470+
}
4471+
}
4472+
},
4473+
"url": {
4474+
"raw": "{{URL}}/taas-teams/email",
4475+
"host": [
4476+
"{{URL}}"
4477+
],
4478+
"path": [
4479+
"taas-teams",
4480+
"email"
4481+
]
4482+
}
4483+
},
4484+
"response": []
44094485
}
44104486
]
44114487
},

docs/swagger.yaml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,6 +1613,46 @@ paths:
16131613
application/json:
16141614
schema:
16151615
$ref: '#/components/schemas/Error'
1616+
/taas-teams/email:
1617+
post:
1618+
tags:
1619+
- Teams
1620+
description: |
1621+
Send emails through one of predefined templates.
1622+
security:
1623+
- bearerAuth: []
1624+
requestBody:
1625+
content:
1626+
application/json:
1627+
schema:
1628+
$ref: '#/components/schemas/TeamEmailRequestBody'
1629+
responses:
1630+
'204':
1631+
description: OK
1632+
'400':
1633+
description: Bad request
1634+
content:
1635+
application/json:
1636+
schema:
1637+
$ref: '#/components/schemas/Error'
1638+
'401':
1639+
description: Not authenticated
1640+
content:
1641+
application/json:
1642+
schema:
1643+
$ref: '#/components/schemas/Error'
1644+
'403':
1645+
description: Forbidden
1646+
content:
1647+
application/json:
1648+
schema:
1649+
$ref: '#/components/schemas/Error'
1650+
'500':
1651+
description: Internal Server Error
1652+
content:
1653+
application/json:
1654+
schema:
1655+
$ref: '#/components/schemas/Error'
16161656
/health:
16171657
get:
16181658
tags:
@@ -2368,6 +2408,17 @@ components:
23682408
type: array
23692409
items:
23702410
$ref: '#/components/schemas/Skill'
2411+
TeamEmailRequestBody:
2412+
type: object
2413+
properties:
2414+
template:
2415+
type: string
2416+
description: "the email template name"
2417+
example: "team-issue-report"
2418+
data:
2419+
type: object
2420+
example: {"projectName": "TaaS Project Name", "projectId": 12345, "reportText": "I have issue with ..."}
2421+
description: "Arbitrary data to feed the specified template"
23712422
Error:
23722423
required:
23732424
- message

local/kafka-client/topics.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ taas.jobcandidate.update
66
taas.resourcebooking.update
77
taas.job.delete
88
taas.jobcandidate.delete
9-
taas.resourcebooking.delete
9+
taas.resourcebooking.delete
10+
external.action.email

package-lock.json

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"express": "^4.17.1",
4242
"express-interceptor": "^1.2.0",
4343
"get-parameter-names": "^0.3.0",
44+
"handlebars": "^4.7.6",
4445
"http-status": "^1.4.2",
4546
"http-status-codes": "^2.1.4",
4647
"joi": "^17.2.1",

src/controllers/TeamController.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/**
22
* Controller for TaaS teams endpoints
33
*/
4+
const HttpStatus = require('http-status-codes')
45
const service = require('../services/TeamService')
56
const helper = require('../common/helper')
67

@@ -33,8 +34,19 @@ async function getTeamJob (req, res) {
3334
res.send(await service.getTeamJob(req.authUser, req.params.id, req.params.jobId))
3435
}
3536

37+
/**
38+
* Send email through a particular template
39+
* @param req the request
40+
* @param res the response
41+
*/
42+
async function sendEmail (req, res) {
43+
await service.sendEmail(req.body)
44+
res.status(HttpStatus.NO_CONTENT).end()
45+
}
46+
3647
module.exports = {
3748
searchTeams,
3849
getTeam,
39-
getTeamJob
50+
getTeamJob,
51+
sendEmail
4052
}

src/routes/TeamRoutes.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ module.exports = {
1212
scopes: [constants.Scopes.READ_TAAS_TEAM]
1313
}
1414
},
15+
'/taas-teams/email': {
16+
post: {
17+
controller: 'TeamController',
18+
method: 'sendEmail',
19+
auth: 'jwt',
20+
scopes: [constants.Scopes.READ_TAAS_TEAM]
21+
}
22+
},
1523
'/taas-teams/skills': {
1624
get: {
1725
controller: 'SkillController',

src/services/TeamService.js

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,24 @@
55
const _ = require('lodash')
66
const Joi = require('joi')
77
const dateFNS = require('date-fns')
8+
const Handlebars = require('handlebars')
9+
const config = require('config')
10+
const emailTemplateConfig = require('../../config/email_template.config')
811
const helper = require('../common/helper')
912
const logger = require('../common/logger')
1013
const errors = require('../common/errors')
1114
const JobService = require('./JobService')
1215
const ResourceBookingService = require('./ResourceBookingService')
1316

17+
const emailTemplates = _.mapValues(emailTemplateConfig, (template) => {
18+
return {
19+
subjectTemplate: Handlebars.compile(template.subject),
20+
messageTemplate: Handlebars.compile(template.message),
21+
recipients: template.recipients,
22+
sendgridTemplateId: template.sendgridTemplateId
23+
}
24+
})
25+
1426
/**
1527
* Function to get assigned resource bookings with specific projectIds
1628
* @param {Object} currentUser the user who perform this operation.
@@ -296,8 +308,33 @@ getTeamJob.schema = Joi.object().keys({
296308
jobId: Joi.string().guid().required()
297309
}).required()
298310

311+
/**
312+
* Send email through a particular template
313+
* @param {Object} data the email object
314+
* @returns {undefined}
315+
*/
316+
async function sendEmail (data) {
317+
const template = emailTemplates[data.template]
318+
await helper.postEvent(config.EMAIL_TOPIC, {
319+
subject: template.subjectTemplate(data.data),
320+
handle: data.data.userHandle,
321+
message: template.messageTemplate(data.data),
322+
sendgrid_template_id: template.sendgridTemplateId,
323+
version: 'v3',
324+
recipients: template.recipients
325+
})
326+
}
327+
328+
sendEmail.schema = Joi.object().keys({
329+
data: Joi.object().keys({
330+
template: Joi.string().valid(...Object.keys(emailTemplates)).required(),
331+
data: Joi.object().required()
332+
}).required()
333+
}).required()
334+
299335
module.exports = {
300336
searchTeams,
301337
getTeam,
302-
getTeamJob
338+
getTeamJob,
339+
sendEmail
303340
}

0 commit comments

Comments
 (0)