T-emergency / hands-up-backend

7 stars 3 forks source link

✨ [ Feat ] 알람 기능 #76

Closed KimGyeongMin-KR closed 1 year ago

KimGyeongMin-KR commented 1 year ago

Description ( 기능 설명 )

Todo

작업 브랜치

feature/auction

ETC

3983b30d1a05de6b097177b5805cddc76ef533f0

KimGyeongMin-KR commented 1 year ago

입찰 경쟁

chat/consumer.py

@database_sync_to_async
def set_high_price(self, goods:object, user_id, money):

    if goods.high_price >= money or goods.status != True: # 방어코드
      return False

    Bid.objects.create(goods_id=goods.id, price=money, user_id=user_id)

    layer = get_channel_layer()
    data = {
      'response_type' : 'alram',
      'message' : '다른 핸더가 입찰했어요!',
      'goods_id' : goods.id,
      'goods_title' : goods.title,
    }
    if(goods.buyer_id != user_id):
      async_to_sync(layer.group_send)(f'alram_{goods.buyer_id}', {'type': 'chat_message', 'response': json.dumps(data)})

3983b30d1a05de6b097177b5805cddc76ef533f0 set_high_price에서 유효한 값이 들어왔을 때 갱신되기 전 buyer에게 알림을 날리고 buyer를 갱신합니다.

KimGyeongMin-KR commented 1 year ago

채팅 메시지 알림

chat/consumer.py

response = {
  'response_type' : 'chat_alram',
  'message': message,
  'sender': user.id,
  'sender_name': user.username,
  'goods_id': goods_id,
  # 'time': datetime.now(),
} 
await self.channel_layer.group_send(
f'alram_{goods.buyer_id}',
  {
    'type': 'chat_message',
    'response': json.dumps(response)
  }
  )
await self.channel_layer.group_send(
  f'alram_{goods.seller_id}',
  {
    'type': 'chat_message',
    'response': json.dumps(response)
  }
)

메시지를 받으면 buyer와 seller에게 모두 보낸다음 프론트에서 내가 보낸 알림은 나오지 않게 처리한다.

백엔드에서 현재 로그인한 사람과 대조해서 한 명에게만 보내는 것이 더 좋을 것으로 판단

KimGyeongMin-KR commented 1 year ago

경매 시작 & 종료 알림

goods/crontab.py

시작 알림

# TODO 최적화 생각하기
for goods in auction_start_list:
    data = {
        'response_type' : 'alram',
        'message' : '경매가 시작됐어요',
        'goods_id' : goods.id,
        'goods_title' : goods.title,
    }
    for receiver in goods.like.all():
        # TODO send()로는 안되는지 확인
        async_to_sync(layer.group_send)(f'alram_{receiver.id}', {'type': 'chat_message', 'response': json.dumps(data)})

시작하는 상품들에서 상품을 좋아하는 사람들에게 알림을 보낸다.

고려점 : 이중 for문이기는 하지만 결국 같은 수의 사람들에게 알림을 보낸다. 쿼리문을 좀 더 고려하여서 for문을 한 번만 날리는 것도 재밌겠다.

종료 알림

for goods in auction_end_list:
            data = {
                'response_type' : 'alram',
                'message' : '낙찰 되었습니다!',
                'goods_id' : goods.id,
                'goods_title' : goods.title,
            }
            room = TradeChatRoom.objects.create()
            async_to_sync(layer.group_send)(f'alram_{goods.buyer_id}', {'type': 'chat_message', 'response': json.dumps(data)})
            goods.trade_room = room
            goods.save()
        auction_end_list.update(status=False)

기존 끝나는 경매에 goods.buyer.id를 이용하여 알림을 보냈으나 buyer가 없을 경우를 미처 생각 못하여 goods.buyer_id를 이용 그리고 buyer가 없으면 TradeRoom은 만들어질 필요는 없음. bulk_create로 시간을 줄이는 것 고려 필요