Skip to content

Commit

Permalink
1. Added rest api to fetch the count of each status in ChannelLogs fo…
Browse files Browse the repository at this point in the history
…r Campaign Analytics.

2. Added unit and integration test cases.
  • Loading branch information
Nupur Khare committed Dec 14, 2023
1 parent 416681a commit dcd15e1
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 4 deletions.
14 changes: 14 additions & 0 deletions kairon/api/app/routers/bot/channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,17 @@ async def retrieve_scheduled_message_broadcast_logs(
log_filters = request.query_params._dict.copy()
logs, total_count = MessageBroadcastProcessor.get_broadcast_logs(current_user.get_bot(), **log_filters)
return Response(data={"logs": logs, "total_count": total_count})


@router.get("/whatsapp/logs", response_model=Response)
async def get_channel_logs_count(
current_user: User = Security(Authentication.get_current_user_and_bot, scopes=TESTER_ACCESS)
):
"""
Get Channel logs count.
"""
channel_logs_count = MessageBroadcastProcessor.get_channel_logs_count(current_user.get_bot())
data = {
'count': channel_logs_count
}
return Response(data=data)
4 changes: 3 additions & 1 deletion kairon/chat/agent/message_processor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from typing import Tuple, Optional, Text

import rasa
from rasa.core.actions.action import Action, ActionRetrieveResponse, ActionEndToEndResponse, RemoteAction, default_actions
from rasa.core.actions.action import Action, ActionRetrieveResponse, ActionEndToEndResponse, RemoteAction, \
default_actions
from rasa.core.channels import UserMessage, OutputChannel, CollectingOutputChannel
from rasa.core.policies.policy import PolicyPrediction
from rasa.core.processor import MessageProcessor, logger
Expand Down
28 changes: 28 additions & 0 deletions kairon/shared/chat/broadcast/processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,31 @@ def insert_status_received_on_channel_webhook(reference_id: Text):
broadcast_logs = MessageBroadcastProcessor.extract_message_ids_from_broadcast_logs(reference_id)
if broadcast_logs:
MessageBroadcastProcessor.__add_broadcast_logs_status_and_errors(reference_id, broadcast_logs)

@staticmethod
def get_channel_logs_count(bot: Text):
result = list(ChannelLogs.objects.aggregate([
{
'$match': {
'bot': bot
}
}, {
'$group': {
'_id': {
'campaign_id': '$campaign_id',
'status': '$status'
},
'count': {
'$sum': 1
}
}
}, {
'$project': {
'status': '$_id.status',
'campaign_id': '$_id.campaign_id',
'cnt': '$count',
'_id': 0
}
}
]))
return result
7 changes: 4 additions & 3 deletions kairon/shared/chat/processor.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from datetime import datetime
from typing import Dict, Text

from mongoengine import DoesNotExist
from loguru import logger
from .data_objects import Channels, ChannelLogs
from datetime import datetime
from mongoengine import DoesNotExist

from kairon.shared.utils import Utility
from .data_objects import Channels, ChannelLogs
from ..constants import ChannelTypes
from ..data.utils import DataUtility
from ...exceptions import AppException
Expand Down
45 changes: 45 additions & 0 deletions tests/integration_test/services_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14054,6 +14054,51 @@ def test_list_whatsapp_templates_error():
assert actual["message"] == "Channel not found!"


def test_get_channel_logs():
from kairon.shared.chat.data_objects import ChannelLogs
ChannelLogs(
status='read',
data={'id': 'CONVERSATION_ID', 'expiration_timestamp': '1691598412',
'origin': {'type': 'business_initated'}},
initiator='business_initated',
campaign_id='6779002886649302',
message_id='wamid.HBgLMTIxMTU1NTc5NDcVAgARGBIyRkQxREUxRDJFQUJGMkQ3NDIZ',
bot=pytest.bot,
user='[email protected]'
).save()
ChannelLogs(
status='delivered',
data={'id': 'CONVERSATION_ID', 'expiration_timestamp': '1621598412',
'origin': {'type': 'business_initated'}},
initiator='business_initated',
campaign_id='6779002886649302',
message_id='wamid.HBgLMTIxMTU1NTc5NDcVAgARGBIyRkQxREUxRDJFQUJGMkQ3NDIZ',
bot=pytest.bot,
user='[email protected]'
).save()
ChannelLogs(
status='sent',
data={'id': 'CONVERSATION_ID', 'expiration_timestamp': '1631598412',
'origin': {'type': 'business_initated'}},
initiator='business_initated',
campaign_id='6779002886649302',
message_id='wamid.HBgLMTIxMTU1NTc5NDcVAgARGBIyRkQxREUxRDJFQUJGMkQ3NDIZ',
bot=pytest.bot,
user='[email protected]'
).save()
response = client.get(
f"/api/bot/{pytest.bot}/channels/whatsapp/logs",
headers={"Authorization": pytest.token_type + " " + pytest.access_token},
)
actual = response.json()
print(actual)
assert actual["success"]
assert actual["error_code"] == 0
assert actual["data"] == {'count': [{'status': 'delivered', 'campaign_id': '6779002886649302', 'cnt': 1},
{'status': 'read', 'campaign_id': '6779002886649302', 'cnt': 1},
{'status': 'sent', 'campaign_id': '6779002886649302', 'cnt': 1}]}


@responses.activate
def test_initiate_bsp_onboarding_without_channels(monkeypatch):
def _mock_get_bot_settings(*args, **kwargs):
Expand Down
3 changes: 3 additions & 0 deletions tests/unit_test/events/events_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,9 @@ def test_execute_message_broadcast_with_logs_modification(self, mock_is_exist, m
'details': "Failed to send message because this user's phone number is part of an experiment"},
'href': 'https://developers.facebook.com/docs/whatsapp/cloud-api/support/error-codes/'}]}
assert ChannelLogs.objects(bot=bot, message_id='wamid.HBgLMTIxMTU1NTc5NDcVAgARGBIyRkQxREUxRDJFQUJGMkQ3NDIZ').get().campaign_id == reference_id
result = MessageBroadcastProcessor.get_channel_logs_count(bot)
print(result)
assert result == [{'status': 'Failed', 'campaign_id': reference_id, 'cnt': 1}]

@responses.activate
@mongomock.patch(servers=(('localhost', 27017),))
Expand Down

0 comments on commit dcd15e1

Please sign in to comment.