Mr-Help's picture
Create app.py
a051e25 verified
from fastapi import FastAPI, Request
import requests
import logging
import os, json
from datetime import datetime
from google.oauth2 import service_account
from googleapiclient.discovery import build
# Existing service account JSON dictionary
# Retrieve the secret as a string
google_credentials = os.getenv("GOOGLE_CREDENTIALS")
# Parse the secret if it's stored as a JSON string
if google_credentials:
json_api_dict = json.loads(google_credentials)
print("Valid Credentials")
else:
print("No secret found.")
app = FastAPI()
logging.basicConfig(level=logging.INFO)
# Set your credentials
CUSTOM_FIELD_ID = os.getenv("CUSTOM_FIELD_ID")
ACCESS_TOKEN = os.getenv("ACCESS_TOKEN")
def update_custom_field(task_id: str, value: str):
"""Updates the ClickUp task's custom field."""
url = f"https://api.clickup.com/api/v2/task/{task_id}/field/{CUSTOM_FIELD_ID}"
headers = {
"Authorization": ACCESS_TOKEN,
"Content-Type": "application/json"
}
payload = {"value": value} # Payload should be a dictionary
# Corrected to pass the payload correctly
response = requests.post(url, json=payload, headers=headers)
if response.status_code == 200:
print(f"Custom field updated successfully for task {task_id}")
else:
print(f"Failed to update custom field: {response.text}")
def create_drive_folder(folder_name, month):
creds = service_account.Credentials.from_service_account_info(json_api_dict)
drive_service = build('drive', 'v3', credentials=creds)
parent_folder_id = os.getenv("PARENT_FOLDER_ID")
def search_folder(name, parent_id):
query = f"name='{name}' and '{parent_id}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false"
results = drive_service.files().list(q=query, fields='files(id, name, webViewLink)').execute()
files = results.get('files', [])
return files[0] if files else None
month_folder = search_folder(month, parent_folder_id)
if not month_folder:
month_metadata = {'name': month, 'mimeType': 'application/vnd.google-apps.folder', 'parents': [parent_folder_id]}
month_folder = drive_service.files().create(body=month_metadata, fields='id, webViewLink').execute()
target_folder = search_folder(folder_name, month_folder['id'])
if target_folder:
return target_folder['webViewLink']
folder_metadata = {'name': folder_name, 'mimeType': 'application/vnd.google-apps.folder', 'parents': [month_folder['id']]}
folder = drive_service.files().create(body=folder_metadata, fields='id, webViewLink').execute()
return folder['webViewLink']
@app.post("/webhook")
async def receive_webhook(request: Request):
"""Receives ClickUp webhook events for new tasks."""
try:
# Parse the JSON payload
data = await request.json()
logging.info(f"Received webhook: {data}")
# Check if the event is 'taskCreated'
if data.get("event") == "taskCreated":
task_id = data.get("task_id") # Task ID is in the top level of the data
history_items = data.get("history_items", [])
task_name = "Unnamed Task" # Default if no name is found
creation_timestamp = None # Placeholder for creation timestamp
# Loop through history_items to find task creation and task name
for item in history_items:
if item.get("field") == "task_creation":
# Ensure 'date' is an integer before division
creation_timestamp = int(item.get("date", 0)) # Convert to int if necessary
# If we have a task_id, make an API call to get task details
if task_id:
task_name = get_task_details(task_id)
# If a creation timestamp is found, convert it to a month
if creation_timestamp:
creation_date = datetime.utcfromtimestamp(creation_timestamp / 1000) # Convert from milliseconds
creation_month = creation_date.strftime("%b %Y") # Format it as "Mon Year" (e.g., "Feb 2025")
else:
creation_month = "Unknown Month"
logging.info(f"New Task Created: {task_name} (ID: {task_id})")
logging.info(f"Task Creation Month: {creation_month}")
else:
logging.info(f"Received a different event: {data.get('event')}")
except Exception as e:
logging.error(f"Error processing webhook: {e}")
# Update custom field "1- Drive Link" with a sample value
drive_link = create_drive_folder(task_name, creation_month)
update_custom_field(task_id, drive_link)
return {"status": "success"}
def get_task_details(task_id: str):
"""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