linhaohong 1 سال پیش
والد
کامیت
007fa617c7
5فایلهای تغییر یافته به همراه211 افزوده شده و 109 حذف شده
  1. 2 1
      Ansjer/urls.py
  2. 13 2
      Controller/UserController.py
  3. 135 21
      Controller/UserDevice/UserSubscriptionController.py
  4. 6 2
      Object/ResponseObject.py
  5. 55 83
      Object/YotpoCoreObject.py

+ 2 - 1
Ansjer/urls.py

@@ -30,7 +30,7 @@ from Controller.Cron import CronTaskController
 from Controller.MessagePush import EquipmentMessagePush
 from Controller.SensorGateway import SensorGatewayController, EquipmentFamilyController
 from Controller.Surveys import CloudStorageController
-from Controller.UserDevice import UserDeviceShareController
+from Controller.UserDevice import UserDeviceShareController, UserSubscriptionController
 from Controller.CampaignController import AppCampaignController
 from Model import views  # 定时任务,不要删除该行代码
 
@@ -273,6 +273,7 @@ urlpatterns = [
     re_path(r'^alexaApi/', include("Ansjer.server_urls.alexa_url")),
     re_path('appCampaign/(?P<operation>.*)', AppCampaignController.AppCampaignView.as_view()),
     re_path('wsParam/(?P<operation>.*)', SmartReplyController.WsParamService.as_view()),
+    re_path('yotpo/(?P<operation>.*)', UserSubscriptionController.UserSubscriptionControllerView.as_view()),
 
     # 后台界面接口 -------------------------------------------------------------------------------------------------------
     # 登录,用户信息,权限

+ 13 - 2
Controller/UserController.py

@@ -2,6 +2,7 @@ import base64
 import datetime
 import logging
 import random
+import threading
 import time
 import traceback
 from io import BytesIO
@@ -28,6 +29,7 @@ from Ansjer.config import AuthCode_Expire, SERVER_DOMAIN, TUTK_PUSH_DOMAIN, \
     LOGGER, CONFIG_US
 from Ansjer.config import BASE_DIR, CONFIG_EUR, CONFIG_INFO, SERVER_DOMAIN_EUR, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
 from Controller.CheckUserData import DataValid, date_handler, RandomStr
+from Controller.UserDevice.UserSubscriptionController import UserSubscriptionControllerView
 from Model.models import Device_User, Role, UidPushModel, UserOauth2Model, UserExModel, Device_Info, UidSetModel, \
     UserAppFrequencyModel, CountryIPModel, CountryModel, UidChannelSetModel, Order_Model, UID_Bucket, Unused_Uid_Meal, \
     GatewayPush, CountryLanguageModel, LanguageModel, IcloudUseDetails, IcloudStorageRecord, VodBucketModel, LogModel
@@ -1278,6 +1280,7 @@ class v3registerView(TemplateView):
         number = request_dict.get('number', None)
         salt = request_dict.get('salt', None)
         region_status = request_dict.get('region_status', None)
+        email_scription = request_dict.get('email_scription', None)
 
         if unique:
             delete_local_account(unique)
@@ -1331,7 +1334,7 @@ class v3registerView(TemplateView):
                                               password_version, salt)
             elif email is not None:
                 return self.do_email_register(email, password, authcode, number, region_status, response,
-                                              password_version, salt)
+                                              password_version, salt, email_scription)
             else:
                 return response.json(444, 'phone or email')
 
@@ -1413,7 +1416,7 @@ class v3registerView(TemplateView):
         res['phone'] = user_list[0]["phone"] if user_list[0]["phone"] is not None else ''
         return response.json(0, res)
 
-    def do_email_register(self, email, password, authcode, number, region_status, response, password_version, salt):
+    def do_email_register(self, email, password, authcode, number, region_status, response, password_version, salt, email_scription):
         data_valid = DataValid()
         if data_valid.email_validate(email) is not True:
             return response.json(105)
