fusesell 1.3.42__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.
- fusesell-1.3.42.dist-info/METADATA +873 -0
- fusesell-1.3.42.dist-info/RECORD +35 -0
- fusesell-1.3.42.dist-info/WHEEL +5 -0
- fusesell-1.3.42.dist-info/entry_points.txt +2 -0
- fusesell-1.3.42.dist-info/licenses/LICENSE +21 -0
- fusesell-1.3.42.dist-info/top_level.txt +2 -0
- fusesell.py +20 -0
- fusesell_local/__init__.py +37 -0
- fusesell_local/api.py +343 -0
- fusesell_local/cli.py +1480 -0
- fusesell_local/config/__init__.py +11 -0
- fusesell_local/config/default_email_templates.json +34 -0
- fusesell_local/config/default_prompts.json +19 -0
- fusesell_local/config/default_scoring_criteria.json +154 -0
- fusesell_local/config/prompts.py +245 -0
- fusesell_local/config/settings.py +277 -0
- fusesell_local/pipeline.py +978 -0
- fusesell_local/stages/__init__.py +19 -0
- fusesell_local/stages/base_stage.py +603 -0
- fusesell_local/stages/data_acquisition.py +1820 -0
- fusesell_local/stages/data_preparation.py +1238 -0
- fusesell_local/stages/follow_up.py +1728 -0
- fusesell_local/stages/initial_outreach.py +2972 -0
- fusesell_local/stages/lead_scoring.py +1452 -0
- fusesell_local/utils/__init__.py +36 -0
- fusesell_local/utils/agent_context.py +552 -0
- fusesell_local/utils/auto_setup.py +361 -0
- fusesell_local/utils/birthday_email_manager.py +467 -0
- fusesell_local/utils/data_manager.py +4857 -0
- fusesell_local/utils/event_scheduler.py +959 -0
- fusesell_local/utils/llm_client.py +342 -0
- fusesell_local/utils/logger.py +203 -0
- fusesell_local/utils/output_helpers.py +2443 -0
- fusesell_local/utils/timezone_detector.py +914 -0
- fusesell_local/utils/validators.py +436 -0
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Birthday Email Management System for FuseSell Local
|
|
3
|
+
Handles birthday email template generation, validation, and processing
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
import logging
|
|
8
|
+
from typing import Dict, Any, Optional, List
|
|
9
|
+
from datetime import datetime, timedelta
|
|
10
|
+
import uuid
|
|
11
|
+
from .data_manager import LocalDataManager
|
|
12
|
+
from .llm_client import LLMClient
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BirthdayEmailManager:
|
|
16
|
+
"""
|
|
17
|
+
Manages birthday email functionality including template generation,
|
|
18
|
+
validation, and processing based on server-side logic from gs_scheduler.py
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, config: Dict[str, Any]):
|
|
22
|
+
"""
|
|
23
|
+
Initialize birthday email manager.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
config: Configuration dictionary with API keys and settings
|
|
27
|
+
"""
|
|
28
|
+
self.config = config
|
|
29
|
+
self.data_manager = LocalDataManager(config.get('data_dir', './fusesell_data'))
|
|
30
|
+
self.llm_client = LLMClient(
|
|
31
|
+
api_key=config.get('openai_api_key'),
|
|
32
|
+
model=config.get('llm_model', 'gpt-4.1-mini'),
|
|
33
|
+
base_url=config.get('llm_base_url')
|
|
34
|
+
)
|
|
35
|
+
self.logger = logging.getLogger("fusesell.birthday_email")
|
|
36
|
+
|
|
37
|
+
# Initialize database tables
|
|
38
|
+
self._initialize_tables()
|
|
39
|
+
|
|
40
|
+
def validate_birthday_prompt(self, prompt: str) -> Dict[str, Any]:
|
|
41
|
+
"""
|
|
42
|
+
Validate birthday email prompt using LLM analysis.
|
|
43
|
+
Based on gs_scheduler.py birthday email check logic.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
prompt: User input prompt to validate
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
Dictionary with validation results
|
|
50
|
+
"""
|
|
51
|
+
try:
|
|
52
|
+
validation_prompt = (
|
|
53
|
+
"Analyze the following text and return a JSON object with exactly 2 fields: "
|
|
54
|
+
"'is_complete_prompt' (boolean - true if it's a complete prompt for writing "
|
|
55
|
+
"birthday email content/drafts with detailed instructions on what to write, "
|
|
56
|
+
"tone, style, etc. NOT configuration/settings instructions) and 'is_enabled' "
|
|
57
|
+
"(boolean - true if birthday email functionality is enabled, default to true). "
|
|
58
|
+
"Configuration instructions like 'update settings', 'enable birthday email', "
|
|
59
|
+
"'set timezone', etc. should return false for is_complete_prompt. "
|
|
60
|
+
"Your output should be a valid JSON object only. Here's the text to analyze:\n\n"
|
|
61
|
+
+ prompt
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
messages = [{"role": "user", "content": validation_prompt}]
|
|
65
|
+
response = self.llm_client.chat_completion(messages, temperature=0.3)
|
|
66
|
+
|
|
67
|
+
try:
|
|
68
|
+
validation_result = json.loads(response)
|
|
69
|
+
return {
|
|
70
|
+
'is_complete_prompt': validation_result.get('is_complete_prompt', False),
|
|
71
|
+
'is_enabled': validation_result.get('is_enabled', True),
|
|
72
|
+
'validation_successful': True
|
|
73
|
+
}
|
|
74
|
+
except json.JSONDecodeError:
|
|
75
|
+
self.logger.warning("Failed to parse LLM validation response")
|
|
76
|
+
return {
|
|
77
|
+
'is_complete_prompt': False,
|
|
78
|
+
'is_enabled': False,
|
|
79
|
+
'validation_successful': False
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
except Exception as e:
|
|
83
|
+
self.logger.error(f"Birthday prompt validation failed: {str(e)}")
|
|
84
|
+
return {
|
|
85
|
+
'is_complete_prompt': False,
|
|
86
|
+
'is_enabled': False,
|
|
87
|
+
'validation_successful': False,
|
|
88
|
+
'error': str(e)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
def generate_birthday_settings_rule(self, prompt: str) -> Dict[str, Any]:
|
|
92
|
+
"""
|
|
93
|
+
Generate birthday email settings rule from user prompt.
|
|
94
|
+
Based on gs_scheduler.py birthday email rule generation logic.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
prompt: User input prompt
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
Dictionary with generated rule settings
|
|
101
|
+
"""
|
|
102
|
+
try:
|
|
103
|
+
rule_prompt = (
|
|
104
|
+
"You are an AI assistant tasked with converting user input into a structured "
|
|
105
|
+
"JSON format for birthday email composition. Analyze the following input and "
|
|
106
|
+
"extract key parameters for crafting an email. Your output should be a valid "
|
|
107
|
+
"JSON object with fields such as 'fewshots_strict_follow' (boolean, required, "
|
|
108
|
+
"indicating if the drafts must follow the examples or not, false if is not mentioned), "
|
|
109
|
+
"'maximum_words' (integer), 'mail_tone' (string), and 'org_timezone' (string, "
|
|
110
|
+
"UTC timezone format like 'UTC+07' or 'UTC-04', extract from the input if mentioned).\n\n"
|
|
111
|
+
"For example, if the input is \"Độ dài giới hạn 400 từ, xưng hô là 'mình' hoặc "
|
|
112
|
+
"tên người gửi, múi giờ UTC+7.\", your output might be:\n"
|
|
113
|
+
"{\n"
|
|
114
|
+
" \"maximum_words\": 400,\n"
|
|
115
|
+
" \"mail_tone\": \"Friendly\",\n"
|
|
116
|
+
" \"pronoun\": \"mình\",\n"
|
|
117
|
+
" \"fewshots_strict_follow\": true,\n"
|
|
118
|
+
" \"org_timezone\": \"UTC+07\"\n"
|
|
119
|
+
"}\n\n"
|
|
120
|
+
"Ensure your output is a single, valid JSON object. Include only the fields "
|
|
121
|
+
"that are explicitly mentioned or strongly implied in the input. For org_timezone, "
|
|
122
|
+
"look for timezone information in formats like 'UTC+7', 'GMT+7', '+7', 'timezone +7', "
|
|
123
|
+
"etc. and convert to UTC format (UTC+07 or UTC-04). NO REDUNDANT WORDS. "
|
|
124
|
+
"NO NEED TO BE WRAPPED IN ``` CODE BLOCK CHARACTERS. Here's the input to analyze:\n"
|
|
125
|
+
+ prompt
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
messages = [{"role": "user", "content": rule_prompt}]
|
|
129
|
+
response = self.llm_client.chat_completion(messages, temperature=0.3)
|
|
130
|
+
|
|
131
|
+
try:
|
|
132
|
+
rule = json.loads(response)
|
|
133
|
+
|
|
134
|
+
# Add default values and validation
|
|
135
|
+
rule.setdefault('fewshots_strict_follow', False)
|
|
136
|
+
rule.setdefault('maximum_words', 200)
|
|
137
|
+
rule.setdefault('mail_tone', 'Friendly')
|
|
138
|
+
rule.setdefault('org_timezone', 'UTC+07')
|
|
139
|
+
|
|
140
|
+
# Add extra guide
|
|
141
|
+
rule['extra_guide'] = prompt
|
|
142
|
+
|
|
143
|
+
# Add birthday email check
|
|
144
|
+
validation_result = self.validate_birthday_prompt(prompt)
|
|
145
|
+
rule['birthday_email_check'] = {
|
|
146
|
+
'is_complete_prompt': validation_result['is_complete_prompt'],
|
|
147
|
+
'is_enabled': validation_result['is_enabled']
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return rule
|
|
151
|
+
|
|
152
|
+
except json.JSONDecodeError:
|
|
153
|
+
self.logger.warning("Failed to parse LLM rule generation response")
|
|
154
|
+
return self._get_default_birthday_rule(prompt)
|
|
155
|
+
|
|
156
|
+
except Exception as e:
|
|
157
|
+
self.logger.error(f"Birthday rule generation failed: {str(e)}")
|
|
158
|
+
return self._get_default_birthday_rule(prompt)
|
|
159
|
+
|
|
160
|
+
def _get_default_birthday_rule(self, prompt: str) -> Dict[str, Any]:
|
|
161
|
+
"""Get default birthday email rule when LLM processing fails."""
|
|
162
|
+
return {
|
|
163
|
+
'fewshots_strict_follow': False,
|
|
164
|
+
'maximum_words': 200,
|
|
165
|
+
'mail_tone': 'Friendly',
|
|
166
|
+
'org_timezone': 'UTC+07',
|
|
167
|
+
'extra_guide': prompt,
|
|
168
|
+
'birthday_email_check': {
|
|
169
|
+
'is_complete_prompt': False,
|
|
170
|
+
'is_enabled': True
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
def generate_birthday_template(self, team_id: str, org_id: str,
|
|
175
|
+
prompt: str, **kwargs) -> Dict[str, Any]:
|
|
176
|
+
"""
|
|
177
|
+
Generate birthday email template.
|
|
178
|
+
Simulates the flowai/auto_interaction_generate_email_template workflow.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
team_id: Team identifier
|
|
182
|
+
org_id: Organization identifier
|
|
183
|
+
prompt: User prompt for template generation
|
|
184
|
+
**kwargs: Additional parameters
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
Dictionary with template generation results
|
|
188
|
+
"""
|
|
189
|
+
try:
|
|
190
|
+
template_id = f"uuid:{str(uuid.uuid4())}"
|
|
191
|
+
template_type = "birthday_email"
|
|
192
|
+
|
|
193
|
+
# Generate template content using LLM
|
|
194
|
+
template_prompt = (
|
|
195
|
+
f"Generate a birthday email template based on the following requirements:\n"
|
|
196
|
+
f"Team ID: {team_id}\n"
|
|
197
|
+
f"Organization: {org_id}\n"
|
|
198
|
+
f"Requirements: {prompt}\n\n"
|
|
199
|
+
f"Create a professional birthday email template that can be personalized "
|
|
200
|
+
f"for customers. Include placeholders for customer name, company name, "
|
|
201
|
+
f"and other relevant details. The template should be warm, professional, "
|
|
202
|
+
f"and appropriate for business relationships.\n\n"
|
|
203
|
+
f"Return the template as a JSON object with fields: 'subject', 'content', "
|
|
204
|
+
f"'placeholders' (list of available placeholders), and 'tone'."
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
messages = [{"role": "user", "content": template_prompt}]
|
|
208
|
+
response = self.llm_client.chat_completion(messages, temperature=0.7)
|
|
209
|
+
|
|
210
|
+
try:
|
|
211
|
+
template_data = json.loads(response)
|
|
212
|
+
except json.JSONDecodeError:
|
|
213
|
+
# Fallback template
|
|
214
|
+
template_data = {
|
|
215
|
+
'subject': 'Happy Birthday from {{company_name}}!',
|
|
216
|
+
'content': (
|
|
217
|
+
'Dear {{customer_name}},\n\n'
|
|
218
|
+
'On behalf of everyone at {{company_name}}, I wanted to take a moment '
|
|
219
|
+
'to wish you a very happy birthday!\n\n'
|
|
220
|
+
'We truly appreciate your partnership and look forward to continuing '
|
|
221
|
+
'our successful relationship in the year ahead.\n\n'
|
|
222
|
+
'Wishing you all the best on your special day!\n\n'
|
|
223
|
+
'Best regards,\n'
|
|
224
|
+
'{{sender_name}}\n'
|
|
225
|
+
'{{company_name}}'
|
|
226
|
+
),
|
|
227
|
+
'placeholders': ['customer_name', 'company_name', 'sender_name'],
|
|
228
|
+
'tone': 'professional_warm'
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
# Save template to database
|
|
232
|
+
template_record = {
|
|
233
|
+
'template_id': template_id,
|
|
234
|
+
'team_id': team_id,
|
|
235
|
+
'org_id': org_id,
|
|
236
|
+
'template_type': template_type,
|
|
237
|
+
'subject': template_data.get('subject', ''),
|
|
238
|
+
'content': template_data.get('content', ''),
|
|
239
|
+
'placeholders': json.dumps(template_data.get('placeholders', [])),
|
|
240
|
+
'tone': template_data.get('tone', 'professional'),
|
|
241
|
+
'created_at': datetime.now().isoformat(),
|
|
242
|
+
'created_by': kwargs.get('username', 'system'),
|
|
243
|
+
'prompt': prompt
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
success = self._save_birthday_template(template_record)
|
|
247
|
+
|
|
248
|
+
return {
|
|
249
|
+
'template_id': template_id,
|
|
250
|
+
'template_data': template_data,
|
|
251
|
+
'saved': success,
|
|
252
|
+
'message': 'Birthday email template generated successfully' if success else 'Template generated but save failed'
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
except Exception as e:
|
|
256
|
+
self.logger.error(f"Birthday template generation failed: {str(e)}")
|
|
257
|
+
return {
|
|
258
|
+
'template_id': None,
|
|
259
|
+
'template_data': None,
|
|
260
|
+
'saved': False,
|
|
261
|
+
'error': str(e)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
def _save_birthday_template(self, template_record: Dict[str, Any]) -> bool:
|
|
265
|
+
"""Save birthday email template to database."""
|
|
266
|
+
try:
|
|
267
|
+
import sqlite3
|
|
268
|
+
# Create birthday_templates table if it doesn't exist
|
|
269
|
+
with sqlite3.connect(self.data_manager.db_path) as conn:
|
|
270
|
+
cursor = conn.cursor()
|
|
271
|
+
cursor.execute("""
|
|
272
|
+
CREATE TABLE IF NOT EXISTS birthday_templates (
|
|
273
|
+
template_id TEXT PRIMARY KEY,
|
|
274
|
+
team_id TEXT NOT NULL,
|
|
275
|
+
org_id TEXT NOT NULL,
|
|
276
|
+
template_type TEXT DEFAULT 'birthday_email',
|
|
277
|
+
subject TEXT,
|
|
278
|
+
content TEXT,
|
|
279
|
+
placeholders TEXT,
|
|
280
|
+
tone TEXT,
|
|
281
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
282
|
+
created_by TEXT,
|
|
283
|
+
prompt TEXT,
|
|
284
|
+
is_active BOOLEAN DEFAULT TRUE
|
|
285
|
+
)
|
|
286
|
+
""")
|
|
287
|
+
|
|
288
|
+
# Insert or update template
|
|
289
|
+
cursor.execute("""
|
|
290
|
+
INSERT OR REPLACE INTO birthday_templates
|
|
291
|
+
(template_id, team_id, org_id, template_type, subject, content,
|
|
292
|
+
placeholders, tone, created_at, created_by, prompt, is_active)
|
|
293
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
294
|
+
""", (
|
|
295
|
+
template_record['template_id'],
|
|
296
|
+
template_record['team_id'],
|
|
297
|
+
template_record['org_id'],
|
|
298
|
+
template_record['template_type'],
|
|
299
|
+
template_record['subject'],
|
|
300
|
+
template_record['content'],
|
|
301
|
+
template_record['placeholders'],
|
|
302
|
+
template_record['tone'],
|
|
303
|
+
template_record['created_at'],
|
|
304
|
+
template_record['created_by'],
|
|
305
|
+
template_record['prompt'],
|
|
306
|
+
True
|
|
307
|
+
))
|
|
308
|
+
|
|
309
|
+
conn.commit()
|
|
310
|
+
return True
|
|
311
|
+
|
|
312
|
+
except Exception as e:
|
|
313
|
+
self.logger.error(f"Failed to save birthday template: {str(e)}")
|
|
314
|
+
return False
|
|
315
|
+
|
|
316
|
+
def get_birthday_template(self, template_id: str) -> Optional[Dict[str, Any]]:
|
|
317
|
+
"""Get birthday email template by ID."""
|
|
318
|
+
try:
|
|
319
|
+
import sqlite3
|
|
320
|
+
with sqlite3.connect(self.data_manager.db_path) as conn:
|
|
321
|
+
conn.row_factory = sqlite3.Row
|
|
322
|
+
cursor = conn.cursor()
|
|
323
|
+
cursor.execute("""
|
|
324
|
+
SELECT * FROM birthday_templates
|
|
325
|
+
WHERE template_id = ? AND is_active = TRUE
|
|
326
|
+
""", (template_id,))
|
|
327
|
+
|
|
328
|
+
row = cursor.fetchone()
|
|
329
|
+
if row:
|
|
330
|
+
# Parse placeholders JSON
|
|
331
|
+
if row['placeholders']:
|
|
332
|
+
try:
|
|
333
|
+
row['placeholders'] = json.loads(row['placeholders'])
|
|
334
|
+
except json.JSONDecodeError:
|
|
335
|
+
row['placeholders'] = []
|
|
336
|
+
return dict(row)
|
|
337
|
+
return None
|
|
338
|
+
|
|
339
|
+
except Exception as e:
|
|
340
|
+
self.logger.error(f"Failed to get birthday template: {str(e)}")
|
|
341
|
+
return None
|
|
342
|
+
|
|
343
|
+
def list_birthday_templates(self, team_id: str = None, org_id: str = None) -> List[Dict[str, Any]]:
|
|
344
|
+
"""List birthday email templates."""
|
|
345
|
+
try:
|
|
346
|
+
import sqlite3
|
|
347
|
+
with sqlite3.connect(self.data_manager.db_path) as conn:
|
|
348
|
+
conn.row_factory = sqlite3.Row
|
|
349
|
+
cursor = conn.cursor()
|
|
350
|
+
|
|
351
|
+
query = "SELECT * FROM birthday_templates WHERE is_active = TRUE"
|
|
352
|
+
params = []
|
|
353
|
+
|
|
354
|
+
if team_id:
|
|
355
|
+
query += " AND team_id = ?"
|
|
356
|
+
params.append(team_id)
|
|
357
|
+
|
|
358
|
+
if org_id:
|
|
359
|
+
query += " AND org_id = ?"
|
|
360
|
+
params.append(org_id)
|
|
361
|
+
|
|
362
|
+
query += " ORDER BY created_at DESC"
|
|
363
|
+
|
|
364
|
+
cursor.execute(query, params)
|
|
365
|
+
rows = cursor.fetchall()
|
|
366
|
+
|
|
367
|
+
templates = []
|
|
368
|
+
for row in rows:
|
|
369
|
+
row_dict = dict(row)
|
|
370
|
+
# Parse placeholders JSON
|
|
371
|
+
if row_dict['placeholders']:
|
|
372
|
+
try:
|
|
373
|
+
row_dict['placeholders'] = json.loads(row_dict['placeholders'])
|
|
374
|
+
except json.JSONDecodeError:
|
|
375
|
+
row_dict['placeholders'] = []
|
|
376
|
+
templates.append(row_dict)
|
|
377
|
+
|
|
378
|
+
return templates
|
|
379
|
+
|
|
380
|
+
except Exception as e:
|
|
381
|
+
self.logger.error(f"Failed to list birthday templates: {str(e)}")
|
|
382
|
+
return []
|
|
383
|
+
|
|
384
|
+
def process_birthday_email_settings(self, team_id: str, prompt: str,
|
|
385
|
+
org_id: str, **kwargs) -> Dict[str, Any]:
|
|
386
|
+
"""
|
|
387
|
+
Process birthday email settings configuration.
|
|
388
|
+
Main entry point that combines validation, rule generation, and template creation.
|
|
389
|
+
|
|
390
|
+
Args:
|
|
391
|
+
team_id: Team identifier
|
|
392
|
+
prompt: User input prompt
|
|
393
|
+
org_id: Organization identifier
|
|
394
|
+
**kwargs: Additional parameters
|
|
395
|
+
|
|
396
|
+
Returns:
|
|
397
|
+
Dictionary with processing results
|
|
398
|
+
"""
|
|
399
|
+
try:
|
|
400
|
+
# Step 1: Validate the prompt
|
|
401
|
+
validation_result = self.validate_birthday_prompt(prompt)
|
|
402
|
+
|
|
403
|
+
# Step 2: Generate settings rule
|
|
404
|
+
rule = self.generate_birthday_settings_rule(prompt)
|
|
405
|
+
|
|
406
|
+
# Step 3: Generate template if it's a complete prompt
|
|
407
|
+
template_result = None
|
|
408
|
+
if validation_result.get('is_complete_prompt', False):
|
|
409
|
+
template_result = self.generate_birthday_template(
|
|
410
|
+
team_id, org_id, prompt, **kwargs
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
# Step 4: Prepare final settings
|
|
414
|
+
birthday_settings = {
|
|
415
|
+
'mail_tone': rule.get('mail_tone', 'Friendly'),
|
|
416
|
+
'extra_guide': rule.get('extra_guide', prompt),
|
|
417
|
+
'org_timezone': rule.get('org_timezone', 'UTC+07'),
|
|
418
|
+
'maximum_words': rule.get('maximum_words', 200),
|
|
419
|
+
'birthday_email_check': rule.get('birthday_email_check', {
|
|
420
|
+
'is_enabled': True,
|
|
421
|
+
'is_complete_prompt': False
|
|
422
|
+
}),
|
|
423
|
+
'fewshots_strict_follow': rule.get('fewshots_strict_follow', False)
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
return {
|
|
427
|
+
'success': True,
|
|
428
|
+
'settings': birthday_settings,
|
|
429
|
+
'validation': validation_result,
|
|
430
|
+
'rule': rule,
|
|
431
|
+
'template': template_result,
|
|
432
|
+
'message': 'Birthday email settings processed successfully'
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
except Exception as e:
|
|
436
|
+
self.logger.error(f"Birthday email settings processing failed: {str(e)}")
|
|
437
|
+
return {
|
|
438
|
+
'success': False,
|
|
439
|
+
'error': str(e),
|
|
440
|
+
'message': 'Failed to process birthday email settings'
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
def _initialize_tables(self) -> None:
|
|
444
|
+
"""Initialize birthday email database tables."""
|
|
445
|
+
try:
|
|
446
|
+
import sqlite3
|
|
447
|
+
with sqlite3.connect(self.data_manager.db_path) as conn:
|
|
448
|
+
cursor = conn.cursor()
|
|
449
|
+
cursor.execute("""
|
|
450
|
+
CREATE TABLE IF NOT EXISTS birthday_templates (
|
|
451
|
+
template_id TEXT PRIMARY KEY,
|
|
452
|
+
team_id TEXT NOT NULL,
|
|
453
|
+
org_id TEXT NOT NULL,
|
|
454
|
+
template_type TEXT DEFAULT 'birthday_email',
|
|
455
|
+
subject TEXT,
|
|
456
|
+
content TEXT,
|
|
457
|
+
placeholders TEXT,
|
|
458
|
+
tone TEXT,
|
|
459
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
460
|
+
created_by TEXT,
|
|
461
|
+
prompt TEXT,
|
|
462
|
+
is_active BOOLEAN DEFAULT TRUE
|
|
463
|
+
)
|
|
464
|
+
""")
|
|
465
|
+
conn.commit()
|
|
466
|
+
except Exception as e:
|
|
467
|
+
self.logger.error(f"Failed to initialize birthday email tables: {str(e)}")
|