0.12.19 : better notifications
All checks were successful
Build release Docker image / Build Docker Images (push) Successful in 7m2s

This commit is contained in:
2026-01-19 00:07:21 +01:00
parent 0bb06e0e2d
commit e18a3fa092
6 changed files with 144 additions and 50 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "harmony-back", "name": "harmony-back",
"version": "0.12.18", "version": "0.12.19",
"private": true, "private": true,
"description": "A Strapi application", "description": "A Strapi application",
"scripts": { "scripts": {

View File

@@ -75,10 +75,74 @@ export default factories.createCoreController(
} }
const message = await strapi const message = await strapi
.service("api::chat-message.chat-message") .service("api::chat-message.chat-message")
.createMessageInConversation(finalConversationId, userId, content, mediaId); .createMessageInConversation(
finalConversationId,
userId,
content,
mediaId
);
const currentUser = await strapi.entityService.findOne(
"plugin::users-permissions.user",
userId,
{ populate: { avatar: true } }
);
const conversation = await strapi.entityService.findOne(
"api::chat-conversation.chat-conversation",
finalConversationId,
{ populate: { users: true } }
);
const conversationMembers = (conversation as any)?.users || [];
const today = new Date();
today.setHours(0, 0, 0, 0);
for (const member of conversationMembers) {
if (member.id === userId) continue;
const existingNotifications = await strapi.entityService.findMany(
"api::notification.notification",
{
filters: {
$and: [
{ type: "messageSent" },
{ target_user: member.id },
{ floodId: finalConversationId },
],
},
sort: { createdAt: "desc" },
}
);
const hasNotificationToday = existingNotifications?.some(
(notification: any) => {
const notificationDate = new Date(notification.createdAt);
notificationDate.setHours(0, 0, 0, 0);
return notificationDate.getTime() === today.getTime();
}
);
if (!hasNotificationToday) {
await strapi
.service("api::notification.notification")
?.createNotification({
message: `Tu as reçu un message de ${currentUser?.name}`,
type: "messageSent",
target_user: member.id,
source: "user",
floodId: finalConversationId,
payload: {
avatar: (currentUser as any)?.avatar?.url,
url: `/app/chat/${finalConversationId}`,
},
});
}
}
ctx.body = { ctx.body = {
data: message, data: message,
conversationId: finalConversationId,
}; };
} catch (error: any) { } catch (error: any) {
return ctx.badRequest(`Failed to create message: ${error.message}`); return ctx.badRequest(`Failed to create message: ${error.message}`);

View File

@@ -4,26 +4,24 @@
"info": { "info": {
"singularName": "notification", "singularName": "notification",
"pluralName": "notifications", "pluralName": "notifications",
"displayName": "Notification" "displayName": "Notification",
"description": ""
}, },
"options": { "options": {
"draftAndPublish": false "draftAndPublish": false
}, },
"pluginOptions": {}, "pluginOptions": {},
"attributes": { "attributes": {
"title": {
"type": "string"
},
"message": { "message": {
"type": "string" "type": "string"
}, },
"type": { "type": {
"type": "enumeration", "type": "enumeration",
"enum": [ "enum": [
"info", "accountCreation",
"success", "friendRequest",
"warning", "messageSent",
"error" "postCreated"
] ]
}, },
"target_user": { "target_user": {
@@ -35,11 +33,20 @@
"type": "boolean", "type": "boolean",
"default": false "default": false
}, },
"source": {
"type": "string"
},
"payload": { "payload": {
"type": "json" "type": "json"
},
"source": {
"type": "enumeration",
"enum": [
"system",
"user",
"group",
"choral"
]
},
"floodId": {
"type": "integer"
} }
} }
} }

View File