@@ -1454,6 +1457,14 @@ class v3registerView(TemplateView):
             if number:
                 create_data["region_country"] = number
             Device_User.objects.create(**create_data)
+            if email_scription:
+                subscribers = {
+                    "NickName": email,
+                    "region_country": number
+                }
+                subscription_thread = threading.Thread(target=UserSubscriptionControllerView.subscription,
+                                                       args=(subscribers,))
+                subscription_thread.start()
 
         except Exception as e:
             errorInfo = traceback.format_exc()

+ 135 - 21
Controller/UserDevice/UserSubscriptionController.py

@@ -6,11 +6,15 @@
 @Email   : zhangdongming@asj6.wecom.work
 @Software: PyCharm
 """
+import threading
+import time
+
 from django.http import QueryDict
 from django.views import View
 
-from Model.models import Device_User
+from Model.models import Device_User, CountryModel, UserEmailSubscriptions
 from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
 from Object.YotpoCoreObject import YotpoCoreObject
 from Ansjer.config import LOGGER
 
@@ -42,31 +46,141 @@ class UserSubscriptionControllerView(View):
 
     def validation(self, request_dict, request, operation):
         response = ResponseObject('cn')
-        if operation == 'subscription':
-            return self.subscription(request_dict, response)
+        tko = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
+        if tko.code != 0:
+            return response.json(tko.code)
+        response.lang = tko.lang
+        userID = tko.userID
+        if operation == 'checkSubscriptionStatus':
+            return self.check_subscription_status(userID, response)
+        elif operation == 'switchSubscription':
+            return self.switch_subscription(userID, request_dict, response)
+        else:
+            return response.json(414)
 
     @staticmethod
-    def subscription(request_dict, response):
-        user_id = request_dict.get('userId', '')
-        if not user_id:
-            return response.json(444)
-        user_qs = Device_User.objects.filter(userID=user_id).values('username', 'userEmail')
+    def check_subscription_status(user_id, response):
+        """
+        检查订阅状态
+        @param user_id: str
+        @param response: 响应
+        @return: response
+        """
+        user_qs = Device_User.objects.filter(userID=user_id)
+        if not user_qs.exists():
+            return response.json(104)
+        user_sub = UserEmailSubscriptions.objects.filter(user_id=user_id).values('status').first()
+        if not user_sub:
+            return response.json(0, {"status": 0})
+        user_sub = {"status": user_sub['status']}
+        return response.json(0, user_sub)
+
+    def switch_subscription(self, user_id, request_dict, response):
+        """
+        订阅开关
+        @param user_id: str
+        @param request_dict: dict
+        @param response
+        """
+        user_qs = Device_User.objects.filter(userID=user_id)
+        status = request_dict.get('status', None)
+        if not status:
+            return response.json(444, "status")
         if not user_qs.exists():
-            return response.json(703)
+            return response.json(104)
+
+        # 修改数据库中订阅状态
+        status = int(status)
+        user_sub_qs = UserEmailSubscriptions.objects.filter(user_id=user_id)
+        # 订阅
+        if status == 1:
+            subscribers = Device_User.objects.filter(userID=user_id).values('NickName', 'userEmail',
+                                                                            'region_country').first()
+            if not subscribers["userEmail"]:
+                LOGGER.info(f'subscribers{user_id}邮箱为空,无法订阅')
+                return response.json(183)
+            if user_sub_qs.exists():
+                user_sub_qs.update(status=1, updated_time=int(time.time()))
+            else:
+                UserEmailSubscriptions.objects.create(user_id=user_id, status=1, email=subscribers["userEmail"],
+                                                      created_time=int(time.time()), updated_time=int(time.time()))
+            subscription_thread = threading.Thread(target=self.subscription, args=(subscribers,))
+            subscription_thread.start()
+        # 取消订阅
+        else:
+            device_user = Device_User.objects.filter(userID=user_id).values('userEmail').first()
+            if device_user:
+                customer = {
+                    "email": device_user["userEmail"],
+                    "first_name": device_user["userEmail"],
+                    "last_name": "APP",
+                }
+            else:
+                return response.json(0, {"status": status})
+            yotpo = YotpoCoreObject()
+            list_id = 8589406
+            subscription_thread = threading.Thread(target=yotpo.close_subscribers, args=(customer, list_id))
+            subscription_thread.start()
+            if user_sub_qs.exists():
+                customer["status"] = "unsubscription"
+                user_sub_qs.update(status=0, sub_result=customer)
+        return response.json(0, {"status": status})
+
+    @staticmethod
+    def subscription(subscribers):
+        """
+        订阅
+        @param subscribers: dict
+        @return: boolean
+        """
 
         yotpo = YotpoCoreObject()
 
-        email = '1920098158@qq.com'
-        customer = {
-            "email": email, "first_name": "test", "last_name": "22",
-            'address': {
-                "country_code": 'GB',
-            }
-        }
+        try:
+            # 查询顾客所在地区
+            if subscribers["region_country"]:
+                country = CountryModel.objects.filter(id=subscribers["region_country"]).values('country_code').first()
+                if country:
+                    country_code = country["country_code"]
+                else:
+                    country_code = ''
+                # 构建顾客订阅格式
+                customer = {
+                    "email": subscribers["userEmail"],
+                    "first_name": subscribers["userEmail"],
+                    "last_name": "APP",
+                    'address': {
+                        "country_code": country_code,
+                    },
+                    "custom_properties": {
+                        "subscription_office": "ZosiApp",
+                    }
+                }
+            else:
+                customer = {
+                    "email": subscribers["userEmail"],
+                    "first_name": subscribers["userEmail"],
+                    "last_name": "APP",
+                    "custom_properties": {
+                        "subscription_office": "ZosiApp",
+                    }
+                }
 
-        result = yotpo.creat_and_update_customers(customer)
+            result = yotpo.creat_and_update_customers(customer)
+            list_id = 8589406
+            sub_status, sub_result = yotpo.create_subscribers(customer, list_id)
 
-        list_id = 8589406
-        subscribers_result = yotpo.create_subscribers(customer, list_id)
-        print()
-        LOGGER.info(f'创建客户:{result},订阅:{subscribers_result}')
+            if result and sub_status:
+                # 创建结果写入数据库
+                user_sub_qs = UserEmailSubscriptions.objects.filter(email=subscribers["userEmail"])
+                if user_sub_qs.exists():
+                    user_sub_qs.update(email=subscribers["userEmail"], status=1, sub_result=sub_result, list_id=list_id,
+                                       updated_time=int(time.time()))
+                    LOGGER.info(f'在yotpo创建客户并订阅成功,customer:{customer}')
+                return True
+            else:
+                LOGGER.info(f'在yotpo创建客户并订阅失败,customer:{customer}')
+            return False
+        except Exception as e:
+            LOGGER.error(f'{subscribers["userEmail"]}订阅失败:{e}')
+            return False

+ 6 - 2
Object/ResponseObject.py

@@ -53,6 +53,7 @@ class ResponseObject(object):
             180: 'Smart button scene trigger conditions cannot be repeated',
             181: 'The gateway only bind 3 smart button at most',
             182: 'Scene effective time conflict',
+            183: 'This user is not bound to an e-mail address',
             201: 'You can only add 3 custom voice at most',
             306: 'The link has expired!',
             309: 'Please ReLogin! errmsg token',
@@ -150,7 +151,8 @@ class ResponseObject(object):
             10071: 'The successful collection can be viewed in Settings - 4G-My package',
             10072: 'This function has been disabled. Please contact the administrator',
             10073: 'The verification code has been sent, please pay attention to check',
-            10074: 'Task queue processing, please try again later'
+            10074: 'Task queue processing, please try again later',
+            10075: 'Email subscription failed'
         }
         data_cn = {
             0: '成功',
@@ -194,6 +196,7 @@ class ResponseObject(object):
             180: '智能按钮场景触发条件不能重复',
             181: '该网关最多只能绑定3个智能按钮',
             182: '场景生效时间冲突',
+            183: '该用户未绑定邮箱',
             201: '最多只能添加3条自定义语音',
             306: '链接已超过有效期!',
             309: '请重新登录!',
@@ -287,7 +290,8 @@ class ResponseObject(object):
             10071: '\t领取成功\n可在设置-4G-我的套餐中查看',
             10072: '该功能已停用,请联系管理员',
             10073: '验证码已发送,请注意查收',
-            10074: '任务队列处理中,请稍后再试'
+            10074: '任务队列处理中,请稍后再试',
+            10075: '邮件订阅失败'
         }
 
         msg = data_cn if self.lang == 'cn' or self.lang == 'zh-Hans' or self.lang == 'zh-Hant' else data_en

+ 55 - 83
Object/YotpoCoreObject.py

@@ -16,8 +16,8 @@
 """
 import datetime
 import json
