diff --git a/Jenkinsfile b/Jenkinsfile
new file mode 100644
index 00000000..c44eb8b5
--- /dev/null
+++ b/Jenkinsfile
@@ -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
+ }
+
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index c7529084..90ec6d01 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,7 @@
-->
-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.
@@ -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"
@@ -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
diff --git a/build.sh b/build.sh
new file mode 100644
index 00000000..28c8e410
--- /dev/null
+++ b/build.sh
@@ -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
\ No newline at end of file
diff --git a/dev-ops/integration_test.env b/dev-ops/integration_test.env
index 15caaade..74a19bec 100644
--- a/dev-ops/integration_test.env
+++ b/dev-ops/integration_test.env
@@ -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
\ No newline at end of file
+DISABLE_LOG=false
+EMAIL_SERVICE=sendgrid
\ No newline at end of file
diff --git a/src/.env.sample b/src/.env.sample
index 2c39afa2..731950b7 100644
--- a/src/.env.sample
+++ b/src/.env.sample
@@ -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'
@@ -31,4 +31,24 @@ API_DOC_URL = '/api-doc'
ERROR_LOG_LEVEL='silly'
#Disable all logs
-DISABLE_LOG=false
\ No newline at end of file
+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******
\ No newline at end of file
diff --git a/src/constants/common.js b/src/constants/common.js
index d6e338ec..083777a9 100644
--- a/src/constants/common.js
+++ b/src/constants/common.js
@@ -13,4 +13,6 @@ module.exports = {
accessTokenSecret: 'hsghasghjab1273JHajnbabsjdj1273981273jhajksdh8y3123yhjkah812398yhjqwe7617237yuhdhhdqwu271',
refreshTokenSecret: '371hkjkjady2y3ihdkajshdkiq23iuekw71yekhaskdvkvegavy23t78veqwexqvxveit6ttxyeeytt62tx236vv',
guestUrls: [],
+ emailServiceSmtp: 'smtp',
+ emailServiceSendgrid: 'sendgrid',
}
diff --git a/src/envVariables.js b/src/envVariables.js
index ae42f9a6..fcb985fc 100644
--- a/src/envVariables.js
+++ b/src/envVariables.js
@@ -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: {
@@ -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
@@ -62,6 +116,7 @@ module.exports = function () {
}
let keyCheckPass = true
+ let validRequiredIfOperators = ['EQUALS', 'NOT_EQUALS']
if (
enviromentVariables[eachEnvironmentVariable].optional === true &&
diff --git a/src/generics/helpers/email-notifications.js b/src/generics/helpers/email-notifications.js
index 155b397a..3cbf1b85 100644
--- a/src/generics/helpers/email-notifications.js
+++ b/src/generics/helpers/email-notifications.js
@@ -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.
@@ -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
}
}
@@ -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 = {
@@ -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,
diff --git a/src/package.json b/src/package.json
index 4535f807..3622f7a7 100644
--- a/src/package.json
+++ b/src/package.json
@@ -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 ",
"license": "ISC",
@@ -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",