Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
node('build-slave') {
try {

String ANSI_GREEN = "\u001B[32m"
String ANSI_NORMAL = "\u001B[0m"
String ANSI_BOLD = "\u001B[1m"
String ANSI_RED = "\u001B[31m"
String ANSI_YELLOW = "\u001B[33m"

ansiColor('xterm') {
stage('Checkout') {
if (!env.hub_org) {
println(ANSI_BOLD + ANSI_RED + "Uh Oh! Please set a Jenkins environment variable named hub_org with value as registery/sunbidrded" + ANSI_NORMAL)
error 'Please resolve the errors and rerun..'
} else
println(ANSI_BOLD + ANSI_GREEN + "Found environment variable named hub_org with value as: " + hub_org + ANSI_NORMAL)
}

cleanWs()
checkout scm
commit_hash = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
build_tag = sh(script: "echo " + params.github_release_tag.split('/')[-1] + "_" + commit_hash + "_" + env.BUILD_NUMBER, returnStdout: true).trim()
echo "build_tag: " + build_tag


stage('Build') {
env.NODE_ENV = "build"
print "Environment will be : ${env.NODE_ENV}"
sh('chmod 777 build.sh')
sh("bash -x build.sh ${build_tag} ${env.NODE_NAME} ${docker_server}")
}


stage('ArchiveArtifacts') {
sh ("echo ${build_tag} > build_tag.txt")
archiveArtifacts "metadata.json"
archiveArtifacts "build_tag.txt"
currentBuild.description = "${build_tag}"
}

}
}
catch (err) {
currentBuild.result = "FAILURE"
throw err
}

}
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
</details> -->

</br>
The Mentoring building block enables effective mentoring interactions between mentors and mentees. The capability aims to create a transparent eco-system to learn, connect, solve, and share within communities.MentorED is an open source mentoring application that facilitates peer learning and professional development by creating a community of mentors and mentees.
The Notification building block enables sending emails via SendGrid service. It can receive informations - To, From, Subject, and Body via API as well as Kafka topic and sends the email using Sendgrid service, the credentials of which can be configured in the .env file. This service also maintains a log of all the emails sent in the Postgres.
</div>

<br>
Expand Down Expand Up @@ -302,7 +302,7 @@ KAFKA_GROUP_ID="elevate-notification"
SENDGRID_API_KEY="SG.asd9f87a9s8d7f."

# Sendgrid sender email address
SENDGRID_FROM_MAIL="no-reply@some.org"
FROM_EMAIL="no-reply@some.org"

# Api doc URL
API_DOC_URL= "/notification/api-doc"
Expand Down Expand Up @@ -417,9 +417,7 @@ npm test