@@ -4,6 +4,7 @@ interface NotificationPayload {
type?: "info" | "success" | "warning" | "error"; type?: "info" | "success" | "warning" | "error";
target_user?: number; target_user?: number;
source?: string; source?: string;
floodId?: number;
payload?: Record<string, any>; payload?: Record<string, any>;
} }
@@ -14,6 +15,7 @@ interface NotificationEntity {
type: string; type: string;
target_user?: number; target_user?: number;
source?: string; source?: string;
floodId?: number;
payload?: Record<string, any>; payload?: Record<string, any>;
read: boolean; read: boolean;
createdAt: string; createdAt: string;
@@ -38,21 +40,21 @@ export default factories.createCoreService(
({ strapi }: { strapi }) => ({ ({ strapi }: { strapi }) => ({
//Custom service for add notification. //Custom service for add notification.
async createNotification({ async createNotification({
title,
message, message,
type = "info", type = "info",
target_user, target_user,
source, source,
floodId,
payload, payload,
}: NotificationPayload): Promise<NotificationEntity> { }: NotificationPayload): Promise<NotificationEntity> {
const data = { title, message, type, target_user, source, payload }; const data = { message, type, target_user, source, floodId, payload };
const notification = await strapi.entityService.create( const notification = await strapi.entityService.create(
"api::notification.notification", "api::notification.notification",
{ data } { data }
); );
strapi.log.info(`🔔 Notification créée: ${title}`); strapi.log.info(`🔔 Notification créée: ${message}`);
return notification; return notification;
}, },
async addActivity({ async addActivity({

View File

@@ -14,7 +14,7 @@
"name": "Apache 2.0", "name": "Apache 2.0",
"url": "https://www.apache.org/licenses/LICENSE-2.0.html" "url": "https://www.apache.org/licenses/LICENSE-2.0.html"
}, },
"x-generation-date": "2026-01-16T10:01:51.447Z" "x-generation-date": "2026-01-18T23:07:12.280Z"
}, },
"x-strapi-config": { "x-strapi-config": {
"plugins": [ "plugins": [
@@ -108357,19 +108357,16 @@
"data": { "data": {
"type": "object", "type": "object",
"properties": { "properties": {
"title": {
"type": "string"
},
"message": { "message": {
"type": "string" "type": "string"
}, },
"type": { "type": {
"type": "string", "type": "string",
"enum": [ "enum": [
"info", "accountCreation",
"success", "friendRequest",
"warning", "messageSent",
"error" "postCreated"
] ]
}, },
"target_user": { "target_user": {
@@ -108386,10 +108383,19 @@
"read": { "read": {
"type": "boolean" "type": "boolean"
}, },
"source": {
"type": "string"
},
"payload": {}, "payload": {},
"source": {
"type": "string",
"enum": [
"system",
"user",
"group",
"choral"
]
},
"floodId": {
"type": "integer"
},
"locale": { "locale": {
"type": "string" "type": "string"
}, },
@@ -108455,19 +108461,16 @@
"documentId": { "documentId": {
"type": "string" "type": "string"
}, },
"title": {
"type": "string"
},
"message": { "message": {
"type": "string" "type": "string"
}, },
"type": { "type": {
"type": "string", "type": "string",
"enum": [ "enum": [
"info", "accountCreation",
"success", "friendRequest",
"warning", "messageSent",
"error" "postCreated"
] ]
}, },
"target_user": { "target_user": {
@@ -112116,10 +112119,19 @@
"read": { "read": {
"type": "boolean" "type": "boolean"
}, },
"source": {
"type": "string"
},
"payload": {}, "payload": {},
"source": {
"type": "string",
"enum": [
"system",
"user",
"group",
"choral"
]
},
"floodId": {
"type": "integer"
},
"createdAt": { "createdAt": {
"type": "string", "type": "string",
"format": "date-time" "format": "date-time"
@@ -112168,19 +112180,16 @@
"documentId": { "documentId": {
"type": "string" "type": "string"
}, },
"title": {
"type": "string"
},
"message": { "message": {
"type": "string" "type": "string"
}, },
"type": { "type": {
"type": "string", "type": "string",
"enum": [ "enum": [
"info", "accountCreation",
"success", "friendRequest",
"warning", "messageSent",
"error" "postCreated"
] ]
}, },
"target_user": { "target_user": {
@@ -112197,10 +112206,19 @@
"read": { "read": {
"type": "boolean" "type": "boolean"
}, },
"source": {
"type": "string"
},
"payload": {}, "payload": {},
"source": {
"type": "string",
"enum": [
"system",
"user",
"group",
"choral"
]
},
"floodId": {
"type": "integer"
},
"createdAt": { "createdAt": {
"type": "string", "type": "string",
"format": "date-time" "format": "date-time"

View File

@@ -1333,6 +1333,7 @@ export interface ApiNotificationNotification
extends Struct.CollectionTypeSchema { extends Struct.CollectionTypeSchema {
collectionName: 'notifications'; collectionName: 'notifications';
info: { info: {
description: '';
displayName: 'Notification'; displayName: 'Notification';
pluralName: 'notifications'; pluralName: 'notifications';
singularName: 'notification'; singularName: 'notification';
@@ -1344,6 +1345,7 @@ export interface ApiNotificationNotification
createdAt: Schema.Attribute.DateTime; createdAt: Schema.Attribute.DateTime;
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> & createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
Schema.Attribute.Private; Schema.Attribute.Private;
floodId: Schema.Attribute.Integer;
locale: Schema.Attribute.String & Schema.Attribute.Private; locale: Schema.Attribute.String & Schema.Attribute.Private;
localizations: Schema.Attribute.Relation< localizations: Schema.Attribute.Relation<
'oneToMany', 'oneToMany',
@@ -1354,13 +1356,14 @@ export interface ApiNotificationNotification
payload: Schema.Attribute.JSON; payload: Schema.Attribute.JSON;
publishedAt: Schema.Attribute.DateTime; publishedAt: Schema.Attribute.DateTime;
read: Schema.Attribute.Boolean & Schema.Attribute.DefaultTo<false>; read: Schema.Attribute.Boolean & Schema.Attribute.DefaultTo<false>;
source: Schema.Attribute.String; source: Schema.Attribute.Enumeration<['system', 'user', 'group', 'choral']>;
target_user: Schema.Attribute.Relation< target_user: Schema.Attribute.Relation<
'oneToOne', 'oneToOne',
'plugin::users-permissions.user' 'plugin::users-permissions.user'
>; >;
title: Schema.Attribute.String; type: Schema.Attribute.Enumeration<
type: Schema.Attribute.Enumeration<['info', 'success', 'warning', 'error']>; ['accountCreation', 'friendRequest', 'messageSent', 'postCreated']
>;
updatedAt: Schema.Attribute.DateTime; updatedAt: Schema.Attribute.DateTime;
updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> & updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
Schema.Attribute.Private; Schema.Attribute.Private;