Adding pipeline
This commit is contained in:
parent
cff02bcc03
commit
04077d95f4
83
fitlien-services-pipeline.yaml
Normal file
83
fitlien-services-pipeline.yaml
Normal file
@ -0,0 +1,83 @@
|
||||
trigger:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: "ubuntu-latest"
|
||||
|
||||
variables:
|
||||
major: $(VERSION_MAJOR)
|
||||
minor: $(VERSION_MINOR)
|
||||
prefix: $[format('{0}.{1}', variables['major'], variables['minor'])]
|
||||
patch: $[counter(variables['prefix'], 100)]
|
||||
buildNumber: $(major).$(minor).$(patch)
|
||||
|
||||
steps:
|
||||
- task: PowerShell@2
|
||||
displayName: "Setting build version"
|
||||
inputs:
|
||||
targetType: "inline"
|
||||
script: |
|
||||
Write-Host "##vso[build.updatebuildnumber]${{ parameters.buildNumber }}"
|
||||
|
||||
- task: NodeTool@0
|
||||
displayName: "Install Node"
|
||||
inputs:
|
||||
version: "20"
|
||||
|
||||
- task: Npm@1
|
||||
displayName: "npm install"
|
||||
inputs:
|
||||
command: "install"
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: "Set version in package.json"
|
||||
inputs:
|
||||
targetType: "inline"
|
||||
script: |
|
||||
$pkg = Get-Content -Path "$(System.DefaultWorkingDirectory)/functions/package.json" -Raw | ConvertFrom-Json
|
||||
$pkg.version = "${{ parameters.buildNumber }}"
|
||||
$pkg | ConvertTo-Json -Depth 100 | Set-Content -Path "$(System.DefaultWorkingDirectory)/functions/package.json"
|
||||
|
||||
- task: CmdLine@2
|
||||
displayName: "Copy .env.example to .env"
|
||||
inputs:
|
||||
script: |
|
||||
cp "$(System.DefaultWorkingDirectory)/functions/.env.example" "$(System.DefaultWorkingDirectory)/functions/.env"
|
||||
|
||||
- task: ReplaceTokens@3
|
||||
displayName: "Replace tokens in .env file"
|
||||
inputs:
|
||||
targetFiles: "$(System.DefaultWorkingDirectory)/functions/.env"
|
||||
tokenPrefix: "#{"
|
||||
tokenSuffix: "}#"
|
||||
|
||||
- task: Npm@1
|
||||
displayName: "npm run build"
|
||||
inputs:
|
||||
command: "custom"
|
||||
workingDir: "$(System.DefaultWorkingDirectory)/functions"
|
||||
customCommand: "run build"
|
||||
|
||||
- task: DeleteFiles@1
|
||||
displayName: "Remove node_modules, *.log files, src directory from functions directory"
|
||||
inputs:
|
||||
SourceFolder: "$(System.DefaultWorkingDirectory)/functions"
|
||||
Contents: |
|
||||
node_modules/**
|
||||
*.log
|
||||
src/**
|
||||
|
||||
- task: ArchiveFiles@2
|
||||
displayName: "Archive functions directory"
|
||||
inputs:
|
||||
rootFolderOrFile: "$(System.DefaultWorkingDirectory)/functions"
|
||||
includeRootFolder: false
|
||||
archiveFile: "$(System.DefaultWorkingDirectory)/fitlien-services-$(buildNumber).zip"
|
||||
compression: "zip"
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: "Copy archive to staging directory"
|
||||
inputs:
|
||||
SourceFolder: "$(System.DefaultWorkingDirectory)"
|
||||
Contents: "fitlien-services-$(buildNumber).zip"
|
||||
TargetFolder: "$(System.ArtifactsDirectory)"
|
||||
6
functions/.env.example
Normal file
6
functions/.env.example
Normal file
@ -0,0 +1,6 @@
|
||||
MAILGUN_API_KEY=#{MAILGUN_API_KEY}#
|
||||
MAILGUN_SERVER=#{MAILGUN_SERVER}#
|
||||
MAILGUN_FROM_ADDRESS=#{MAILGUN_FROM_ADDRESS}#
|
||||
TWILIO_ACCOUNT_SID=AC5cfaae728ba68fb1aa6756d973b6e32b
|
||||
TWILIO_AUTH_TOKEN=886ed704c7918078f361f5f88b42ffc0
|
||||
TWILIO_PHONE_NUMBER=+12315005309
|
||||
26
functions/package-lock.json
generated
26
functions/package-lock.json
generated
@ -1,15 +1,18 @@
|
||||
{
|
||||
"name": "functions",
|
||||
"version": "0.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "functions",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"firebase-admin": "^12.6.0",
|
||||
"firebase-functions": "^6.0.1",
|
||||
"form-data": "^4.0.1",
|
||||
"html-to-text": "^9.0.5",
|
||||
"long": "4.0.0",
|
||||
"mailgun.js": "^10.4.0",
|
||||
"twilio": "^5.4.0"
|
||||
},
|
||||
@ -765,6 +768,12 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@grpc/proto-loader/node_modules/long": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.3.1.tgz",
|
||||
"integrity": "sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
||||
@ -2743,9 +2752,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/firebase-functions": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-6.2.0.tgz",
|
||||
"integrity": "sha512-vfyyVHS8elxplzEQ9To+NaINRPFUsDasQrasTa2eFJBYSPzdhkw6rwLmvwyYw622+ze+g4sDIb14VZym+afqXQ==",
|
||||
"version": "6.3.2",
|
||||
"resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-6.3.2.tgz",
|
||||
"integrity": "sha512-FC3A1/nhqt1ZzxRnj5HZLScQaozAcFSD/vSR8khqSoFNOfxuXgwJS6ZABTB7+v+iMD5z6Mmxw6OfqITUBuI7OQ==",
|
||||
"dependencies": {
|
||||
"@types/cors": "^2.8.5",
|
||||
"@types/express": "^4.17.21",
|
||||
@ -4425,9 +4434,9 @@
|
||||
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
|
||||
},
|
||||
"node_modules/long": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
|
||||
"integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q=="
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
|
||||
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "5.1.1",
|
||||
@ -5035,6 +5044,11 @@
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/protobufjs/node_modules/long": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.3.1.tgz",
|
||||
"integrity": "sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng=="
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "functions",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"build:watch": "tsc --watch",
|
||||
@ -18,6 +19,7 @@
|
||||
"firebase-functions": "^6.0.1",
|
||||
"form-data": "^4.0.1",
|
||||
"html-to-text": "^9.0.5",
|
||||
"long": "4.0.0",
|
||||
"mailgun.js": "^10.4.0",
|
||||
"twilio": "^5.4.0"
|
||||
},
|
||||
|
||||
@ -1,11 +1,16 @@
|
||||
import { onRequest } from "firebase-functions/v2/https";
|
||||
import { Request } from "firebase-functions/v2/https";
|
||||
import { onDocumentCreated } from 'firebase-functions/v2/firestore';
|
||||
import * as admin from 'firebase-admin';
|
||||
import * as express from "express";
|
||||
import * as logger from "firebase-functions/logger";
|
||||
|
||||
const formData = require('form-data');
|
||||
const Mailgun = require('mailgun.js');
|
||||
const { convert } = require('html-to-text');
|
||||
const twilio = require('twilio')
|
||||
|
||||
export const sendEmail = onRequest((request, response) => {
|
||||
export const sendEmail = onRequest((request: Request, response: express.Response) => {
|
||||
const mailgun = new Mailgun(formData);
|
||||
const mailGunClient = mailgun.client({ username: 'api', key: process.env.MAILGUN_API_KEY });
|
||||
|
||||
@ -32,11 +37,9 @@ export const sendEmail = onRequest((request, response) => {
|
||||
});
|
||||
});
|
||||
|
||||
export const sendSMS = onRequest((request, response) => {
|
||||
export const sendSMS = onRequest((request: Request, response: express.Response) => {
|
||||
const client = twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
|
||||
|
||||
const { to, body } = request.body;
|
||||
|
||||
client.messages
|
||||
.create({
|
||||
body: body,
|
||||
@ -52,3 +55,81 @@ export const sendSMS = onRequest((request, response) => {
|
||||
response.status(500).json({ success: false, error: error.message });
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
interface Invitation {
|
||||
email: string;
|
||||
phoneNumber: string;
|
||||
gymName: string;
|
||||
invitedByName: string;
|
||||
}
|
||||
|
||||
export const sendInvitationNotification = onDocumentCreated(
|
||||
'invitations/{invitationId}',
|
||||
async (event) => {
|
||||
const invitation = event.data?.data() as Invitation;
|
||||
const invitationId = event.params.invitationId;
|
||||
|
||||
if (!invitation) {
|
||||
console.error('Invitation data is missing.');
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const userQuery = await admin
|
||||
.firestore()
|
||||
.collection('users')
|
||||
.where('email', '==', invitation.email)
|
||||
.where('phoneNumber', '==', invitation.phoneNumber)
|
||||
.limit(1)
|
||||
.get();
|
||||
|
||||
if (userQuery.empty) {
|
||||
console.log(
|
||||
`User not found for email: ${invitation.email} and phone: ${invitation.phoneNumber}.`
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
const user = userQuery.docs[0].data();
|
||||
const fcmToken = user.fcmToken;
|
||||
|
||||
if (!fcmToken) {
|
||||
console.log(`FCM token not found for user: ${invitation.email}.`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const message: admin.messaging.Message = {
|
||||
notification: {
|
||||
title: 'New Gym Invitation',
|
||||
body: `${invitation.invitedByName} has invited you to join ${invitation.gymName}`,
|
||||
},
|
||||
data: {
|
||||
type: 'invitation',
|
||||
invitationId: invitationId,
|
||||
gymName: invitation.gymName,
|
||||
senderName: invitation.invitedByName,
|
||||
},
|
||||
android: {
|
||||
priority: 'high',
|
||||
notification: {
|
||||
channelId: 'invitations_channel',
|
||||
priority: 'high',
|
||||
defaultSound: true,
|
||||
defaultVibrateTimings: true,
|
||||
icon: '@mipmap/ic_launcher',
|
||||
clickAction: 'FLUTTER_NOTIFICATION_CLICK',
|
||||
},
|
||||
},
|
||||
token: fcmToken,
|
||||
};
|
||||
|
||||
await admin.messaging().send(message);
|
||||
console.log(`Invitation notification sent to ${invitation.email}.`);
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.error('Error sending invitation notification:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -2,7 +2,8 @@
|
||||
"compilerOptions": {
|
||||
"module": "NodeNext",
|
||||
"esModuleInterop": true,
|
||||
"moduleResolution": "nodenext",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"moduleResolution": "node16",
|
||||
"noImplicitReturns": true,
|
||||
"noUnusedLocals": true,
|
||||
"outDir": "lib",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user