-
 import requests
+from Ansjer.config import LOGGER
 
 STORE_ID = "LIKwYlx6uonKqN91fXiGFb4FHqVLpvMUdGNU5Zf9"
 YOTPO_URL = f"https://api.yotpo.com/core/v3/stores/{STORE_ID}/"
@@ -27,46 +27,58 @@ secret = 'isb8EOQs8bkjrksLHN73o3HIkrhoW539IXhULfdh'
 class YotpoCoreObject:
 
     def get_token(self):
-        url = YOTPO_URL + "access_tokens"
+        try:
+            url = YOTPO_URL + "access_tokens"
 
-        payload = {'secret': secret}
-        headers = {
-            "accept": "application/json",
-            "Content-Type": "application/json"
-        }
-
-        response = requests.post(url, json=payload, headers=headers)
-        assert response.status_code == 200
+            payload = {'secret': secret}
+            headers = {
+                "accept": "application/json",
+                "Content-Type": "application/json"
+            }
 
-        token = json.loads(response.text).get("access_token")
-        print("token:", token)
-        return token
+            response = requests.post(url, json=payload, headers=headers)
+            if response.status_code != 200:
+                LOGGER.info(f'yotpo获取token失败, response.status_code请求不为200')
+                return ""
+            token = json.loads(response.text).get("access_token")
+            return token
+        except Exception as e:
+            LOGGER.info(f'yotpo获取token失败, {e}')
+            return ""
 
     def creat_and_update_customers(self, customers):
         """
         创建和更新用户
         """
