Skip to main content
Glama
newsletter.controller.ts6.7 kB
import { logger } from '@logger'; import type { ResponseWithSession } from '@middlewares/sessionAuth.middleware'; import * as userService from '@services/user.service'; import { type AppError, ErrorHandler } from '@utils/errors'; import { mapUserToAPI } from '@utils/mapper/user'; import { hasPermission } from '@utils/permissions'; import { formatResponse, type ResponseData } from '@utils/responseData'; import type { NextFunction, Request } from 'express'; import { t } from 'express-intlayer'; import type { EmailsList, UserAPI } from '@/types/user.types'; export type NewsletterSubscriptionBody = { email: string; emailList: EmailsList | EmailsList[]; }; export type NewsletterSubscriptionResult = ResponseData<UserAPI>; /** * Subscribes a user to the newsletter. * If the user doesn't exist, creates a new user. * If the user exists, updates their newsletter subscription to true. */ export const subscribeToNewsletter = async ( req: Request<any, any, NewsletterSubscriptionBody>, res: ResponseWithSession<NewsletterSubscriptionResult>, _next: NextFunction ): Promise<void> => { const { roles } = res.locals; const { email, emailList } = req.body; if (!email) { ErrorHandler.handleGenericErrorResponse(res, 'USER_DATA_NOT_FOUND'); return; } const emailLists = Array.isArray(emailList) ? emailList : [emailList]; // Create new user with newsletter subscription enabled const emailsListObject = Object.fromEntries( emailLists.map((list) => [list, true]) ) as Record<EmailsList, boolean>; try { // Check if user exists let user = await userService.getUserByEmail(email); if (!user) { user = await userService.createUser({ email, emailsList: emailsListObject, }); logger.info(`New user created and subscribed to newsletter: ${email}`); } else { if ( !hasPermission( roles, 'user:write' )({ ...res.locals, targetUsers: [user], }) ) { ErrorHandler.handleGenericErrorResponse(res, 'PERMISSION_DENIED'); return; } // Update existing user's newsletter subscription user = await userService.updateUserById(user.id, { emailsList: { ...user.emailsList, ...emailsListObject }, }); logger.info(`User subscribed to newsletter: ${email}`); } const formattedUser = mapUserToAPI(user); const responseData = formatResponse<UserAPI>({ message: t({ en: 'Successfully subscribed to newsletter', fr: 'Abonnement à la newsletter réussi', es: 'Suscripción al boletín exitosa', }), description: t({ en: 'You have been successfully subscribed to our newsletter', fr: 'Vous avez été abonné avec succès à notre newsletter', es: 'Te has suscrito exitosamente a nuestro boletín', }), data: formattedUser, }); res.json(responseData); return; } catch (error) { ErrorHandler.handleAppErrorResponse(res, error as AppError); return; } }; export type NewsletterUnsubscriptionBody = { userId: string; emailList: EmailsList | EmailsList[]; }; /** * Unsubscribes a user from the newsletter. * Only works if the user exists. */ export const unsubscribeFromNewsletter = async ( req: Request<any, any, NewsletterUnsubscriptionBody>, res: ResponseWithSession<NewsletterSubscriptionResult>, _next: NextFunction ): Promise<void> => { const { userId, emailList } = req.body; const { roles } = res.locals; if (!userId) { ErrorHandler.handleGenericErrorResponse(res, 'USER_DATA_NOT_FOUND'); return; } try { // Check if user exists const user = await userService.getUserById(userId); if (!user) { ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND'); return; } if ( !hasPermission( roles, 'user:write' )({ ...res.locals, targetUsers: [user], }) ) { ErrorHandler.handleGenericErrorResponse(res, 'PERMISSION_DENIED'); return; } const emailLists = Array.isArray(emailList) ? emailList : [emailList]; // Create new user with newsletter subscription enabled const emailsListObject = Object.fromEntries( emailLists.map((list) => [list, false]) ) as Record<EmailsList, boolean>; // Update user's newsletter subscription to false const updatedUser = await userService.updateUserById(user.id, { emailsList: { ...user.emailsList, ...emailsListObject }, }); logger.info(`User unsubscribed from newsletter: ${updatedUser.email}`); const formattedUser = mapUserToAPI(updatedUser); const responseData = formatResponse<UserAPI>({ message: t({ en: 'Successfully unsubscribed from newsletter', fr: 'Désabonnement de la newsletter réussi', es: 'Cancelación de suscripción al boletín exitosa', }), description: t({ en: 'You have been successfully unsubscribed from our newsletter', fr: 'Vous avez été désabonné avec succès de notre newsletter', es: 'Te has desuscrito exitosamente de nuestro boletín', }), data: formattedUser, }); res.json(responseData); return; } catch (error) { ErrorHandler.handleAppErrorResponse(res, error as AppError); return; } }; /** * Gets the newsletter subscription status for a user. */ export const getNewsletterStatus = async ( _req: Request<{ email: string }>, res: ResponseWithSession<NewsletterSubscriptionResult>, _next: NextFunction ): Promise<void> => { const email = res.locals.user?.email; const { roles } = res.locals; if (!email) { ErrorHandler.handleGenericErrorResponse(res, 'USER_DATA_NOT_FOUND'); return; } try { const user = await userService.getUserByEmail(email); if (!user) { ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND'); return; } if ( !hasPermission( roles, 'user:read' )({ ...res.locals, targetUsers: [user], }) ) { ErrorHandler.handleGenericErrorResponse(res, 'PERMISSION_DENIED'); return; } const formattedUser = mapUserToAPI(user); const responseData = formatResponse<UserAPI>({ message: t({ en: 'Newsletter subscription status retrieved', fr: "Statut d'abonnement à la newsletter récupéré", es: 'Estado de suscripción al boletín obtenido', }), data: formattedUser, }); res.json(responseData); return; } catch (error) { ErrorHandler.handleAppErrorResponse(res, error as AppError); return; } };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aymericzip/intlayer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server