0.12.18 : add create message, conversation
This commit is contained in:
@@ -4,7 +4,8 @@
|
||||
"info": {
|
||||
"singularName": "chat-message",
|
||||
"pluralName": "chat-messages",
|
||||
"displayName": "ChatMessage"
|
||||
"displayName": "ChatMessage",
|
||||
"description": ""
|
||||
},
|
||||
"options": {
|
||||
"draftAndPublish": false
|
||||
@@ -26,6 +27,16 @@
|
||||
},
|
||||
"deletedAt": {
|
||||
"type": "datetime"
|
||||
},
|
||||
"media": {
|
||||
"allowedTypes": [
|
||||
"images",
|
||||
"files",
|
||||
"videos",
|
||||
"audios"
|
||||
],
|
||||
"type": "media",
|
||||
"multiple": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,87 @@
|
||||
* chat-message controller
|
||||
*/
|
||||
|
||||
import { factories } from '@strapi/strapi'
|
||||
import { factories } from "@strapi/strapi";
|
||||
|
||||
export default factories.createCoreController('api::chat-message.chat-message');
|
||||
export default factories.createCoreController(
|
||||
"api::chat-message.chat-message",
|
||||
({ strapi }) => ({
|
||||
async create(ctx) {
|
||||
const userId = ctx.state.user?.id;
|
||||
if (!userId) {
|
||||
return ctx.unauthorized("You must be logged in to send a message");
|
||||
}
|
||||
|
||||
const body = ctx.request.body as any;
|
||||
const data =
|
||||
typeof body?.data === "string"
|
||||
? JSON.parse(body.data)
|
||||
: body?.data || {};
|
||||
|
||||
const { conversation, content, recipientIds } = data;
|
||||
|
||||
if (!content || content.trim() === "") {
|
||||
return ctx.badRequest("Message content is required");
|
||||
}
|
||||
|
||||
let finalConversationId = conversation;
|
||||
|
||||
if (!finalConversationId) {
|
||||
if (
|
||||
!recipientIds ||
|
||||
!Array.isArray(recipientIds) ||
|
||||
recipientIds.length === 0
|
||||
) {
|
||||
return ctx.badRequest(
|
||||
"Either conversationId or recipientIds must be provided"
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const newConversation = await strapi
|
||||
.service("api::chat-conversation.chat-conversation")
|
||||
.createConversationWithMembers(recipientIds, userId);
|
||||
finalConversationId = newConversation.id;
|
||||
} catch (error: any) {
|
||||
return ctx.badRequest(
|
||||
`Failed to create conversation: ${error.message}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
let mediaId: number | undefined;
|
||||
const mediaInput = (ctx.request.files as any)?.media;
|
||||
if (mediaInput) {
|
||||
const file = Array.isArray(mediaInput) ? mediaInput[0] : mediaInput;
|
||||
const uploaded = await strapi
|
||||
.plugin("upload")
|
||||
.service("upload")
|
||||
.upload({
|
||||
data: {
|
||||
fileInfo: {
|
||||
alternativeText: data?.name || "media",
|
||||
caption: "media",
|
||||
name: file.originalFilename || "media",
|
||||
},
|
||||
},
|
||||
files: file,
|
||||
});
|
||||
|
||||
if (uploaded?.[0]?.id) {
|
||||
mediaId = uploaded[0].id;
|
||||
}
|
||||
}
|
||||
const message = await strapi
|
||||
.service("api::chat-message.chat-message")
|
||||
.createMessageInConversation(finalConversationId, userId, content, mediaId);
|
||||
|
||||
ctx.body = {
|
||||
data: message,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return ctx.badRequest(`Failed to create message: ${error.message}`);
|
||||
}
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
@@ -4,4 +4,92 @@
|
||||
|
||||
import { factories } from '@strapi/strapi';
|
||||
|
||||
export default factories.createCoreService('api::chat-message.chat-message');
|
||||
export default factories.createCoreService(
|
||||
'api::chat-message.chat-message',
|
||||
({ strapi }) => ({
|
||||
async createMessageInConversation(
|
||||
conversationId: number,
|
||||
senderId: number,
|
||||
content: string,
|
||||
mediaId?: number
|
||||
) {
|
||||
if (!conversationId) {
|
||||
throw new Error('Conversation ID is required');
|
||||
}
|
||||
|
||||
if (!senderId) {
|
||||
throw new Error('Sender ID is required');
|
||||
}
|
||||
|
||||
if (!content || content.trim() === '') {
|
||||
throw new Error('Message content is required and cannot be empty');
|
||||
}
|
||||
|
||||
const conversation = await strapi.db
|
||||
.query('api::chat-conversation.chat-conversation')
|
||||
.findOne({
|
||||
where: { id: conversationId },
|
||||
});
|
||||
|
||||
if (!conversation) {
|
||||
throw new Error(`Conversation with ID ${conversationId} not found`);
|
||||
}
|
||||
|
||||
const member = await strapi.db
|
||||
.query('api::chat-conversation-member.chat-conversation-member')
|
||||
.findOne({
|
||||
where: {
|
||||
user: { id: senderId },
|
||||
conversation: { id: conversationId },
|
||||
},
|
||||
});
|
||||
|
||||
if (!member) {
|
||||
throw new Error(
|
||||
'User is not a member of this conversation'
|
||||
);
|
||||
}
|
||||
|
||||
if (mediaId) {
|
||||
const media = await strapi.db
|
||||
.query('plugin::upload.file')
|
||||
.findOne({
|
||||
where: { id: mediaId },
|
||||
});
|
||||
|
||||
if (!media) {
|
||||
throw new Error(`Media with ID ${mediaId} not found`);
|
||||
}
|
||||
}
|
||||
|
||||
const messageData: any = {
|
||||
sender: senderId,
|
||||
content: content.trim(),
|
||||
isEdited: false,
|
||||
};
|
||||
|
||||
if (mediaId) {
|
||||
messageData.media = mediaId;
|
||||
}
|
||||
|
||||
const message = await strapi.db
|
||||
.query('api::chat-message.chat-message')
|
||||
.create({
|
||||
data: messageData,
|
||||
});
|
||||
|
||||
await strapi.db
|
||||
.query('api::chat-conversation.chat-conversation')
|
||||
.update({
|
||||
where: { id: conversationId },
|
||||
data: {
|
||||
messages: {
|
||||
connect: [{ id: message.id }],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return message;
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user