feat: reactions

This commit is contained in:
Timothy Jaeryang Baek
2024-12-30 23:06:34 -08:00
parent 4b0fa112bb
commit f93c2e4a8d
9 changed files with 479 additions and 69 deletions

View File

@@ -11,7 +11,12 @@ from open_webui.socket.main import sio, get_user_ids_from_room
from open_webui.models.users import Users, UserNameResponse
from open_webui.models.channels import Channels, ChannelModel, ChannelForm
from open_webui.models.messages import Messages, MessageModel, MessageForm
from open_webui.models.messages import (
Messages,
MessageModel,
MessageResponse,
MessageForm,
)
from open_webui.config import ENABLE_ADMIN_CHAT_ACCESS, ENABLE_ADMIN_EXPORT
@@ -49,7 +54,7 @@ async def get_channels(user=Depends(get_verified_user)):
@router.post("/create", response_model=Optional[ChannelModel])
async def create_new_channel(form_data: ChannelForm, user=Depends(get_admin_user)):
try:
channel = Channels.insert_new_channel(form_data, user.id)
channel = Channels.insert_new_channel(None, form_data, user.id)
return ChannelModel(**channel.model_dump())
except Exception as e:
log.exception(e)
@@ -134,11 +139,11 @@ async def delete_channel_by_id(id: str, user=Depends(get_admin_user)):
############################
class MessageUserModel(MessageModel):
class MessageUserResponse(MessageResponse):
user: UserNameResponse
@router.get("/{id}/messages", response_model=list[MessageUserModel])
@router.get("/{id}/messages", response_model=list[MessageUserResponse])
async def get_channel_messages(
id: str, skip: int = 0, limit: int = 50, user=Depends(get_verified_user)
):
@@ -165,9 +170,10 @@ async def get_channel_messages(
users[message.user_id] = user
messages.append(
MessageUserModel(
MessageUserResponse(
**{
**message.model_dump(),
"reactions": Messages.get_reactions_by_message_id(message.id),
"user": UserNameResponse(**users[message.user_id].model_dump()),
}
)
@@ -333,6 +339,140 @@ async def update_message_by_id(
)
############################
# AddReactionToMessage
############################
class ReactionForm(BaseModel):
name: str
@router.post("/{id}/messages/{message_id}/reactions/add", response_model=bool)
async def add_reaction_to_message(
id: str, message_id: str, form_data: ReactionForm, user=Depends(get_verified_user)
):
channel = Channels.get_channel_by_id(id)
if not channel:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
)
if user.role != "admin" and not has_access(
user.id, type="read", access_control=channel.access_control
):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT()
)
message = Messages.get_message_by_id(message_id)
if not message:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
)
if message.channel_id != id:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT()
)
try:
Messages.add_reaction_to_message(message_id, user.id, form_data.name)
message = Messages.get_message_by_id(message_id)
await sio.emit(
"channel-events",
{
"channel_id": channel.id,
"message_id": message.id,
"data": {
"type": "message:reaction",
"data": {
**message.model_dump(),
"user": UserNameResponse(**user.model_dump()).model_dump(),
"name": form_data.name,
},
},
"user": UserNameResponse(**user.model_dump()).model_dump(),
"channel": channel.model_dump(),
},
to=f"channel:{channel.id}",
)
return True
except Exception as e:
log.exception(e)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT()
)
############################
# RemoveReactionById
############################
@router.post("/{id}/messages/{message_id}/reactions/remove", response_model=bool)
async def remove_reaction_by_id_and_user_id_and_name(
id: str, message_id: str, form_data: ReactionForm, user=Depends(get_verified_user)
):
channel = Channels.get_channel_by_id(id)
if not channel:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
)
if user.role != "admin" and not has_access(
user.id, type="read", access_control=channel.access_control
):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT()
)
message = Messages.get_message_by_id(message_id)
if not message:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
)
if message.channel_id != id:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT()
)
try:
Messages.remove_reaction_by_id_and_user_id_and_name(
message_id, user.id, form_data.name
)
message = Messages.get_message_by_id(message_id)
await sio.emit(
"channel-events",
{
"channel_id": channel.id,
"message_id": message.id,
"data": {
"type": "message:reaction",
"data": {
**message.model_dump(),
"user": UserNameResponse(**user.model_dump()).model_dump(),
"name": form_data.name,
},
},
"user": UserNameResponse(**user.model_dump()).model_dump(),
"channel": channel.model_dump(),
},
to=f"channel:{channel.id}",
)
return True
except Exception as e:
log.exception(e)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT()
)
############################
# DeleteMessageById
############################