-        url = YOTPO_URL + "customers"
-        yotpo_token = self.get_token()
-        headers = {
-            "accept": "application/json",
-            "X-Yotpo-Token": yotpo_token,
-            "Content-Type": "application/json"
-        }
-
-        payload = {
-            "customer": customers
-        }
-
-        response = requests.patch(url, json=payload, headers=headers)
-        assert response.status_code == 200
-        return response.text
+        try:
+            url = YOTPO_URL + "customers"
+            yotpo_token = self.get_token()
+            if yotpo_token == "":
+                LOGGER.info(f'yotpo创建顾客失败, yotpo_token为空 ,customers:{customers}')
+                return False
+            headers = {
+                "accept": "application/json",
+                "X-Yotpo-Token": yotpo_token,
+                "Content-Type": "application/json"
+            }
+            payload = {
+                "customer": customers
+            }
+            response = requests.patch(url, json=payload, headers=headers)
+            if response.status_code != 200:
+                LOGGER.info(f'yotpo创建顾客失败,response.status_code != 200,customers:{customers}')
+                return False
+            LOGGER.info(f'yotpo创建顾客成功,customers:{customers}')
+            return True
+        except Exception as e:
+            LOGGER.info(f'yotpo创建顾客失败, customers:{customers},{e}')
+            return False
 
     def get_customers_list(self, email):
         """
         查用户信息
         """
