142 lines
5.4 KiB
Python
142 lines
5.4 KiB
Python
import requests
|
|
import json
|
|
import pprint
|
|
from flask import Flask, request
|
|
from dotenv import load_dotenv
|
|
import os
|
|
from utilfuncs import Utils
|
|
|
|
load_dotenv(override=True)
|
|
app = Flask(__name__)
|
|
pp = pprint.PrettyPrinter(indent=4)
|
|
CLIENTSEC = os.getenv("CLIENT")
|
|
SECRET = os.getenv("SECRET")
|
|
USER_ID = os.getenv("USER_ID")
|
|
SAVE_DIR = os.getenv("DIR")
|
|
BASE = "https://api.planningcenteronline.com"
|
|
LOGLEVEL = os.getenv("LOGLEVEL")
|
|
|
|
|
|
@app.route("/webhook", methods=["POST"])
|
|
def accept_webhook():
|
|
logging.info("Webhook page prepared and ready to receive webhook.")
|
|
if request.method == "POST":
|
|
logging.info("POST call received")
|
|
payload = json.loads(request.json)
|
|
logging.debug(f"***** DEBUG PAYLOAD *****\n{payload}\n************")
|
|
try:
|
|
service_date, webhook_ids = parse_payload(payload)
|
|
if service_date:
|
|
service_id, plan_id = get_my_plans(webhook_ids)
|
|
if service_id is None or plan_id is None:
|
|
pass
|
|
else:
|
|
return get_plans(service_id, plan_id, service_date)
|
|
except TypeError as e:
|
|
print(e)
|
|
finally:
|
|
return "End of app"
|
|
|
|
|
|
def parse_payload(payload):
|
|
for item in payload["data"]:
|
|
# event_type = item['attributes']['name']
|
|
webhook_ids = (
|
|
item["attributes"]["payload"]["data"]["id"],
|
|
item["attributes"]["payload"]["data"]["relationships"]["service_type"][
|
|
"data"
|
|
]["id"],
|
|
)
|
|
service_date = item["attributes"]["payload"]["data"]["attributes"]["dates"]
|
|
|
|
# Check if service date is in the future before proceeding
|
|
if not Utils.is_future_date(service_date):
|
|
logging.info(f"Service date {service_date} is in the past. Exiting.")
|
|
return f"Service date {service_date} is in the past. Exiting."
|
|
|
|
return service_date, webhook_ids
|
|
|
|
def get_my_plans(incoming_ids):
|
|
"""
|
|
This is the url for all the plans the user is part of
|
|
"""
|
|
url = f"{BASE}/services/v2/people/{USER_ID}/plan_people"
|
|
data = requests.get(url, auth=(CLIENTSEC, SECRET)).json()
|
|
plan_ids = []
|
|
for items in data["data"]:
|
|
plan_ids.append(
|
|
(
|
|
items["relationships"]["plan"]["data"]["id"],
|
|
items["relationships"]["service_type"]["data"]["id"],
|
|
)
|
|
)
|
|
# In Tuple, index 0 is the service_type_id and index 1 is the plan_id
|
|
# Service Type is a parent of the plan. Plans exist within services
|
|
if len(plan_ids) > 1:
|
|
for plan in plan_ids:
|
|
if plan == incoming_ids:
|
|
return incoming_ids[1], incoming_ids[0]
|
|
else:
|
|
return None
|
|
else:
|
|
if plan_ids[0] == incoming_ids:
|
|
return incoming_ids[1], incoming_ids[0]
|
|
else:
|
|
return None
|
|
|
|
|
|
def get_plans(service_type_id, plan_id, service_date):
|
|
filenames = []
|
|
planurl = (
|
|
f"{BASE}/services/v2/service_types/{service_type_id}/plans/{plan_id}/items"
|
|
)
|
|
reqdata = requests.get(planurl, auth=(CLIENTSEC, SECRET)).json()
|
|
for items in reqdata["data"]:
|
|
if items["attributes"]["item_type"] == "song":
|
|
item_id = items["id"]
|
|
getkey = requests.get(
|
|
f"{planurl}/{item_id}/key", auth=(CLIENTSEC, SECRET)
|
|
).json()
|
|
key = getkey["data"]["attributes"]["starting_key"]
|
|
filename = f"{items['attributes']['title']} - {key}"
|
|
filenames.append(filename)
|
|
planattachments = f"{BASE}/services/v2/service_types/{service_type_id}/plans/{plan_id}/items/{item_id}/media"
|
|
|
|
planattachments = f"{BASE}/services/v2/service_types/{service_type_id}/plans/{plan_id}/all_attachments"
|
|
plana = requests.get(planattachments, auth=(CLIENTSEC, SECRET)).json()
|
|
logging.info("Looking for attachments")
|
|
if plana["data"] == []:
|
|
logging.info(f"No attachments available for {service_date}")
|
|
else:
|
|
logging.info(f"Attachments available for {service_date}")
|
|
for attachments in plana["data"]:
|
|
if attachments["attributes"]["content_type"] == "audio/mpeg":
|
|
# attachment_id = attachments["id"]
|
|
file = attachments["attributes"]["filename"]
|
|
# close_match = Utils.find_close_matches(file, filenames)
|
|
# I know this works outside of a flask app with a specific payload, but I haven't gotten this far to test functions across all possible webhook payloads
|
|
# return get_download_url(attachment_id, close_match)
|
|
return "Next function is the get_download_url"
|
|
|
|
|
|
def get_download_url(uuid, file):
|
|
"""
|
|
Has not been fully tested yet.
|
|
To get the s3 bucket download url, this is a sample curl url:
|
|
curl -u client_sec:secret_secret -X POST https://api.planningcenteronline.com/services/v2/media/media_id/attachments/attachment_id/open
|
|
"""
|
|
downurl = f"{BASE}/services/v2/attachments/{uuid}/open"
|
|
downreq = requests.post(downurl, auth=(CLIENTSEC, SECRET))
|
|
downdata = downreq.json()
|
|
s3url = downdata["data"]["attributes"]["attachment_url"]
|
|
|
|
s3response = requests.get(s3url)
|
|
with open(f"{str(file)[2:-2]}.mp3", "wb") as f:
|
|
f.write(s3response.content)
|
|
|
|
if __name__ == "__main__":
|
|
import logging
|
|
numeric_level = getattr(logging, LOGLEVEL.upper(), None)
|
|
logging.basicConfig(filename='record.log', level=numeric_level)
|
|
app.run(host="0.0.0.0", port=8000, debug=True)
|