Mr-Help's picture
Update app.py
5dfdba5 verified
raw
history blame
11.3 kB
from fastapi import FastAPI, Request
from pydantic import BaseModel
import requests
import logging
from datetime import datetime
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
app = FastAPI()
# ClickUp API URL for creating a task
CLICKUP_URL_BASE = "https://api.clickup.com/api/v2"
# WhatsApp API URL
WHATSAPP_URL = "https://7105.api.greenapi.com/waInstance7105210836/sendMessage/805b69f6c85d4e6caea0edaba692b889abecc9e6bb8b457e8f"
# Your access token
ACCESS_TOKEN = "2144425825_36f2249dc27c5aca075ac5442b1bbcdf01c3a29b9e41b86bda46a6cf651acd0f"
# Headers for ClickUp authorization
headers = {
"Authorization": ACCESS_TOKEN,
"Content-Type": "application/json"
}
# Headers for WhatsApp API
whatsapp_headers = {
"Content-Type": "application/json"
}
class TaskData(BaseModel):
task_name: str
task_type: str # "Reel" or "Design"
campaign_name: str
platforms: list[str]
assignees: list[int] # List of user IDs
due_date: int # Unix timestamp in milliseconds
@app.post("/singletask")
async def create_task(request: Request):
data = await request.json()
logging.info(f"Received task data: {data}")
# Extract and assign to variables
team = data.get('team', '')
task_type = data.get('taskType', '')
task_title = data.get('taskTitle', '')
assignees = data.get('assignees', '')
platforms = data.get('platforms', [])
deadline = data.get('deadline', '')
goal = data.get('goal', '')
description = data.get('description', '')
creative_type = data.get('creativeType', '')
ad_content = data.get('adContent', '')
posting_content = data.get('postingContent', '')
attachment_link = data.get('attachmentLink', '')
start_date = data.get('startDate', '')
end_date = data.get('endDate', '')
# Print extracted values for debugging
print(f"Team: {team}")
print(f"Task Type: {task_type}")
print(f"Task Title: {task_title}")
print(f"Assignees: {assignees}")
print(f"Platforms: {platforms}")
print(f"Deadline: {deadline}")
print(f"Goal: {goal}")
print(f"Description: {description}")
print(f"Creative Type: {creative_type}")
print(f"Ad Content: {ad_content}")
print(f"Posting Content: {posting_content}")
print(f"Attachment Link: {attachment_link}")
print(f"Start Date: {start_date}")
print(f"End Date: {end_date}")
web_app_url = "https://script.google.com/macros/s/AKfycbzL6OVq4WNKb1mX0BWEtvxYNRKUdjmzp-gjCbhHOZa_y3N9XB9IF_RWZxlgB_Dx07Aw/exec"
params = {
"mode": "extended",
"taskType": task_type,
"company": team,
"assignees": ','.join(assignees)
}
response = requests.get(web_app_url, params=params)
try:
response_data = response.json()
except ValueError:
print("ERROR: Failed to decode JSON from web app response")
return {"error": "Invalid response from Google Apps Script"}
print(f"Web App Response: {response_data}")
list_id = response_data.get("listId")
print(f"List ID: {list_id}")
assignee_ids = response_data.get("assigneeIds", [])
print(f"Assignee IDs: {assignee_ids}")
assignee_numbers = response_data.get("assigneeNumbers", [])
manager_numbers = response_data.get("managerNumbers", [])
print(f"Assignee Numbers: {assignee_numbers}")
print(f"Manager Numbers: {manager_numbers}")
# Create ClickUp task according to task type
description_text = ""
task_type_lower = task_type.lower()
if task_type_lower == "strategy":
status = "to do"
description_text = description
elif task_type_lower == "content":
status = "backlog"
description_text = f"{goal.strip()}".strip()
if platforms:
description_text += "\n\nPlatforms: " + ", ".join(platforms)
elif task_type_lower == "creative":
status = "to do"
description_text = f"{creative_type.strip()}".strip()
if platforms:
description_text += "\n\nPlatforms: " + ", ".join(platforms)
elif task_type_lower == "ads":
status = "ready"
parts = []
if ad_content:
parts.append(ad_content.strip())
if attachment_link:
parts.append(f"Attachment: {attachment_link.strip()}")
if platforms:
parts.append("Platforms: " + ", ".join(platforms))
description_text = "\n\n".join(parts)
elif task_type_lower == "posting":
status = "ready for posting"
parts = []
if posting_content:
parts.append(posting_content.strip())
if platforms:
parts.append("Platforms: " + ", ".join(platforms))
if attachment_link:
parts.append(f"Attachment: {attachment_link.strip()}")
description_text = "\n\n".join(parts)
elif task_type_lower == "ads report":
status = "ready"
platforms_text = ", ".join(platforms) if platforms else ""
description_text = f"Prepare an ads report for {platforms_text}"
if start_date and end_date:
description_text += f" from {start_date} to {end_date}"
else:
return {"error": f"Unsupported task type: {task_type}"}
# Construct ClickUp task payload
payload = {
"name": task_title,
"description": description_text,
"assignees": [int(uid) for uid in assignee_ids],
"status": status
}
# Handle due date
if deadline:
try:
due_timestamp = int(datetime.strptime(deadline, "%Y-%m-%d").timestamp() * 1000)
payload["due_date"] = due_timestamp
print(f"Due Date (timestamp): {due_timestamp}")
except ValueError:
print("Invalid deadline format. Skipping due_date.")
# Send request to ClickUp
create_url = f"{CLICKUP_URL_BASE}/list/{list_id}/task"
clickup_response = requests.post(create_url, headers=headers, json=payload)
clickup_data = clickup_response.json()
print(f"ClickUp Response: {clickup_response.status_code}, {clickup_data}")
# WhatsApp notification part is commented out for now
# We'll handle WhatsApp notification later
return {"status": "Task data received and parsed"}
# Function to get task name by task ID
def get_task_name(task_id):
"""Fetch task details from ClickUp API using task_id."""
url = f"https://api.clickup.com/api/v2/task/{task_id}"
headers = {
"Authorization": ACCESS_TOKEN
}
# Make the API request to ClickUp
response = requests.get(url, headers=headers)
# Check if the request was successful (status code 200)
if response.status_code == 200:
# Parse and return the task details
task_name = response.json()["name"]
return task_name
else:
task_name = "Task name wasn't not found"
return task_name
def get_task_details(task_id):
url = f"https://api.clickup.com/api/v2/task/{task_id}"
headers = {"Authorization": ACCESS_TOKEN}
response = requests.get(url, headers=headers)
if response.status_code == 200:
task_data = response.json()
else:
print(f"Error: {response.status_code}, {response.text}")
task_data = "invalid data"
return task_data
def send_whatsapp_notification(chat_id: str, message: str):
payload = {
"chatId": chat_id,
"message": message
}
try:
response = requests.post(WHATSAPP_URL, json=payload, headers=whatsapp_headers)
response.raise_for_status()
logging.info(f"WhatsApp sent to {chat_id} - {response.status_code}: {response.text}")
except requests.RequestException as e:
logging.error(f"WhatsApp send failed for {chat_id}: {e}")
@app.post("/updates")
async def task_update(request: Request):
data = await request.json()
logging.info(f"Received task update from ClickUp: {data}")
event_type = data.get("event")
task_id = data.get("task_id", "Unknown ID")
# Get task details
task_name = get_task_name(task_id)
task_link = f"https://app.clickup.com/t/{task_id}"
if event_type == "taskUpdated":
history_items = data.get("history_items", [])
for item in history_items:
if item.get("field") == "status":
after_status = item.get("after", {}).get("status")
action_timestamp = item.get("date", 0)
if not after_status:
logging.warning(f"Task {task_id} update ignored: No status change detected.")
continue
action_date_human = datetime.utcfromtimestamp(int(action_timestamp) / 1000).strftime('%Y-%m-%d %H:%M:%S') if action_timestamp else "Unknown Date"
logging.info(f"Task: {task_name}, New Status: {after_status}, Action Date: {action_date_human}")
if after_status.lower() == "ready for review":
chat_id = "201092003112@c.us"
message = (
f"📝 *Task Submitted for Review!*\n\n"
f"📌 *Task:* {task_name}\n"
f"📅 *Submitted On:* {action_date_human}\n\n"
f"🔗 *View Task:* {task_link}\n\n"
f"Please review the task and provide feedback."
)
send_whatsapp_notification(chat_id, message)
elif event_type == "taskTagUpdated":
history_items = data.get("history_items", [])
if history_items:
for history_item in history_items:
if "after" in history_item:
for tag in history_item["after"]:
tag_name = tag.get("name")
if tag_name and tag_name.lower() == "missed due date":
# Get due date
task_details = get_task_details(task_id) # Function to fetch task details
print(f"Task details: {task_details}")
# Extract assignee usernames
assignee_usernames = [assignee['username'] for assignee in task_details.get('assignees', [])]
print(assignee_usernames)
due_date_timestamp = task_details.get("due_date")
due_date = datetime.utcfromtimestamp(int(due_date_timestamp) / 1000).strftime('%Y-%m-%d') if due_date_timestamp else "Unknown Due Date"
logging.info(f"Missed Due Date Tag Added for Task: {task_name}, Due Date: {due_date}")
chat_id = "201092003112@c.us"
message = (
f"⚠️ *Task Missed Due Date!*\n\n"
f"📌 *Task:* {task_name}\n"
f"📅 *Due Date:* {due_date}\n\n"
f"🔗 *View Task:* {task_link}\n\n"
f"Please take action immediately."
)
send_whatsapp_notification(chat_id, message)
return {"status": "Update received"}