-        url = YOTPO_URL + f"customers?email={email}"
+        url = YOTPO_URL + f"customers?include_custom_properties=true&email={email}"
         yotpo_token = self.get_token()
         headers = {
             "accept": "application/json",
@@ -82,6 +94,8 @@ class YotpoCoreObject:
         创建订阅
         """
         url = f"https://api.yotpo.com/messaging/v3/stores/{STORE_ID}/subscribers"
+        if "custom_properties" in customer_params:
+            del customer_params["custom_properties"]
         payload = {
             "customer": customer_params,
             "channels": {
@@ -89,7 +103,6 @@ class YotpoCoreObject:
                     "marketing": {
                         "consent": "subscribed",
                         "list_id": list_id,
-                        "source": "post_purchase_popup"
                     },
                     "suppression": {
                         "suppress_email": True,
@@ -98,7 +111,6 @@ class YotpoCoreObject:
                     }
                 },
             },
-            "suppress_welcome_messages": True
         }
         headers = {
             "accept": "application/json",
@@ -106,41 +118,37 @@ class YotpoCoreObject:
             "X-Yotpo-Token": self.get_token()
         }
         response = requests.post(url, json=payload, headers=headers)
-        assert response.status_code == 200
-        return response.text
+        if response.status_code != 200:
+            LOGGER.info(f'yotpo创建订阅失败, customer_params:{customer_params}')
+            return False, ""
+        return True, response.text
 
-    def close_subscribers(self, email, list_id):
+    def close_subscribers(self, customer, list_id):
         """
         关闭订阅
         """
         url = f"https://api.yotpo.com/messaging/v3/stores/{STORE_ID}/subscribers"
-
         payload = {
-            "customer": {
-                "email": email,
-            },
-            # "channels": {
-            #     "email": {"marketing": {"consent": None}},
-            #     "suppress_welcome_messages": True
-            # },
+            "customer": customer,
             "channels": {
                 "email": {"marketing": {
                     "consent": "unsubscribed",
                     "list_id": list_id,
                     "source": "post_purchase_popup"
                 }}
-            },
-            "list_id": list_id
+            }
         }
         headers = {
             "accept": "application/json",
             "content-type": "application/json",
             "X-Yotpo-Token": self.get_token()
         }
-
         response = requests.post(url, json=payload, headers=headers)
-
-        print(response.text)
+        if response.status_code != 200:
+            LOGGER.info(f'yotpo关闭订阅失败, customer:{customer}')
+            return False
+        LOGGER.info(f'yotpo关闭订阅成功, customer:{customer}')
+        return True
 
     def get_all_list_ids(self):
         """
@@ -198,39 +206,3 @@ class YotpoCoreObject:
         #     }
         #     self.creat_and_update_customers(customer)
         print('success')
-
-
-if __name__ == "__main__":
-    pass
-    # YotpoCoreObject().check_api()
-    # 获取 token ok
-    # token = get_token()
-    # print(token)
-
-    # # # 创建用户 ok
-    # response = creat_and_update_customers()
-    # print(response)
-    #
-    # 检索用户 ok
-    # response = get_customers_list()
-    # print(response.text)
-
-    # 检索订阅 ok
-    # response = get_webhooks_subscriptions()
-    # print(response.text)
-
-    # 检索接口
-    # response = get_webhooks("webhooks/targets")
-    # print(response)
-
-    # 创建筛选器
-    # create_webhook_filters()
-    #
-    # 创建订阅
-    # create_subscribers()
-
-    # 关闭订阅
-    # YotpoCoreObject().close_subscribers('1920098158@qq.com', 8589406)
-
-    # 获取list
-    # get_all_list_ids()