This project was built to be used with [Mentoring Service](https://github.com/ELEVATE-Project/mentoring.git) and [User Service](https://github.com/ELEVATE-Project/user.git).

The frontend/mobile application [repo](https://github.com/ELEVATE-Project/mentoring-mobile-app).

You can learn more about the full implementation of MentorEd [here](https://elevate-docs.shikshalokam.org/.mentorEd/intro) .
You can learn more about the full implementation of various capabilities of ELEVATE [here](https://elevate-docs.shikshalokam.org) .

# Team

Expand Down
15 changes: 15 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

echo "Docker build script"

# Build script
set -eo pipefail

build_tag=$1
name=mentoring-notification-service
node=$2
org=$3

docker build -f ./Dockerfile --label commitHash=$(git rev-parse --short HEAD) -t ${org}/${name}:${build_tag} .

echo {\"image_name\" : \"${name}\", \"image_tag\" : \"${build_tag}\", \"node_name\" : \"$node\"} > metadata.json
5 changes: 3 additions & 2 deletions dev-ops/integration_test.env
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ APPLICATION_ENV = development
KAFKA_HOST = "localhost:9092"
KAFKA_TOPIC ="testTopic"
SENDGRID_API_KEY = "Yk*********"
SENDGRID_FROM_MAIL = "****@gmail.com"
FROM_EMAIL = "****@gmail.com"
APPLICATION_BASE_URL = '/notification/'
API_DOC_URL = 'xx'
INTERNAL_ACCESS_TOKEN = 'internal-access-token'
ACCESS_TOKEN_SECRET = 'ACCESS_TOKEN_SECRET'
ERROR_LOG_LEVEL='silly'
DISABLE_LOG=false
DISABLE_LOG=false
EMAIL_SERVICE=sendgrid
24 changes: 22 additions & 2 deletions src/.env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ KAFKA_GROUP_ID = "notification"
SENDGRID_API_KEY = "SG.YkHql6d5TwqkKDd1vxpM5w.V7Vxn3ZKzc_EUPC4uuFUCUGqsw"

#sendgrid sender email address
SENDGRID_FROM_MAIL = "example@test.com"
FROM_EMAIL = "example@test.com"

# Api doc url
API_DOC_URL = '/api-doc'
Expand All @@ -31,4 +31,24 @@ API_DOC_URL = '/api-doc'
ERROR_LOG_LEVEL='silly'

#Disable all logs
DISABLE_LOG=false
DISABLE_LOG=false

# Choose the email service: SMTP or SENDGRID
EMAIL_SERVICE=smtp

# SMTP Configuration
# Replace with your actual SMTP server details
# SMTP server host
SMTP_HOST=sandbox.smtp.mailtrap.io

# SMTP server port (587 for TLS, 465 for SSL)
SMTP_PORT=25

# Set to 'true' for secure connection (SSL/TLS)
SMTP_SECURE=false

# SMTP username
SMTP_USER=1e5955****

# SMTP password
SMTP_PASS=21065dd******
2 changes: 2 additions & 0 deletions src/constants/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ module.exports = {
accessTokenSecret: 'hsghasghjab1273JHajnbabsjdj1273981273jhajksdh8y3123yhjkah812398yhjqwe7617237yuhdhhdqwu271',
refreshTokenSecret: '371hkjkjady2y3ihdkajshdkiq23iuekw71yekhaskdvkvegavy23t78veqwexqvxveit6ttxyeeytt62tx236vv',
guestUrls: [],
emailServiceSmtp: 'smtp',
emailServiceSendgrid: 'sendgrid',
}
61 changes: 58 additions & 3 deletions src/envVariables.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,21 @@ let enviromentVariables = {
message: 'Required kafka consumer group id',
optional: true,
},
EMAIL_SERVICE: {
message: 'Required the email service sendgrid/smtp',
optional: false,
},
SENDGRID_API_KEY: {
message: 'Required sendgrid api key',
optional: false,
optional: true,
requiredIf: {
key: 'EMAIL_SERVICE',
operator: 'EQUALS',
value: 'sendgrid',
},
},
SENDGRID_FROM_MAIL: {
message: 'Required sendgrid sender email address',
FROM_EMAIL: {
message: 'Required sender email address',
optional: false,
},
API_DOC_URL: {
Expand All @@ -51,6 +60,51 @@ let enviromentVariables = {
message: 'Required disable log level',
optional: false,
},
SMTP_PASS: {
message: 'Required smtp password',
optional: true,
requiredIf: {
key: 'EMAIL_SERVICE',
operator: 'EQUALS',
value: 'smtp',
},
},
SMTP_HOST: {
message: 'Required smtp host',
optional: true,
requiredIf: {
key: 'EMAIL_SERVICE',
operator: 'EQUALS',
value: 'smtp',
},
},
SMTP_PORT: {
message: 'Required smtp port',
optional: true,
requiredIf: {
key: 'EMAIL_SERVICE',
operator: 'EQUALS',
value: 'smtp',
},
},
SMTP_USER: {
message: 'Required smtp username',
optional: true,
requiredIf: {
key: 'EMAIL_SERVICE',
operator: 'EQUALS',
value: 'smtp',
},
},
SMTP_SECURE: {
message: 'Required smtp secure',
optional: true,
requiredIf: {
key: 'EMAIL_SERVICE',
operator: 'EQUALS',
value: 'smtp',
},
},
}

let success = true
Expand All @@ -62,6 +116,7 @@ module.exports = function () {
}

let keyCheckPass = true
let validRequiredIfOperators = ['EQUALS', 'NOT_EQUALS']

if (
enviromentVariables[eachEnvironmentVariable].optional === true &&
Expand Down
61 changes: 51 additions & 10 deletions src/generics/helpers/email-notifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@

//Dependencies
const sgMail = require('@sendgrid/mail')
sgMail.setApiKey(process.env.SENDGRID_API_KEY)
const logQueries = require('../../database/queries/log')
const request = require('request')
const nodemailer = require('nodemailer')
const emailService = process.env.EMAIL_SERVICE || 'sendgrid'
const common = require('../../constants/common')

/**
* Fetches a file from a given URL.
Expand Down Expand Up @@ -59,10 +61,26 @@ async function sendEmail(params) {
if (params.attachments && params.attachments.length > 0) {
const processAttachment = async (attachment) => {
const attachmentContent = await fetchFileByUrl(attachment)

// Common attachment properties
const baseAttachment = {
filename: attachment.filename,
content: attachmentContent.content,
}

if (emailService === common.emailServiceSmtp) {
// For SMTP, just return the content as is with contentType
return {
...baseAttachment,
contentType: attachment.type, // Add content type for SMTP
}
}

// For SendGrid, encode the content in base64
return {
...baseAttachment,
content: Buffer.from(attachmentContent.content).toString('base64'),
filename: attachment.filename,
type: attachment.type,
type: attachment.type, // Required for SendGrid
}
}

Expand All @@ -77,11 +95,13 @@ async function sendEmail(params) {
attachments: { message: error.message },
}
}
let fromMail = process.env.SENDGRID_FROM_MAIL

let fromMail = process.env.FROM_EMAIL

if (params.from) {
fromMail = params.from
}

const to = params.to.split(',')

let message = {
Expand All @@ -98,13 +118,34 @@ async function sendEmail(params) {
message['replyTo'] = params.replyTo
}
try {
const res = await sgMail.send(message)
errorResponse = {
email: to,
response_code: Number(res[0].statusCode),
meta: errorMeta,
if (emailService == common.emailServiceSmtp) {
// SMTP Configuration
const transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: process.env.SMTP_PORT || 587,
secure: process.env.SMTP_SECURE || false,
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
})

let response = await transporter.sendMail(message)
if (!response?.messageId) {
throw new Error('Failed to send message')
}
} else if (emailService == common.emailServiceSendgrid) {
sgMail.setApiKey(process.env.SENDGRID_API_KEY)
const res = await sgMail.send(message)
errorResponse = {
email: to,
response_code: Number(res[0].statusCode),
meta: errorMeta,
}
await logQueries.createLog(errorResponse)
} else {
throw new Error('emailService provided should be either smtp or sendgrid')
}
await logQueries.createLog(errorResponse)
} catch (error) {
errorResponse = {
email: to,
Expand Down
5 changes: 3 additions & 2 deletions src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"stage": "node app.js",
"prepare": "cd .. && husky install src/.husky",
"test:integration": "jest --verbose ./integration-test --config=integrationJest.config.js --runInBand",
"db:init": "sequelize-cli db:create && sequelize-cli db:migrate ",
"db:seed:all": "sequelize-cli db:seed:all"
"db:init": "sequelize-cli db:create || echo 'Database already exists or some issue while creating db, Please check' && sequelize-cli db:migrate ",
"db:seed:all": "sequelize-cli db:seed:all || echo 'Seeded data already exists or some issue while seeding the data, Please check' "
},
"author": "Aman Kumar Gupta <amangupta15jan@gmail.com>",
"license": "ISC",
Expand All @@ -31,6 +31,7 @@
"jsonwebtoken": "^8.5.1",
"kafkajs": "^2.2.2",
"module-alias": "^2.2.2",
"nodemailer": "^6.10.0",
"pg": "^8.11.3",
"pg-hstore": "^2.3.4",
"require-all": "^3.0.0",
Expand Down