Skip to content

Instantly share code, notes, and snippets.

@why-not
Created January 14, 2025 23:23
Show Gist options
  • Save why-not/131ed6a341155e6f847fe5f137271e5b to your computer and use it in GitHub Desktop.
Save why-not/131ed6a341155e6f847fe5f137271e5b to your computer and use it in GitHub Desktop.
Access dropbox, read a folder's files, prompt AI to read it and find the task list, send it to a whatsapp acct.
"""
Monitor a Dropbox folder daily at 5 PM. For each PDF file, send its contents to OpenAI GPT-3.5
to generate a two-sentence summary/action. Collect all summaries and send them via WhatsApp.
NOTE: This example code is written in a functional style with separate functions for each step.
Fill in the auth tokens and any additional settings in the commented sections.
Dependencies you might need to install:
pip install dropbox openai PyPDF2 requests schedule
Usage:
1. Fill in the auth tokens and phone number in the comments below.
2. Run this script (python script_name.py).
3. Keep the script running, or use a process manager (like systemd, pm2, etc.) to keep it alive.
"""
import schedule
import time
import dropbox
import openai
import requests
import PyPDF2
from io import BytesIO
from datetime import datetime
# -----------------------------------------------------------------------------
# Configuration - Fill in or replace with environment variables or config files
# -----------------------------------------------------------------------------
# 1. Dropbox Auth Token:
# Generate an access token by creating a Dropbox App in the Dropbox developer console.
# Replace 'YOUR_DROPBOX_ACCESS_TOKEN' with your actual token.
DROPBOX_ACCESS_TOKEN = "YOUR_DROPBOX_ACCESS_TOKEN"
# 2. OpenAI API Key:
# Get your API key from: https://platform.openai.com/account/api-keys
# Replace 'YOUR_OPENAI_API_KEY' with your actual key.
OPENAI_API_KEY = "YOUR_OPENAI_API_KEY"
# 3. WhatsApp Messaging Setup (Twilio API or other provider):
# Example for Twilio:
# - TWILIO_ACCOUNT_SID
# - TWILIO_AUTH_TOKEN
# - TWILIO_WHATSAPP_FROM (the "From" phone number, in WhatsApp format, e.g. "whatsapp:+1234567890")
# - WHATSAPP_TO (the "To" phone number, in WhatsApp format, e.g. "whatsapp:+0987654321")
# The code below uses a generic placeholders for demonstration.
TWILIO_ACCOUNT_SID = "YOUR_TWILIO_ACCOUNT_SID"
TWILIO_AUTH_TOKEN = "YOUR_TWILIO_AUTH_TOKEN"
TWILIO_WHATSAPP_FROM = "whatsapp:+11234567890"
WHATSAPP_TO = "whatsapp:+10987654321"
# -----------------------------------------------------------------------------
# Functional steps
# -----------------------------------------------------------------------------
def get_pdf_files_from_dropbox():
"""
Returns a list of file metadata for all PDF files in the root Dropbox folder.
"""
dbx = dropbox.Dropbox(DROPBOX_ACCESS_TOKEN)
try:
response = dbx.files_list_folder("") # List files in the root folder
pdf_files = [entry for entry in response.entries if entry.name.lower().endswith(".pdf")]
return pdf_files
except Exception as e:
print(f"Error fetching files from Dropbox: {e}")
return []
def read_pdf_content(file_path):
"""
Reads a PDF file from Dropbox and returns its text content.
"""
dbx = dropbox.Dropbox(DROPBOX_ACCESS_TOKEN)
try:
_, res = dbx.files_download(file_path)
with BytesIO(res.content) as file_stream:
reader = PyPDF2.PdfReader(file_stream)
text = ""
for page in reader.pages:
text += page.extract_text() or ""
return text
except Exception as e:
print(f"Error reading PDF content from Dropbox: {e}")
return ""
def generate_prompt(pdf_text):
"""
Generates the prompt to send to OpenAI GPT-3.5 model.
"""
# The user's desired prompt structure:
# "Summarize this in one sentence, and in one extra sentence tell the action need to be taken to finish processing this:"
prompt = (
"Summarize this in one sentence, and in one extra sentence tell the action need to be taken "
"to finish processing this:\n\n" + pdf_text
)
return prompt
def call_openai_gpt_3_5(prompt):
"""
Calls the OpenAI GPT-3.5 API with the given prompt and returns the response text.
"""
openai.api_key = OPENAI_API_KEY
try:
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}],
max_tokens=150,
temperature=0.7
)
# Extract response
return response.choices[0].message.content.strip()
except Exception as e:
print(f"Error calling OpenAI GPT-3.5 API: {e}")
return "Error: Could not get summary."
def send_whatsapp_message(final_text):
"""
Sends the final text via WhatsApp using Twilio's API (as an example).
"""
url = f"https://api.twilio.com/2010-04-01/Accounts/{TWILIO_ACCOUNT_SID}/Messages.json"
data = {
"From": TWILIO_WHATSAPP_FROM,
"Body": final_text,
"To": WHATSAPP_TO
}
try:
response = requests.post(url, data=data, auth=(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN))
if response.status_code == 201 or response.status_code == 200:
print("WhatsApp message sent successfully.")
else:
print("Failed to send WhatsApp message:", response.text)
except Exception as e:
print("Error sending WhatsApp message:", e)
def process_files():
"""
Main functional pipeline:
1) Get all PDF files from Dropbox.
2) For each PDF, read its content.
3) Generate the custom prompt.
4) Call OpenAI GPT-3.5 with the prompt.
5) Collect the response.
6) Combine all responses into one output text.
7) Send that text via WhatsApp.
"""
pdf_files = get_pdf_files_from_dropbox()
summaries = []
for pdf_file in pdf_files:
pdf_text = read_pdf_content(pdf_file.path_lower)
prompt = generate_prompt(pdf_text)
response = call_openai_gpt_3_5(prompt)
summaries.append(f"*File:* {pdf_file.name}\n{response}\n")
# Combine all summaries
final_text = "Daily Dropbox PDF Summaries ({}):\n\n".format(datetime.now().strftime("%Y-%m-%d"))
final_text += "\n".join(summaries)
# Send the final text via WhatsApp
send_whatsapp_message(final_text)
# -----------------------------------------------------------------------------
# Scheduling to run daily at 5 PM
# -----------------------------------------------------------------------------
def main():
"""
Schedule the process_files function to run daily at 17:00 (5 PM).
Keep the script running.
"""
schedule.every().day.at("17:00").do(process_files)
while True:
schedule.run_pending()
time.sleep(30) # Wait a bit before checking again
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment