Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

724 send weekly analysis to the user at the same day of the week when the user created the account #764

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion application.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ async def lifespan(app: FastAPI) -> AsyncGenerator: # type: ignore
"cron",
hour="4",
minute="15",
day_of_week="wed",
# day_of_week="wed",
)
scheduler.start()

Expand Down
31 changes: 30 additions & 1 deletion captn/captn_agents/backend/teams/_weekly_analysis_team.py
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,8 @@ def _guidelines(self) -> str:
"Remove 'Free' keyword because it is not performing well" is specific enough.
"Remove the headline 'New product' and replace it with 'Very New product' in the 'Adgroup 1'" is specific enough.

Messages within the 'proposed_user_actions' are the ONLY messages the client will see. So make sure to include all the necessary information in them.
e.g. Do NOT suggest 'Update the ad copy with the suggested headlines and descriptions for better engagement.' because the client will not know which ad copy you are talking about and what changes you want to make.

12. There is a list of commands which you are able to execute in the 'Commands' section.
You can NOT execute anything else, so do not suggest changes which you can NOT perform.
Expand Down Expand Up @@ -1029,6 +1031,28 @@ def _validate_conversation_and_send_email(
)


def _get_day_of_week(date_str: str) -> str:
# Parse the date string into a datetime object
date_obj = datetime.strptime(date_str, "%Y-%m-%d")

# Get the day of the week as an integer (0=Monday, 6=Sunday)
day_of_week_num = date_obj.weekday()

# Map the integer to the day name
days = [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday",
]
day_of_week_name = days[day_of_week_num]

return day_of_week_name


def execute_weekly_analysis(
send_only_to_emails: Optional[List[str]] = None,
date: Optional[str] = None,
Expand All @@ -1038,7 +1062,12 @@ def execute_weekly_analysis(
if date is None:
date = (datetime.today().date() - timedelta(1)).isoformat()
print("Starting weekly analysis.")
id_email_dict = json.loads(get_user_ids_and_emails())
if send_only_to_emails is not None:
day_of_week = None
else:
day_of_week = _get_day_of_week(date)
day_of_week = "Wednesday"
id_email_dict = json.loads(get_user_ids_and_emails(day_of_week=day_of_week))

# if send_only_to_emails is None:
# send_only_to_emails = ["robert@airt.ai", "harish@airt.ai"]
Expand Down
9 changes: 7 additions & 2 deletions captn/google_ads/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,13 @@ def execute_query(
return str(response_json)


def get_user_ids_and_emails() -> str:
response = requests_get(f"{BASE_URL}/get-user-ids-and-emails", timeout=60)
def get_user_ids_and_emails(day_of_week: Optional[str] = None) -> str:
params = {
"day_of_week_created": day_of_week,
}
response = requests_get(
f"{BASE_URL}/get-user-ids-and-emails", params=params, timeout=60
)
if not response.ok:
raise ValueError(response.content)
return response.json() # type: ignore[no-any-return]
Expand Down
13 changes: 9 additions & 4 deletions google_ads/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,15 @@
}


async def get_users() -> Any:
async def get_users(day_of_week_created: Optional[str] = None) -> Any:
wasp_db_url = await get_wasp_db_url()
if day_of_week_created:
query = f"""SELECT * FROM "User"
WHERE TO_CHAR("createdAt", 'Day') = '{day_of_week_created}'""" # nosec: [B608]
else:
query = 'SELECT * from "User"'
async with get_db_connection(db_url=wasp_db_url) as db:
users = await db.query_raw('SELECT * from "User"')
users = await db.query_raw(query)

return users

Expand Down Expand Up @@ -337,8 +342,8 @@ async def search(

# Route 5: Fetch user's emails
@router.get("/get-user-ids-and-emails")
async def get_user_ids_and_emails() -> str:
users = await get_users()
async def get_user_ids_and_emails(day_of_week_created: Optional[str] = None) -> str:
users = await get_users(day_of_week_created=day_of_week_created)
id_email_dict = {user["id"]: user["email"] for user in users}
return json.dumps(id_email_dict)

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ agents = [
"fastapi==0.111.0",
"APScheduler==3.10.4",
"prisma==0.13.1",
"google-ads==23.1.0",
"google-ads==24.1.0",
"httpx==0.27.0",
"uvicorn==0.30.1",
"python-dotenv==1.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
_add_metrics_message,
_check_if_any_campaign_exists,
_create_date_query,
_get_day_of_week,
_update_chat_message_and_send_email,
_update_message_and_campaigns_template,
calculate_metrics_change,
Expand Down Expand Up @@ -1343,6 +1344,16 @@ def test_get_weekly_report_when_there_are_no_campaigns() -> None:
)


def test_get_day_of_week() -> None:
assert _get_day_of_week("2024-06-09") == "Sunday"
assert _get_day_of_week("2024-06-10") == "Monday"
assert _get_day_of_week("2024-06-11") == "Tuesday"
assert _get_day_of_week("2024-06-12") == "Wednesday"
assert _get_day_of_week("2024-06-13") == "Thursday"
assert _get_day_of_week("2024-06-14") == "Friday"
assert _get_day_of_week("2024-06-15") == "Saturday"


class TestWeeklyAnalysisTeam:
@pytest.fixture(autouse=True)
def setup(self) -> Iterator[None]:
Expand Down