fitlien-services/functions/src/index.ts
2025-03-13 13:13:35 +05:30

135 lines
4.1 KiB
TypeScript

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: Request, response: express.Response) => {
const mailgun = new Mailgun(formData);
const mailGunClient = mailgun.client({ username: 'api', key: process.env.MAILGUN_API_KEY });
const toAddress = request.body.toAddress;
const subject = request.body.subject;
const message = request.body.message;
const options = {
wordwrap: 130,
};
const textMessage = convert(message, options);
mailGunClient.messages.create(process.env.MAILGUN_SERVER, {
from: process.env.MAILGUN_FROM_ADDRESS,
to: toAddress,
subject: subject,
text: textMessage,
html: message
}).then((res: any) => {
logger.info(res);
response.send(res);
}).catch((err: any) => {
logger.error(err);
response.send(err);
});
});
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,
from: process.env.TWILIO_PHONE_NUMBER,
to: to
})
.then((message: any) => {
logger.info('SMS sent successfully:', message.sid);
response.json({ success: true, messageId: message.sid });
})
.catch((error: any) => {
logger.error('Error sending SMS:', error);
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;
}
}
);