leadguru-jobs 0.561.0__py3-none-any.whl → 0.562.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {leadguru_jobs-0.561.0.dist-info → leadguru_jobs-0.562.0.dist-info}/METADATA +1 -1
- {leadguru_jobs-0.561.0.dist-info → leadguru_jobs-0.562.0.dist-info}/RECORD +12 -11
- lgt_jobs/__init__.py +4 -0
- lgt_jobs/jobs/chat_history.py +2 -3
- lgt_jobs/jobs/connect_sources.py +90 -0
- lgt_jobs/jobs/send_slack_message.py +2 -4
- lgt_jobs/lgt_common/slack_client/web_client.py +16 -51
- lgt_jobs/lgt_data/enums.py +1 -0
- lgt_jobs/lgt_data/model.py +23 -4
- lgt_jobs/lgt_data/mongo_repository.py +14 -1
- {leadguru_jobs-0.561.0.dist-info → leadguru_jobs-0.562.0.dist-info}/WHEEL +0 -0
- {leadguru_jobs-0.561.0.dist-info → leadguru_jobs-0.562.0.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
lgt_jobs/__init__.py,sha256=
|
1
|
+
lgt_jobs/__init__.py,sha256=kmM5J3qBJd-fOZa2I4gkh36IytrgN6_18gWwwpR3n6Y,2156
|
2
2
|
lgt_jobs/basejobs.py,sha256=LPEclvY6fIG17YMGy9pRK0Q58n62gkI5W1BTK6R2p-c,1234
|
3
3
|
lgt_jobs/env.py,sha256=cRO03GGvstUjBsv3uYO-iakrOvAk_ZWUP_fnmf21iZQ,789
|
4
4
|
lgt_jobs/main.py,sha256=cK_nkBtJHnUNDbba1WZotqPtI_6OWxiYQkAgco9OAmE,1539
|
@@ -13,11 +13,12 @@ lgt_jobs/assets/images/mail.png,sha256=eORzQcAMkFr7DjgtABVhJ_zFuXgO7OXv78lLF4b39
|
|
13
13
|
lgt_jobs/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
14
|
lgt_jobs/jobs/analytics.py,sha256=IIsWt4A1qUw3w-S-8W16uKY1FRVWfXXA41_mu4uCNiM,979
|
15
15
|
lgt_jobs/jobs/bot_stats_update.py,sha256=R6mf5FxhWbyx92AYXlj0FZVjz2Tgz86mBvLHrsQ9AFE,7502
|
16
|
-
lgt_jobs/jobs/chat_history.py,sha256=
|
16
|
+
lgt_jobs/jobs/chat_history.py,sha256=tZ4XyOGdy1k6r4uotxSSKbXjTR_oRK6Ym0YthFYBtl8,6200
|
17
|
+
lgt_jobs/jobs/connect_sources.py,sha256=uVO_kH-Hxn7HkYUNGNcS7Mu3jB7KlB4pU5qcdtR2hrM,4260
|
17
18
|
lgt_jobs/jobs/inbox_leads.py,sha256=EYxdQPseNBY5ON7BK3LpnXDCgQpzHTPLRJCZmZiAAHA,5582
|
18
19
|
lgt_jobs/jobs/mass_message.py,sha256=1mFcBlL2MhzLbj5yrd_NyJc7TXDWCcROAzGDnr0miMU,2035
|
19
20
|
lgt_jobs/jobs/send_code.py,sha256=dIlLPkG3GgGKIEqGiElyzrtdrnJNTL1Ak2V0xnE-WIQ,824
|
20
|
-
lgt_jobs/jobs/send_slack_message.py,sha256=
|
21
|
+
lgt_jobs/jobs/send_slack_message.py,sha256=IuRqDGcDrz2EAZzF6nrLXO0aSA4mETB_tGOEbcMhjHE,2562
|
21
22
|
lgt_jobs/jobs/update_slack_profile.py,sha256=0fUHBd2gEBne52sTfxwji2Wu-oYDM5dLGsL-rHq5kwM,2765
|
22
23
|
lgt_jobs/jobs/user_balance_update.py,sha256=HxeEmDdloK9EcoEj1ybYTgxIkB0IQNLnss_kk3rLI1Q,2404
|
23
24
|
lgt_jobs/jobs/workspace_connect.py,sha256=qgjIRzAQRbJBx--eYsTtYgOUh2-p3N_-LIltfbJrYYo,7102
|
@@ -35,18 +36,18 @@ lgt_jobs/lgt_common/pubsub/pubsubfactory.py,sha256=rfUDooYuhBQ2pE9FdDxZOpXjbrvlp
|
|
35
36
|
lgt_jobs/lgt_common/slack_client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
37
|
lgt_jobs/lgt_common/slack_client/methods.py,sha256=ctKF_1UHEmSWaRsoGEgMZicVabV7eEufZ7pjxdMAx8g,1455
|
37
38
|
lgt_jobs/lgt_common/slack_client/slack_client.py,sha256=icHapSOszFYnSofJ-eWl4lUWSOqng6S9XSRFfMx87Rg,13836
|
38
|
-
lgt_jobs/lgt_common/slack_client/web_client.py,sha256=
|
39
|
+
lgt_jobs/lgt_common/slack_client/web_client.py,sha256=JrkEepL6EhEtX3Psv_sd25bcRB2P23LoGnFHcczQpnc,4778
|
39
40
|
lgt_jobs/lgt_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
40
41
|
lgt_jobs/lgt_data/analytics.py,sha256=TFUffL8Dn-vIJ3ZaCVN-cj1Qnjb8F9GJyuk6Fo7mR1s,21645
|
41
42
|
lgt_jobs/lgt_data/engine.py,sha256=Rsbz-CApAo_TVDssdjBkv8v_fVOZm_Uh1S6W4fnaEWo,7728
|
42
|
-
lgt_jobs/lgt_data/enums.py,sha256=
|
43
|
+
lgt_jobs/lgt_data/enums.py,sha256=jBH5WGBtDAvFrh4iiPIzlQ-XrImMpuwqstuasG55mJ0,2209
|
43
44
|
lgt_jobs/lgt_data/helpers.py,sha256=NDa-V5EYaJfkGoWsmQSwSe6N_jxNxs8tHRQzW1iST6k,480
|
44
|
-
lgt_jobs/lgt_data/model.py,sha256=
|
45
|
-
lgt_jobs/lgt_data/mongo_repository.py,sha256=
|
45
|
+
lgt_jobs/lgt_data/model.py,sha256=BtVpJC_TRXUOklpzwRiDywyuKCCV2GGXtjsRYcPibDc,28454
|
46
|
+
lgt_jobs/lgt_data/mongo_repository.py,sha256=wdhslZTfTU-3Ad4Gm8NVl9HZFM5aK_vgG47EqNQBARk,45179
|
46
47
|
lgt_jobs/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
47
48
|
lgt_jobs/services/web_client.py,sha256=GLWsJkIC8rv6xLFaLwcMm4EwBlVDu0njORwkZqBJaE4,2086
|
48
49
|
lgt_jobs/templates/new_message.html,sha256=BD_E90akmQ1Wf07wtZAjeK_7DUKRmja5HFHVo_AKI24,6994
|
49
|
-
leadguru_jobs-0.
|
50
|
-
leadguru_jobs-0.
|
51
|
-
leadguru_jobs-0.
|
52
|
-
leadguru_jobs-0.
|
50
|
+
leadguru_jobs-0.562.0.dist-info/METADATA,sha256=KoLJrkMpvPsywYTmEQy6vwxcHtLNXubHITY0VZbN4xY,1319
|
51
|
+
leadguru_jobs-0.562.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
52
|
+
leadguru_jobs-0.562.0.dist-info/top_level.txt,sha256=rIuw1DqwbnZyeoarBSC-bYeGOhv9mZBs7_afl9q4_JI,9
|
53
|
+
leadguru_jobs-0.562.0.dist-info/RECORD,,
|
lgt_jobs/__init__.py
CHANGED
@@ -3,6 +3,7 @@ name = "lgt_jobs"
|
|
3
3
|
from .jobs.user_balance_update import UpdateUserBalanceJob, UpdateUserBalanceJobData
|
4
4
|
from .jobs.send_slack_message import SendSlackMessageJob, SendSlackMessageJobData
|
5
5
|
from .jobs.analytics import (TrackAnalyticsJob, TrackAnalyticsJobData)
|
6
|
+
from .jobs.connect_sources import (ConnectSourceJobData, ConnectSourceJob)
|
6
7
|
from .jobs.bot_stats_update import (BotStatsUpdateJob, BotStatsUpdateJobData)
|
7
8
|
from .jobs.chat_history import (LoadChatHistoryJob, LoadChatHistoryJobData)
|
8
9
|
from .jobs.update_slack_profile import (UpdateExternalUserProfileJob, UpdateExternalUserProfileJobData)
|
@@ -22,6 +23,7 @@ jobs_map = {
|
|
22
23
|
"SendSlackMessageJob": SendSlackMessageJob,
|
23
24
|
"UpdateUserBalanceJob": UpdateUserBalanceJob,
|
24
25
|
"SendMassMessageSlackChannelJob": SendMassMessageSlackChannelJob,
|
26
|
+
"ConnectSourceJob": ConnectSourceJob
|
25
27
|
}
|
26
28
|
__all__ = [
|
27
29
|
# Jobs
|
@@ -35,6 +37,7 @@ __all__ = [
|
|
35
37
|
SendSlackMessageJob,
|
36
38
|
UpdateUserBalanceJob,
|
37
39
|
SendMassMessageSlackChannelJob,
|
40
|
+
ConnectSourceJob,
|
38
41
|
|
39
42
|
# module classes
|
40
43
|
BackgroundJobRunner,
|
@@ -50,6 +53,7 @@ __all__ = [
|
|
50
53
|
SendSlackMessageJobData,
|
51
54
|
UpdateUserBalanceJobData,
|
52
55
|
SendMassMessageSlackChannelJobData,
|
56
|
+
ConnectSourceJobData,
|
53
57
|
# mapping
|
54
58
|
jobs_map
|
55
59
|
]
|
lgt_jobs/jobs/chat_history.py
CHANGED
@@ -100,9 +100,8 @@ class LoadChatHistoryJob(BaseBackgroundJob, ABC):
|
|
100
100
|
if not messages:
|
101
101
|
return None
|
102
102
|
|
103
|
-
messages = [SlackMessageConvertService.from_slack_response(
|
104
|
-
bot.
|
105
|
-
user.id, bot.cookies) for m in messages]
|
103
|
+
messages = [SlackMessageConvertService.from_slack_response(bot.user_name, m, contact.sender_id,
|
104
|
+
bot.id, user.id) for m in messages]
|
106
105
|
new_messages = self._get_new_messages(contact, bot, messages)
|
107
106
|
chat_history = [message.to_dic() for message in new_messages]
|
108
107
|
self.chat_repo.upsert_messages(chat_history)
|
@@ -0,0 +1,90 @@
|
|
1
|
+
from abc import ABC
|
2
|
+
from typing import List
|
3
|
+
import logging as log
|
4
|
+
from lgt_jobs.basejobs import BaseBackgroundJob, BaseBackgroundJobData
|
5
|
+
from lgt_jobs.jobs.bot_stats_update import BotStatsUpdateJob, BotStatsUpdateJobData
|
6
|
+
from lgt_jobs.runner import BackgroundJobRunner
|
7
|
+
from lgt_jobs.lgt_data.engine import UserTrackAction
|
8
|
+
from lgt_jobs.lgt_data.enums import SourceType, UserAction, StatusConnection
|
9
|
+
from lgt_jobs.lgt_data.model import BaseModel, DedicatedBotModel, Server, Source, SlackUser
|
10
|
+
from lgt_jobs.lgt_data.mongo_repository import DedicatedBotRepository, UserMongoRepository
|
11
|
+
|
12
|
+
|
13
|
+
class ConnectSourceJobData(BaseBackgroundJobData, BaseModel):
|
14
|
+
slack_email: str
|
15
|
+
sources_ids: List[str]
|
16
|
+
action_user_email: str
|
17
|
+
user_email: str
|
18
|
+
|
19
|
+
|
20
|
+
class ConnectSourceJob(BaseBackgroundJob, ABC):
|
21
|
+
@property
|
22
|
+
def job_data_type(self) -> type:
|
23
|
+
return ConnectSourceJobData
|
24
|
+
|
25
|
+
def exec(self, data: ConnectSourceJobData):
|
26
|
+
users_repository = UserMongoRepository()
|
27
|
+
bots_repository = DedicatedBotRepository()
|
28
|
+
action_user = users_repository.get_by_email(data.action_user_email)
|
29
|
+
user = users_repository.get_by_email(data.user_email)
|
30
|
+
if not action_user:
|
31
|
+
log.info(f'[ConnectSourceJobData]: Unable to find user with email: {data.action_user_email}')
|
32
|
+
return
|
33
|
+
|
34
|
+
slack_user: SlackUser = action_user.get_slack_user(data.slack_email)
|
35
|
+
if not slack_user:
|
36
|
+
log.info(f"[ConnectSourceJobData]: You have no credentials for {data.slack_email}. Try to login to Slack.")
|
37
|
+
slack_user.status = StatusConnection.COMPLETE
|
38
|
+
users_repository.set(action_user.id, slack_users=[user.to_dic() for user in action_user.slack_users])
|
39
|
+
return
|
40
|
+
bots = []
|
41
|
+
for ws in slack_user.workspaces:
|
42
|
+
try:
|
43
|
+
if ws.id in data.sources_ids:
|
44
|
+
active_bot = bots_repository.get_one(user_id=action_user.id, active_server_id=ws.id)
|
45
|
+
bot = bots_repository.get_one(user_id=action_user.id, server_id=ws.id, include_deleted=True,
|
46
|
+
user_name=data.slack_email)
|
47
|
+
if active_bot:
|
48
|
+
continue
|
49
|
+
if not bot:
|
50
|
+
bot = DedicatedBotModel()
|
51
|
+
bot.servers = [Server()]
|
52
|
+
|
53
|
+
bot.user_name = slack_user.email
|
54
|
+
bot.slack_url = ws.url
|
55
|
+
bot.user_id = action_user.id
|
56
|
+
bot.created_by = user.email
|
57
|
+
bot.registration_link = ws.url
|
58
|
+
bot.token = ws.token
|
59
|
+
bot.cookies = slack_user.cookies
|
60
|
+
bot.deleted = False
|
61
|
+
bot.paused = False
|
62
|
+
bot.invalid_creds = False
|
63
|
+
bot.banned = False
|
64
|
+
bot.two_factor_required = ws.two_factor_required
|
65
|
+
source = Source()
|
66
|
+
|
67
|
+
for server in bot.servers:
|
68
|
+
server.id = ws.id
|
69
|
+
server.name = ws.domain
|
70
|
+
server.deleted = False
|
71
|
+
server.active = True
|
72
|
+
server.icon = ws.icon
|
73
|
+
|
74
|
+
source.source_id = ws.id
|
75
|
+
source.source_name = ws.domain
|
76
|
+
bot.type = source.source_type = SourceType.SLACK
|
77
|
+
bot.icon = ws.icon
|
78
|
+
bot.source = source
|
79
|
+
bots_repository.add_or_update(bot)
|
80
|
+
UserTrackAction.track(action_user.id, UserAction.START_SOURCE, ws.id)
|
81
|
+
bot = bots_repository.get_one(user_id=action_user.id, server_id=ws.id, user_name=slack_user.email)
|
82
|
+
bots.append(bot)
|
83
|
+
BackgroundJobRunner.submit(BotStatsUpdateJob, BotStatsUpdateJobData(bot_id=str(bot.id)))
|
84
|
+
except Exception:
|
85
|
+
import traceback
|
86
|
+
log.exception(f"[ConnectSourceJobData]: Error to connect {ws.id}")
|
87
|
+
traceback.print_exc()
|
88
|
+
slack_user.status = StatusConnection.COMPLETE
|
89
|
+
users_repository.set(action_user.id, slack_users=[user.to_dic() for user in action_user.slack_users])
|
90
|
+
return bots
|
@@ -54,9 +54,7 @@ class SendSlackMessageJob(BaseBackgroundJob, ABC):
|
|
54
54
|
message = resp.get('message') if 'message' in resp \
|
55
55
|
else slack_client.conversation_replies(channel_id, resp['file_msg_ts'])['messages'][0]
|
56
56
|
|
57
|
-
message_model: ChatMessage = SlackMessageConvertService.from_slack_response(
|
58
|
-
|
59
|
-
bot.id, user.id,
|
60
|
-
slack_client.client.cookies)
|
57
|
+
message_model: ChatMessage = SlackMessageConvertService.from_slack_response(bot.user_name, message,
|
58
|
+
data.sender_id, bot.id, user.id)
|
61
59
|
message_model.viewed = True
|
62
60
|
ChatRepository().upsert_messages([message_model.to_dic()])
|
@@ -1,28 +1,13 @@
|
|
1
|
-
import requests
|
2
1
|
from google.cloud import storage
|
3
2
|
from datetime import datetime, timedelta
|
4
|
-
from lgt_jobs.lgt_data.model import ChatMessage
|
5
|
-
from .slack_client import SlackClient
|
6
|
-
from
|
7
|
-
|
8
|
-
|
9
|
-
def get_file_url(blob_path):
|
10
|
-
storage_client = storage.Client()
|
11
|
-
bucket = storage_client.get_bucket(SlackFilesClient.bucket_name)
|
12
|
-
blob = bucket.get_blob(blob_path)
|
13
|
-
if not blob:
|
14
|
-
return None
|
15
|
-
# valid for 3 days
|
16
|
-
return blob.generate_signed_url(timedelta(3))
|
3
|
+
from lgt_jobs.lgt_data.model import ChatMessage, LeadGuruFile
|
4
|
+
from lgt_jobs.lgt_common.slack_client.slack_client import SlackClient
|
5
|
+
from lgt_jobs.lgt_data.mongo_repository import to_object_id
|
17
6
|
|
18
7
|
|
19
8
|
class SlackMessageConvertService:
|
20
9
|
@staticmethod
|
21
|
-
def from_slack_response(
|
22
|
-
|
23
|
-
"""
|
24
|
-
:rtype: SlackHistoryMessageModel
|
25
|
-
"""
|
10
|
+
def from_slack_response(bot_name, dic, sender_id, bot_id, user_id) -> ChatMessage:
|
26
11
|
result = ChatMessage()
|
27
12
|
result.sender_id = sender_id
|
28
13
|
result.bot_id = bot_id
|
@@ -32,24 +17,15 @@ class SlackMessageConvertService:
|
|
32
17
|
result.attachments = dic.get('attachments', [])
|
33
18
|
result.files = []
|
34
19
|
result.user_id = to_object_id(user_id)
|
35
|
-
|
36
20
|
if 'files' in dic:
|
37
21
|
for file in dic.get('files'):
|
38
|
-
if file.get('mode'
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
new_file.size = file.get('size')
|
46
|
-
new_file.mimetype = file.get('mimetype')
|
47
|
-
|
48
|
-
url_private_download = file.get('url_private_download')
|
49
|
-
new_file.download_url = SlackFilesClient.get_file_url(user_email, bot_name, bot_token,
|
50
|
-
new_file.id, url_private_download,
|
51
|
-
new_file.mimetype, cookies)
|
52
|
-
result.files.append(new_file)
|
22
|
+
if file.get('mode') != "tombstone" and file.get('url_private_download'):
|
23
|
+
leadguru_file = LeadGuruFile()
|
24
|
+
leadguru_file.id = file['id']
|
25
|
+
leadguru_file.content_type = file['mimetype']
|
26
|
+
leadguru_file.file_name = file['name']
|
27
|
+
leadguru_file.blob_path = f'slack_files/{bot_name}/slack_files/{file["id"]}'
|
28
|
+
result.files.append(leadguru_file)
|
53
29
|
|
54
30
|
js_ticks = int(result.id.split('.')[0] + result.id.split('.')[1][3:])
|
55
31
|
result.created_at = datetime.fromtimestamp(js_ticks / 1000.0)
|
@@ -59,23 +35,12 @@ class SlackMessageConvertService:
|
|
59
35
|
class SlackFilesClient:
|
60
36
|
bucket_name = 'lgt_service_file'
|
61
37
|
|
62
|
-
|
63
|
-
@staticmethod
|
64
|
-
def get_file_url(user_email, bot_name, bot_token, file_id, url_private_download, mimetype, cookies=None):
|
38
|
+
def get_file_url(self, blob_path):
|
65
39
|
storage_client = storage.Client()
|
66
|
-
bucket = storage_client.get_bucket(
|
67
|
-
blob_path = f'slack_files/{user_email}/{bot_name}/{file_id}'
|
40
|
+
bucket = storage_client.get_bucket(self.bucket_name)
|
68
41
|
blob = bucket.get_blob(blob_path)
|
69
|
-
|
70
42
|
if not blob:
|
71
|
-
|
72
|
-
if res.status_code != 200:
|
73
|
-
raise Exception(
|
74
|
-
f'Failed to download file: {url_private_download} from slack due to response: '
|
75
|
-
f'Code: {res.status_code} Error: {res.content}')
|
76
|
-
blob = bucket.blob(blob_path)
|
77
|
-
blob.upload_from_string(res.content, content_type=mimetype)
|
78
|
-
|
43
|
+
return None
|
79
44
|
# valid for 3 days
|
80
45
|
return blob.generate_signed_url(timedelta(3))
|
81
46
|
|
@@ -138,10 +103,10 @@ class SlackWebClient:
|
|
138
103
|
def confirm_email(self, email: str, user_agent: str, locale: str = 'en-US') -> bool:
|
139
104
|
return self.client.confirm_email(email, user_agent, locale)
|
140
105
|
|
141
|
-
def confirm_code(self, email: str, code: str, user_agent: str
|
106
|
+
def confirm_code(self, email: str, code: str, user_agent: str):
|
142
107
|
return self.client.confirm_code(email, code, user_agent)
|
143
108
|
|
144
|
-
def find_workspaces(self, user_agent: str
|
109
|
+
def find_workspaces(self, user_agent: str):
|
145
110
|
return self.client.find_workspaces(user_agent)
|
146
111
|
|
147
112
|
def conversation_replies(self, channel: str, id: str) -> dict:
|
lgt_jobs/lgt_data/enums.py
CHANGED
lgt_jobs/lgt_data/model.py
CHANGED
@@ -322,6 +322,10 @@ class UserModel(BaseModel):
|
|
322
322
|
def is_admin(self):
|
323
323
|
return UserRole.ADMIN in self.roles
|
324
324
|
|
325
|
+
@property
|
326
|
+
def subscription_expired(self):
|
327
|
+
return self.subscription_expired_at.replace(tzinfo=UTC) < datetime.now(UTC)
|
328
|
+
|
325
329
|
def get_slack_user(self, slack_email: str):
|
326
330
|
return next(filter(lambda x: slack_email == x.email, self.slack_users), None)
|
327
331
|
|
@@ -579,9 +583,7 @@ class ChatMessage:
|
|
579
583
|
|
580
584
|
def to_dic(self):
|
581
585
|
result = copy.deepcopy(self.__dict__)
|
582
|
-
|
583
|
-
result['files'] = [x.to_dic() if isinstance(x, ChatMessage.SlackFileModel) else x for x in self.files]
|
584
|
-
|
586
|
+
result['files'] = [x.to_dic() for x in result.get('files', [])]
|
585
587
|
return result
|
586
588
|
|
587
589
|
@classmethod
|
@@ -869,7 +871,8 @@ class ExtendedSlackMemberInformation(SlackMemberInformation):
|
|
869
871
|
if not hasattr(contact, "display_name"):
|
870
872
|
contact.display_name = contact.name
|
871
873
|
|
872
|
-
lead.linkedin_urls = [
|
874
|
+
lead.linkedin_urls = [
|
875
|
+
f"https://www.linkedin.com/search/results/all/?keywords={contact.real_name}&origin=GLOBAL_SEARCH_HEADER&sid=u%40F"]
|
873
876
|
lead.message = MessageModel()
|
874
877
|
lead.message.message = contact.real_name
|
875
878
|
if contact.title:
|
@@ -971,3 +974,19 @@ class Subscription(BaseModel):
|
|
971
974
|
model: Subscription | None = super().from_dic(dic)
|
972
975
|
model.features = [Feature.from_dic(feature) for feature in dic.get('features', [])]
|
973
976
|
return model
|
977
|
+
|
978
|
+
|
979
|
+
class LeadGuruFile(DictionaryModel):
|
980
|
+
id: str = None
|
981
|
+
blob_path: str
|
982
|
+
content_type: str
|
983
|
+
file_name: str = None
|
984
|
+
|
985
|
+
|
986
|
+
class ScheduledMessage(BaseModel):
|
987
|
+
post_at: datetime
|
988
|
+
bot_id: ObjectId
|
989
|
+
user_id: ObjectId
|
990
|
+
sender_id: str
|
991
|
+
text: str | None
|
992
|
+
files: list
|
@@ -9,7 +9,8 @@ from lgt_jobs.lgt_data.enums import SourceType
|
|
9
9
|
from lgt_jobs.lgt_data.model import (LeadModel, BaseModel, UserModel, UserResetPasswordModel, BoardModel, BoardedStatus,
|
10
10
|
DedicatedBotModel, SlackMemberInformation, UserTemplateModel,
|
11
11
|
ExtendedUserLeadModel, UserLeadModel, ExtendedLeadModel, UserContact, ChatMessage,
|
12
|
-
GroupedMessagesModel, UserVerificationModel, UsersPage, Subscription
|
12
|
+
GroupedMessagesModel, UserVerificationModel, UsersPage, Subscription,
|
13
|
+
ScheduledMessage)
|
13
14
|
from datetime import datetime, UTC, timedelta
|
14
15
|
from collections import OrderedDict
|
15
16
|
|
@@ -1207,3 +1208,15 @@ class SubscriptionsRepository(BaseMongoRepository):
|
|
1207
1208
|
pipeline['expired'] = expired
|
1208
1209
|
|
1209
1210
|
return Subscription.from_dic(self.collection().find_one(pipeline))
|
1211
|
+
|
1212
|
+
|
1213
|
+
class ScheduledMessagesRepository(BaseMongoRepository):
|
1214
|
+
pass
|
1215
|
+
|
1216
|
+
collection_name = 'scheduled_messages'
|
1217
|
+
|
1218
|
+
def find_all(self, only_actual: bool = True):
|
1219
|
+
pipeline = {}
|
1220
|
+
if only_actual:
|
1221
|
+
pipeline['post_at'] = {'$lte': datetime.now(UTC)}
|
1222
|
+
return [ScheduledMessage.from_dic(doc) for doc in self.collection().find(pipeline)]
|
File without changes
|
File without changes
|