-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Split dashamail app into two parts -- lists and directcrm * Notifying dashamail directcrm about new and orders * Subscribing users to the dedicted per-productgroup mailing lists
- Loading branch information
Showing
45 changed files
with
840 additions
and
605 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from apps.dashamail.directcrm.events.order_created import OrderCreated | ||
from apps.dashamail.directcrm.events.order_paid import OrderPaid | ||
|
||
__all__ = [ | ||
"OrderCreated", | ||
"OrderPaid", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
from abc import ABCMeta | ||
from abc import abstractmethod | ||
from abc import abstractproperty | ||
from decimal import Decimal | ||
|
||
import httpx | ||
|
||
from django.conf import settings | ||
|
||
from apps.dashamail import exceptions | ||
|
||
|
||
class Event(metaclass=ABCMeta): | ||
"""Dashamail DirectCRM backend event | ||
https://lk.dashamail.ru/?page=cdp&action=developer | ||
""" | ||
|
||
@abstractproperty | ||
def name(self) -> str: | ||
"""Event name""" | ||
|
||
@abstractmethod | ||
def to_json(self) -> dict[str, str | dict]: | ||
"""Actual event payload, 'data' field in the dashamail request""" | ||
|
||
@staticmethod | ||
def format_price(price: Decimal) -> str: | ||
return str(price).replace(".", ",") | ||
|
||
def send(self) -> None: | ||
response = httpx.post( | ||
url=f"https://directcrm.dashamail.com/v3/operations/sync?endpointId={settings.DASHAMAIL_DIRECTCRM_ENDPOINT}&operation={self.name}", | ||
json=self.to_json(), | ||
headers={ | ||
"Authorization": f"Dashamail secretKey={settings.DASHAMAIL_DIRECTCRM_SECRET_KEY}", | ||
}, | ||
) | ||
|
||
if response.status_code != 200: | ||
raise exceptions.DashamailDirectCRMHTTPException(f"Wrong HTTP response from dashamail directcrm: {response.status_code}") | ||
|
||
response_json = response.json() | ||
|
||
if response_json is None or response_json["status"] != "Success": | ||
raise exceptions.DashamailDirectCRMWrongResponse(f"Wrong response from dashamail directcrm: {response_json}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from apps.dashamail.directcrm.events.base import Event | ||
from apps.orders.models import Order | ||
|
||
|
||
class OrderCreated(Event): | ||
name = "OrderCreate" | ||
|
||
def __init__(self, order: Order): | ||
self.order = order | ||
|
||
def to_json(self) -> dict: | ||
return { | ||
"customer": { | ||
"email": self.order.user.email, | ||
}, | ||
"order": { | ||
"orderId": self.order.slug, | ||
"totalPrice": self.format_price(self.order.price), | ||
"status": "created", | ||
"lines": [ | ||
{ | ||
"productId": self.order.course.slug, | ||
"quantity": 1, | ||
"price": self.format_price(self.order.price), | ||
} | ||
], | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from apps.dashamail.directcrm.events.base import Event as DirectCRMEvent | ||
from apps.orders.models import Order | ||
|
||
|
||
class OrderPaid(DirectCRMEvent): | ||
name = "OrderPaid" | ||
|
||
def __init__(self, order: Order): | ||
self.order = order | ||
|
||
def to_json(self) -> dict: | ||
return { | ||
"customer": { | ||
"email": self.order.user.email, | ||
}, | ||
"order": { | ||
"orderId": self.order.slug, | ||
"totalPrice": self.format_price(self.order.price), | ||
"status": "finished", | ||
"lines": [ | ||
{ | ||
"productId": self.order.course.slug, | ||
"quantity": 1, | ||
"price": self.format_price(self.order.price), | ||
} | ||
], | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from apps.dashamail.lists.dto.list import DashamailList | ||
from apps.dashamail.lists.dto.subscriber import DashamailSubscriber | ||
|
||
__all__ = [ | ||
"DashamailList", | ||
"DashamailSubscriber", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from apps.dashamail.lists.http import DashamailListsHTTP | ||
|
||
|
||
class DashamailListsDTO: | ||
@property | ||
def api(self) -> DashamailListsHTTP: | ||
return DashamailListsHTTP() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from dataclasses import dataclass | ||
|
||
from apps.dashamail.lists.dto.base import DashamailListsDTO | ||
|
||
|
||
@dataclass | ||
class DashamailList(DashamailListsDTO): | ||
list_id: int | None = None | ||
name: str | None = None | ||
|
||
def create(self) -> int: | ||
if self.name is None: | ||
raise RuntimeError("List name must be given") | ||
|
||
response = self.api.call("lists.add", {"name": self.name}) | ||
|
||
return response["response"]["data"]["list_id"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
from dataclasses import dataclass | ||
from typing import TYPE_CHECKING | ||
|
||
from django.conf import settings | ||
|
||
from apps.dashamail import exceptions | ||
from apps.dashamail.lists.dto.base import DashamailListsDTO | ||
from apps.dashamail.lists.dto.list import DashamailList | ||
|
||
if TYPE_CHECKING: | ||
from apps.users.models import User | ||
|
||
|
||
@dataclass | ||
class DashamailSubscriber(DashamailListsDTO): | ||
user: "User" | ||
|
||
def subscribe(self, to: DashamailList | None = None) -> None: | ||
mail_list = to if to is not None else self.get_default_list() | ||
|
||
if self.get_member_id(mail_list) is None: | ||
self._subscribe(to=mail_list) | ||
else: | ||
self._update(mail_list) | ||
|
||
def _subscribe(self, to: DashamailList) -> None: | ||
response = self.api.call( | ||
"lists.add_member", | ||
{ | ||
"list_id": str(to.list_id), | ||
"email": self.format_email(self.user.email), | ||
"merge_1": self.user.first_name, | ||
"merge_2": self.user.last_name, | ||
"merge_3": ";".join(self.user.tags), | ||
}, | ||
) | ||
|
||
if response["response"]["msg"]["err_code"] != 0: | ||
raise exceptions.DashamailSubscriptionFailed(f"{response}") | ||
|
||
def _update(self, mail_list: DashamailList) -> None: | ||
"""Replace old user's fields with new""" | ||
|
||
response = self.api.call( | ||
"lists.update_member", | ||
{ | ||
"list_id": str(mail_list.list_id), | ||
"merge_1": self.user.first_name, | ||
"merge_2": self.user.last_name, | ||
"member_id": str(self.get_member_id(mail_list)), | ||
"merge_3": ";".join(self.user.tags), | ||
}, | ||
) | ||
|
||
if response["response"]["msg"]["err_code"] != 0: | ||
raise exceptions.DashamailUpdateFailed(f"{response}") | ||
|
||
def get_member_id(self, mail_list: DashamailList) -> int | None: | ||
"""Return tuple which consists of member_id and is_active""" | ||
response = self.api.call( | ||
"lists.get_members", | ||
{ | ||
"list_id": str(mail_list.list_id), | ||
"email": self.format_email(self.user.email), | ||
}, | ||
) | ||
|
||
if response["response"]["msg"]["err_code"] != 0: | ||
return None | ||
|
||
return int(response["response"]["data"][0]["id"]) | ||
|
||
@staticmethod | ||
def get_default_list() -> DashamailList: | ||
return DashamailList(list_id=settings.DASHAMAIL_LIST_ID) | ||
|
||
@staticmethod | ||
def format_email(email: str) -> str: | ||
if email.endswith("@ya.ru"): | ||
# Dashamail internally converts ya.ru to yandex.ru, with ya.ru we're going to get nothing | ||
return email.replace("@ya.ru", "@yandex.ru") | ||
|
||
return email |
Oops, something went wrong.