diff --git a/api/helpers/db_helper.py b/api/helpers/db_helper.py index 23f46ed4..c0092abd 100644 --- a/api/helpers/db_helper.py +++ b/api/helpers/db_helper.py @@ -39,3 +39,11 @@ def get_program_prompt_id(jsonData): def save(data): db.session.add(data) db.session.commit() + + +def get_user_by_phone(phone): + return models.User.query.get_by_phone(phone) + + +def get_registrant_by_phone(phone): + return models.Registration.query.get_latest_by_phone(phone) diff --git a/api/models/__init__.py b/api/models/__init__.py index 4f426b0b..86e9e7ae 100644 --- a/api/models/__init__.py +++ b/api/models/__init__.py @@ -16,3 +16,4 @@ from .user_module_content import * from .ivr_prompt import * from .ivr_prompt_response import * +from .user_group import * diff --git a/api/models/user_group.py b/api/models/user_group.py new file mode 100644 index 00000000..e09e56fa --- /dev/null +++ b/api/models/user_group.py @@ -0,0 +1,33 @@ +from api.mixins import TimestampMixin +from api import db, helpers +from flask_sqlalchemy import BaseQuery +from sqlalchemy import desc, and_ + + +class UserGroupQuery(BaseQuery): + def get_by_uuid(self, uuid): + return self.filter(UserGroup.group_uuid == uuid).first() + + def get_unique(self, uuid, phone): + return ( + self.filter( + and_( + UserGroup.group_uuid == uuid, + UserGroup.user_phone == phone, + ) + ) + .order_by(desc(UserGroup.created_on)) + .first() + ) + + +class UserGroup(TimestampMixin, db.Model): + query_class = UserGroupQuery + __tablename__ = "user_group" + id = db.Column(db.Integer, primary_key=True) + user_phone = db.Column(db.String(50), nullable=False) + user_id = db.Column(db.Integer, db.ForeignKey("user.id")) + registration_id = db.Column(db.Integer, db.ForeignKey("registration.id")) + group_name = db.Column(db.String(255), nullable=False) + group_uuid = db.Column(db.String(255)) + status = db.Column(db.String(100)) diff --git a/api/services/__init__.py b/api/services/__init__.py index 77dd46a0..31ec53a6 100644 --- a/api/services/__init__.py +++ b/api/services/__init__.py @@ -2,3 +2,4 @@ from .call_log_service import * from .prompt_service import * from .content_service import * +from .user_group_service import * diff --git a/api/services/call_log_service.py b/api/services/call_log_service.py index 87ceb414..89e8ebbf 100644 --- a/api/services/call_log_service.py +++ b/api/services/call_log_service.py @@ -113,17 +113,18 @@ def handle_parent_flow(self, jsonData): parent_flow_data = {} parent_flow_data["parent_flow_name"] = None parent_flow_data["parent_flow_run_uuid"] = None - if "parent" in jsonData and "flow" in jsonData["parent"]: - parent_flow = jsonData["parent"]["flow"] - parent_flow_data["parent_flow_name"] = parent_flow["name"] - missedcall_category_list = helpers.list_having_string( - parent_flow["name"], self.missedcall_flow_identifier - ) - if missedcall_category_list: - """The call category is set to call back if missedcall flow has ran. - For that, the missed call flow name should contains string "missedcall" - """ - self.call_category = models.CallLog.CallCategories.CALLBACK + if "parent" in jsonData and jsonData["parent"] is not None: + if "flow" in jsonData["parent"]: + parent_flow = jsonData["parent"]["flow"] + parent_flow_data["parent_flow_name"] = parent_flow["name"] + missedcall_category_list = helpers.list_having_string( + parent_flow["name"], self.missedcall_flow_identifier + ) + if missedcall_category_list: + """The call category is set to call back if missedcall flow has ran. + For that, the missed call flow name should contain string "missedcall" + """ + self.call_category = models.CallLog.CallCategories.CALLBACK if "uuid" in jsonData["parent"]: parent_flow_data["parent_flow_run_uuid"] = jsonData["parent"]["uuid"] return parent_flow_data diff --git a/api/services/prompt_service.py b/api/services/prompt_service.py index ea6cf82f..e2d26842 100644 --- a/api/services/prompt_service.py +++ b/api/services/prompt_service.py @@ -10,7 +10,11 @@ def __init__(self): def set_init_data(self, jsonData): user_phone = helpers.fetch_by_key("urn", jsonData["contact"]) self.user_phone = helpers.sanitize_phone_string(user_phone) - flow_run_uuid = helpers.fetch_by_key("run_uuid", jsonData) + flow_run_uuid = helpers.fetch_by_key( + "run_uuid", jsonData + ) # Need to remove once we are done with making changes in webhooks + if "flow_run_details" in jsonData: + flow_run_uuid = helpers.fetch_by_key("uuid", jsonData["flow_run_details"]) call_log_details = models.CallLog.query.get_by_flow_run_uuid(flow_run_uuid) self.call_log_id = call_log_details.id diff --git a/api/services/registration_service.py b/api/services/registration_service.py index 9cfce5ff..b92c8a5b 100644 --- a/api/services/registration_service.py +++ b/api/services/registration_service.py @@ -20,7 +20,13 @@ def set_init_data(self, jsonData): def handle_registration(self, jsonData): try: self.set_init_data(jsonData) - flow_run_uuid = helpers.fetch_by_key("run_uuid", jsonData) + flow_run_uuid = helpers.fetch_by_key( + "run_uuid", jsonData + ) # TODO: need to remove this once every flow has flow_run_details variable in webhook + if "flow_run_details" in jsonData: + flow_run_uuid = helpers.fetch_by_key( + "uuid", jsonData["flow_run_details"] + ) if flow_run_uuid: call_log = models.CallLog.query.get_by_flow_run_uuid(flow_run_uuid) if call_log: diff --git a/api/services/user_group_service.py b/api/services/user_group_service.py new file mode 100644 index 00000000..db814de5 --- /dev/null +++ b/api/services/user_group_service.py @@ -0,0 +1,41 @@ +from api import models, db, helpers + + +class UserGroupService(object): + def __init__(self): + self.user_phone = None + self.user_data = None + self.registration_data = None + + def handle(self, jsonData): + user_phone = helpers.fetch_by_key("urn", jsonData["contact"]) + self.user_phone = helpers.sanitize_phone_string(user_phone) + contact_groups = jsonData["contact"]["groups"] + self.user_data = helpers.get_user_by_phone(self.user_phone) + self.registration_data = helpers.get_registrant_by_phone(self.user_phone) + + for group in contact_groups: + group_data = models.UserGroup.query.get_unique( + group["uuid"], self.user_phone + ) + if group_data: + self.udpate(group_data) + else: + self.add(group) + + def add(self, group): + user_group_data = models.UserGroup( + user_id=self.user_data.id if self.user_data else None, + registration_id=self.registration_data.id + if self.registration_data + else None, + user_phone=self.user_phone, + group_name=group["name"], + group_uuid=group["uuid"], + status="active", + ) + helpers.save(user_group_data) + + def udpate(self, data): + data.status = "active" + db.session.commit() diff --git a/main.py b/main.py index ec6ea6dd..8d99e74a 100644 --- a/main.py +++ b/main.py @@ -6,7 +6,7 @@ def webhook(request): if request.method == "POST": try: jsonData = request.get_json() - if "contact" in jsonData and "run_uuid" in jsonData: + if "contact" in jsonData: # Conditions based on the flow categories if "flow_category" in jsonData: handle_flow_category_data(jsonData) @@ -30,8 +30,16 @@ def webhook(request): calllog_service.update_user_module_content_id_in_call_log( user_module_content_id ) + + # Handle contact groups + if ( + "groups" in jsonData["contact"] + and jsonData["contact"]["groups"] is not None + ): + user_group_service = services.UserGroupService() + user_group_service.handle(jsonData) else: - return jsonify(message="Contact or Flow Run UUID is missing"), 400 + return jsonify(message="Contact"), 400 except IndexError: return jsonify(message="Something went wrong!"), 400 return jsonify(message="Success"), 200