File size: 11,255 Bytes
c0da355
6eacba4
 
a30d6f0
c49d4bf
a30d6f0
 
 
6eacba4
 
 
a30d6f0
65f3a4b
6eacba4
20ddaeb
 
 
6eacba4
 
 
a30d6f0
6eacba4
 
 
 
 
a30d6f0
 
 
 
 
6eacba4
 
 
 
 
 
 
 
0cb1545
231c278
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ac6026c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85306f9
dd83bd7
56257cb
 
 
 
 
 
ab59847
56257cb
 
 
 
 
 
85306f9
56257cb
85306f9
56257cb
 
85306f9
56257cb
 
ab59847
56257cb
 
 
 
 
 
63e446c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56257cb
63e446c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85306f9
231c278
 
 
 
329a73c
94362a2
 
14e5b99
 
 
 
 
94362a2
14e5b99
 
 
 
94362a2
14e5b99
 
 
 
94362a2
14e5b99
 
94362a2
9153366
 
 
 
 
 
 
 
 
 
6e19536
9153366
 
 
e7c30e5
 
 
 
 
 
 
 
 
 
 
 
329a73c
 
 
 
 
f194d83
329a73c
94362a2
0f92424
94362a2
f194d83
 
 
 
2ce55e1
 
0f92424
2ce55e1
 
 
 
 
0f92424
2ce55e1
 
 
 
 
 
e7c30e5
 
 
 
 
 
 
 
 
f194d83
 
94362a2
 
 
 
 
 
0f92424
 
 
73d930a
1ecbec5
5dfdba5
1ecbec5
 
0f92424
 
 
 
 
e7c30e5
 
 
 
 
 
 
 
 
329a73c
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
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"}