Spaces:
Runtime error
Runtime error
| import gspread | |
| import os | |
| import json | |
| from sendgrid import SendGridAPIClient | |
| import streamlit as st | |
| import pandas as pd | |
| import plotly.express as px | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| GCP_JSON_KEY = os.environ.get("GCP_JSON_KEY") | |
| SENDGRID_API_KEY = os.environ.get("SENDGRID_API_KEY") | |
| MY_EMAIL = "ashharakhlaque@gmail.com" | |
| MY_NAME = "Ashhar Akhlaque" | |
| TEMPLATE_COL_NAME = "Template" | |
| print(SENDGRID_API_KEY) | |
| sg = SendGridAPIClient(SENDGRID_API_KEY) | |
| def saveProfileDetailsInGSheet( | |
| emailPurpose, | |
| aboutYou, | |
| recipientIndustry, | |
| recipientRole, | |
| specificDetails | |
| ): | |
| client = gspread.service_account_from_dict(json.loads(GCP_JSON_KEY)) | |
| workBook = "Cold Mail Outreach - User Profiles" | |
| try: | |
| spreadsheet = client.open(workBook) | |
| except gspread.SpreadsheetNotFound: | |
| print(f"Creating new sheet: {workBook}") | |
| spreadsheet = client.create(workBook) | |
| print(f"Created new sheet: {spreadsheet.url}") | |
| spreadsheet.share( | |
| MY_EMAIL, | |
| perm_type='user', | |
| role='writer', | |
| ) | |
| sheet = spreadsheet.worksheet("Profiles & Templates") | |
| sheet.append_row([ | |
| emailPurpose, | |
| aboutYou, | |
| recipientIndustry, | |
| recipientRole, | |
| specificDetails | |
| ]) | |
| if not (emailPurpose and aboutYou): | |
| return {} | |
| return { | |
| "response": "Saved profile details in Google Sheet.", | |
| "display": { | |
| "text": f"`Saved profile details in Google Sheet` [Link]({spreadsheet.url})", | |
| "icon": "icons/completed-task.png", | |
| } | |
| } | |
| def saveTemplateInGSheet(template: str): | |
| client = gspread.service_account_from_dict(json.loads(GCP_JSON_KEY)) | |
| workBook = "Cold Mail Outreach - User Profiles" | |
| try: | |
| spreadsheet = client.open(workBook) | |
| except gspread.SpreadsheetNotFound: | |
| print(f"Sheet not found: {workBook}") | |
| return { | |
| "response": "Failed to save template. Sheet not found.", | |
| "display": { | |
| "text": "`Failed to save template. Sheet not found.`", | |
| "icon": "icons/error.png", | |
| } | |
| } | |
| sheet = spreadsheet.worksheet("Profiles & Templates") | |
| headers = sheet.row_values(1) | |
| templateColIndex = headers.index(TEMPLATE_COL_NAME) + 1 | |
| lastRow = len([row for row in sheet.get_all_values() if any(row)]) | |
| sheet.update_cell(lastRow, templateColIndex, template) | |
| return { | |
| "response": "Saved template in Google Sheet.", | |
| "display": { | |
| "text": f"`Saved template in Google Sheet` [Link]({spreadsheet.url})", | |
| "icon": "icons/completed-task.png", | |
| } | |
| } | |
| def sendEmail( | |
| toEmail: str, | |
| subject: str, | |
| htmlContent: str | |
| ): | |
| data = { | |
| "personalizations": [{ | |
| "to": [ | |
| { | |
| "email": toEmail, | |
| } | |
| ], | |
| "subject": subject | |
| }], | |
| "from": { | |
| "email": MY_EMAIL, | |
| "name": MY_NAME | |
| }, | |
| "reply_to": { | |
| "email": MY_EMAIL, | |
| "name": MY_NAME | |
| }, | |
| "content": [{ | |
| "type": "text/html", | |
| "value": htmlContent | |
| }] | |
| } | |
| try: | |
| response = sg.client.mail.send.post(request_body=data) | |
| print(f"{response.status_code=}") | |
| st.session_state["emailSent"] = True | |
| return { | |
| "response": "Email sent", | |
| "display": { | |
| "text": f"`Email sent to {toEmail}`", | |
| "icon": "icons/mail.png", | |
| } | |
| } | |
| except Exception as e: | |
| print(e.message) | |
| return { | |
| "response": f"Failed to send email. Error: {e.message}", | |
| "display": { | |
| "text": f"`Failed to send email to {toEmail}`", | |
| "icon": "icons/error.png", | |
| } | |
| } | |
| toolsInfo = { | |
| "saveProfileDetailsInGSheet": { | |
| "func": saveProfileDetailsInGSheet, | |
| "schema": { | |
| "type": "function", | |
| "function": { | |
| "name": "saveProfileDetailsInGSheet", | |
| "description": "Saves the email profile details in Google Sheet", | |
| "parameters": { | |
| "type": "object", | |
| "properties": { | |
| "emailPurpose": { | |
| "type": "string", | |
| "description": "Purpose of the email" | |
| }, | |
| "aboutYou": { | |
| "type": "string", | |
| "description": "A bit about you that's required for email content" | |
| }, | |
| "recipientIndustry": { | |
| "type": "string", | |
| "description": "Industry of the recipient" | |
| }, | |
| "recipientRole": { | |
| "type": "string", | |
| "description": "Recipient's role in the company" | |
| }, | |
| "specificDetails": { | |
| "type": "string", | |
| "description": "Any specific details about the email" | |
| } | |
| }, | |
| "required": ["emailPurpose", "aboutYou", "recipientIndustry"] | |
| } | |
| } | |
| }, | |
| }, | |
| "saveTemplateInGSheet": { | |
| "func": saveTemplateInGSheet, | |
| "schema": { | |
| "type": "function", | |
| "function": { | |
| "name": "saveTemplateInGSheet", | |
| "description": "Saves the email template in Google Sheet", | |
| "parameters": { | |
| "type": "object", | |
| "properties": { | |
| "template": { | |
| "type": "string", | |
| "description": "Email template" | |
| } | |
| }, | |
| "required": ["template"] | |
| } | |
| } | |
| }, | |
| }, | |
| "sendEmail": { | |
| "func": sendEmail, | |
| "schema": { | |
| "type": "function", | |
| "function": { | |
| "name": "sendEmail", | |
| "description": "Sends an email to the user", | |
| "parameters": { | |
| "type": "object", | |
| "properties": { | |
| "toEmail": { | |
| "type": "string", | |
| "description": "Email address of the recipient" | |
| }, | |
| "subject": { | |
| "type": "string", | |
| "description": "Subject of the email" | |
| }, | |
| "htmlContent": { | |
| "type": "string", | |
| "description": "HTML content of the email" | |
| } | |
| }, | |
| "required": ["toEmail", "subject", "htmlContent"] | |
| } | |
| } | |
| }, | |
| }, | |
| } | |
| def showEmailStats(): | |
| params = {'start_date': '2024-09-07'} | |
| response = sg.client.stats.get( | |
| query_params=params | |
| ) | |
| stats = json.loads(response.body) | |
| # Convert stats to a pandas DataFrame | |
| df = pd.DataFrame([ | |
| { | |
| 'date': item['date'], | |
| **item['stats'][0]['metrics'] | |
| } for item in stats | |
| ]) | |
| df['date'] = pd.to_datetime(df['date']) | |
| # Display overall stats | |
| st.subheader("Email Campaign Overview") | |
| col1, col2, col3, col4, col5 = st.columns([1, 1, 1, 1, 4]) | |
| col1.metric("Total Sent", df['requests'].sum()) | |
| col2.metric("Delivered", df['delivered'].sum()) | |
| col3.metric("Opens", df['opens'].sum()) | |
| col4.metric("Bounces", df['bounces'].sum()) | |
| col1, col2, col3 = st.columns([3, 1, 3]) | |
| # Create line chart for key metrics | |
| figLine = px.line( | |
| df, | |
| x='date', | |
| y=['delivered', 'opens', 'unique_opens', 'bounces'], | |
| title='Key Metrics Over Time', | |
| color_discrete_map={ # Define custom colors | |
| 'delivered': 'green', | |
| 'opens': 'blue', | |
| 'unique_opens': 'purple', | |
| 'bounces': 'red' | |
| }, | |
| labels={'date': 'Date', 'value': 'Count'}, | |
| markers=True, | |
| height=400, | |
| ) | |
| figLine.update_layout( | |
| legend=dict( | |
| orientation="h", # Horizontal orientation | |
| yanchor="bottom", | |
| y=1.02, # Position above the chart | |
| xanchor="right", | |
| x=1, | |
| title=None, # Remove legend title | |
| ) | |
| ) | |
| col1.plotly_chart(figLine) | |
| # Create bar chart for email status | |
| dfStatus = df[['delivered', 'bounces', 'invalid_emails']].sum().reset_index() | |
| dfStatus.columns = ['status', 'count'] | |
| figBar = px.bar( | |
| dfStatus, | |
| x='status', | |
| y='count', | |
| title='Email Status Distribution', | |
| color='status', # Use status for color | |
| color_discrete_map={ # Define custom colors | |
| 'delivered': 'green', | |
| 'bounces': 'red', | |
| 'invalid_emails': 'orange' | |
| }, | |
| labels={'status': 'Status', 'count': 'Count'}, | |
| text='count', | |
| height=400, | |
| ) | |
| figBar.update_layout( | |
| legend=dict( | |
| orientation="h", # Horizontal orientation | |
| yanchor="bottom", | |
| y=1.02, # Position above the chart | |
| xanchor="right", | |
| x=1, | |
| title=None, # Remove legend title | |
| ) | |
| ) | |
| col3.plotly_chart(figBar) | |