Base code
This commit is contained in:
117
ToBeMigrated/ai_marketing_tools/ai_backlinker/README.md
Normal file
117
ToBeMigrated/ai_marketing_tools/ai_backlinker/README.md
Normal file
@@ -0,0 +1,117 @@
|
||||
---
|
||||
|
||||
# AI Backlinking Tool
|
||||
|
||||
## Overview
|
||||
|
||||
The `ai_backlinking.py` module is part of the [AI-Writer](https://github.com/AJaySi/AI-Writer) project. It simplifies and automates the process of finding and securing backlink opportunities. Using AI, the tool performs web research, extracts contact information, and sends personalized outreach emails for guest posting opportunities, making it an essential tool for content writers, digital marketers, and solopreneurs.
|
||||
|
||||
---
|
||||
|
||||
## Key Features
|
||||
|
||||
| Feature | Description |
|
||||
|-------------------------------|-----------------------------------------------------------------------------|
|
||||
| **Automated Web Scraping** | Extract guest post opportunities, contact details, and website insights. |
|
||||
| **AI-Powered Emails** | Create personalized outreach emails tailored to target websites. |
|
||||
| **Email Automation** | Integrate with platforms like Gmail or SendGrid for streamlined communication. |
|
||||
| **Lead Management** | Track email status (sent, replied, successful) and follow up efficiently. |
|
||||
| **Batch Processing** | Handle multiple keywords and queries simultaneously. |
|
||||
| **AI-Driven Follow-Up** | Automate polite reminders if there's no response. |
|
||||
| **Reports and Analytics** | View performance metrics like email open rates and backlink success rates. |
|
||||
|
||||
---
|
||||
|
||||
## Workflow Breakdown
|
||||
|
||||
| Step | Action | Example |
|
||||
|-------------------------------|---------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------|
|
||||
| **Input Keywords** | Provide keywords for backlinking opportunities. | *E.g., "AI tools", "SEO strategies", "content marketing."* |
|
||||
| **Generate Search Queries** | Automatically create queries for search engines. | *E.g., "AI tools + 'write for us'" or "content marketing + 'submit a guest post.'"* |
|
||||
| **Web Scraping** | Collect URLs, email addresses, and content details from target websites. | Extract "editor@contentblog.com" from "https://contentblog.com/write-for-us". |
|
||||
| **Compose Outreach Emails** | Use AI to draft personalized emails based on scraped website data. | Email tailored to "Content Blog" discussing "AI tools for better content writing." |
|
||||
| **Automated Email Sending** | Review and send emails or fully automate the process. | Send emails through Gmail or other SMTP services. |
|
||||
| **Follow-Ups** | Automate follow-ups for non-responsive contacts. | A polite reminder email sent 7 days later. |
|
||||
| **Track and Log Results** | Monitor sent emails, responses, and backlink placements. | View logs showing responses and backlink acquisition rate. |
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Python Version**: 3.6 or higher.
|
||||
- **Required Packages**: `googlesearch-python`, `loguru`, `smtplib`, `email`.
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
1. Clone the repository:
|
||||
```bash
|
||||
git clone https://github.com/AJaySi/AI-Writer.git
|
||||
cd AI-Writer
|
||||
```
|
||||
|
||||
2. Install dependencies:
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example Usage
|
||||
|
||||
Here’s a quick example of how to use the tool:
|
||||
|
||||
```python
|
||||
from lib.ai_marketing_tools.ai_backlinking import main_backlinking_workflow
|
||||
|
||||
# Email configurations
|
||||
smtp_config = {
|
||||
'server': 'smtp.gmail.com',
|
||||
'port': 587,
|
||||
'user': 'your_email@gmail.com',
|
||||
'password': 'your_password'
|
||||
}
|
||||
|
||||
imap_config = {
|
||||
'server': 'imap.gmail.com',
|
||||
'user': 'your_email@gmail.com',
|
||||
'password': 'your_password'
|
||||
}
|
||||
|
||||
# Proposal details
|
||||
user_proposal = {
|
||||
'user_name': 'Your Name',
|
||||
'user_email': 'your_email@gmail.com',
|
||||
'topic': 'Proposed guest post topic'
|
||||
}
|
||||
|
||||
# Keywords to search
|
||||
keywords = ['AI tools', 'SEO strategies', 'content marketing']
|
||||
|
||||
# Start the workflow
|
||||
main_backlinking_workflow(keywords, smtp_config, imap_config, user_proposal)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Core Functions
|
||||
|
||||
| Function | Purpose |
|
||||
|--------------------------------------------|-------------------------------------------------------------------------------------------|
|
||||
| `generate_search_queries(keyword)` | Create search queries to find guest post opportunities. |
|
||||
| `find_backlink_opportunities(keyword)` | Scrape websites for backlink opportunities. |
|
||||
| `compose_personalized_email()` | Draft outreach emails using AI insights and website data. |
|
||||
| `send_email()` | Send emails using SMTP configurations. |
|
||||
| `check_email_responses()` | Monitor inbox for replies using IMAP. |
|
||||
| `send_follow_up_email()` | Automate polite reminders to non-responsive contacts. |
|
||||
| `log_sent_email()` | Keep a record of all sent emails and responses. |
|
||||
| `main_backlinking_workflow()` | Execute the complete backlinking workflow for multiple keywords. |
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License. For more details, refer to the [LICENSE](LICENSE) file.
|
||||
|
||||
---
|
||||
423
ToBeMigrated/ai_marketing_tools/ai_backlinker/ai_backlinking.py
Normal file
423
ToBeMigrated/ai_marketing_tools/ai_backlinker/ai_backlinking.py
Normal file
@@ -0,0 +1,423 @@
|
||||
#Problem:
|
||||
#
|
||||
#Finding websites for guest posts is manual, tedious, and time-consuming. Communicating with webmasters, maintaining conversations, and keeping track of backlinking opportunities is difficult to scale. Content creators and marketers struggle with discovering new websites and consistently getting backlinks.
|
||||
#Solution:
|
||||
#
|
||||
#An AI-powered backlinking app that automates web research, scrapes websites, extracts contact information, and sends personalized outreach emails to webmasters. This would simplify the entire process, allowing marketers to scale their backlinking strategy with minimal manual intervention.
|
||||
#Core Workflow:
|
||||
#
|
||||
# User Input:
|
||||
# Keyword Search: The user inputs a keyword (e.g., "AI writers").
|
||||
# Search Queries: Your app will append various search strings to this keyword to find backlinking opportunities (e.g., "AI writers + 'Write for Us'").
|
||||
#
|
||||
# Web Research:
|
||||
#
|
||||
# Use search engines or web scraping to run multiple queries:
|
||||
# Keyword + "Guest Contributor"
|
||||
# Keyword + "Add Guest Post"
|
||||
# Keyword + "Write for Us", etc.
|
||||
#
|
||||
# Collect URLs of websites that have pages or posts related to guest post opportunities.
|
||||
#
|
||||
# Scrape Website Data:
|
||||
# Contact Information Extraction:
|
||||
# Scrape the website for contact details (email addresses, contact forms, etc.).
|
||||
# Use natural language processing (NLP) to understand the type of content on the website and who the contact person might be (webmaster, editor, or guest post manager).
|
||||
# Website Content Understanding:
|
||||
# Scrape a summary of each website's content (e.g., their blog topics, categories, and tone) to personalize the email based on the site's focus.
|
||||
#
|
||||
# Personalized Outreach:
|
||||
# AI Email Composition:
|
||||
# Compose personalized outreach emails based on:
|
||||
# The scraped data (website content, topic focus, etc.).
|
||||
# The user's input (what kind of guest post or content they want to contribute).
|
||||
# Example: "Hi [Webmaster Name], I noticed that your site [Site Name] features high-quality content about [Topic]. I would love to contribute a guest post on [Proposed Topic] in exchange for a backlink."
|
||||
#
|
||||
# Automated Email Sending:
|
||||
# Review Emails (Optional HITL):
|
||||
# Let users review and approve the personalized emails before they are sent, or allow full automation.
|
||||
# Send Emails:
|
||||
# Automate email dispatch through an integrated SMTP or API (e.g., Gmail API, SendGrid).
|
||||
# Keep track of which emails were sent, bounced, or received replies.
|
||||
#
|
||||
# Scaling the Search:
|
||||
# Repeat for Multiple Keywords:
|
||||
# Run the same scraping and outreach process for a list of relevant keywords, either automatically suggested or uploaded by the user.
|
||||
# Keep Track of Sent Emails:
|
||||
# Maintain a log of all sent emails, responses, and follow-up reminders to avoid repetition or forgotten leads.
|
||||
#
|
||||
# Tracking Responses and Follow-ups:
|
||||
# Automated Responses:
|
||||
# If a website replies positively, AI can respond with predefined follow-up emails (e.g., proposing topics, confirming submission deadlines).
|
||||
# Follow-up Reminders:
|
||||
# If there's no reply, the system can send polite follow-up reminders at pre-set intervals.
|
||||
#
|
||||
#Key Features:
|
||||
#
|
||||
# Automated Web Scraping:
|
||||
# Scrape websites for guest post opportunities using a predefined set of search queries based on user input.
|
||||
# Extract key information like email addresses, names, and submission guidelines.
|
||||
#
|
||||
# Personalized Email Writing:
|
||||
# Leverage AI to create personalized emails using the scraped website information.
|
||||
# Tailor each email to the tone, content style, and focus of the website.
|
||||
#
|
||||
# Email Sending Automation:
|
||||
# Integrate with email platforms (e.g., Gmail, SendGrid, or custom SMTP).
|
||||
# Send automated outreach emails with the ability for users to review first (HITL - Human-in-the-loop) or automate completely.
|
||||
#
|
||||
# Customizable Email Templates:
|
||||
# Allow users to customize or choose from a set of email templates for different types of outreach (e.g., guest post requests, follow-up emails, submission offers).
|
||||
#
|
||||
# Lead Tracking and Management:
|
||||
# Track all emails sent, monitor replies, and keep track of successful backlinks.
|
||||
# Log each lead's status (e.g., emailed, responded, no reply) to manage future interactions.
|
||||
#
|
||||
# Multiple Keywords/Queries:
|
||||
# Allow users to run the same process for a batch of keywords, automatically generating relevant search queries for each.
|
||||
#
|
||||
# AI-Driven Follow-Up:
|
||||
# Schedule follow-up emails if there is no response after a specified period.
|
||||
#
|
||||
# Reports and Analytics:
|
||||
# Provide users with reports on how many emails were sent, opened, replied to, and successful backlink placements.
|
||||
#
|
||||
#Advanced Features (for Scaling and Optimization):
|
||||
#
|
||||
# Domain Authority Filtering:
|
||||
# Use SEO APIs (e.g., Moz, Ahrefs) to filter websites based on their domain authority or backlink strength.
|
||||
# Prioritize high-authority websites to maximize the impact of backlinks.
|
||||
#
|
||||
# Spam Detection:
|
||||
# Use AI to detect and avoid spammy or low-quality websites that might harm the user's SEO.
|
||||
#
|
||||
# Contact Form Auto-Fill:
|
||||
# If the site only offers a contact form (without email), automatically fill and submit the form with AI-generated content.
|
||||
#
|
||||
# Dynamic Content Suggestions:
|
||||
# Suggest guest post topics based on the website's focus, using NLP to analyze the site's existing content.
|
||||
#
|
||||
# Bulk Email Support:
|
||||
# Allow users to bulk-send outreach emails while still personalizing each message for scalability.
|
||||
#
|
||||
# AI Copy Optimization:
|
||||
# Use copywriting AI to optimize email content, adjusting tone and CTA based on the target audience.
|
||||
#
|
||||
#Challenges and Considerations:
|
||||
#
|
||||
# Legal Compliance:
|
||||
# Ensure compliance with anti-spam laws (e.g., CAN-SPAM, GDPR) by including unsubscribe options or manual email approval.
|
||||
#
|
||||
# Scraping Limits:
|
||||
# Be mindful of scraping limits on certain websites and employ smart throttling or use API-based scraping for better reliability.
|
||||
#
|
||||
# Deliverability:
|
||||
# Ensure emails are delivered properly without landing in spam folders by integrating proper email authentication (SPF, DKIM) and using high-reputation SMTP servers.
|
||||
#
|
||||
# Maintaining Email Personalization:
|
||||
# Striking the balance between automating the email process and keeping each message personal enough to avoid being flagged as spam.
|
||||
#
|
||||
#Technology Stack:
|
||||
#
|
||||
# Web Scraping: BeautifulSoup, Scrapy, or Puppeteer for scraping guest post opportunities and contact information.
|
||||
# Email Automation: Integrate with Gmail API, SendGrid, or Mailgun for sending emails.
|
||||
# NLP for Personalization: GPT-based models for email generation and web content understanding.
|
||||
# Frontend: React or Vue for the user interface.
|
||||
# Backend: Python/Node.js with Flask or Express for the API and automation logic.
|
||||
# Database: MongoDB or PostgreSQL to track leads, emails, and responses.
|
||||
#
|
||||
#This solution will significantly streamline the backlinking process by automating the most tedious tasks, from finding sites to personalizing outreach, enabling marketers to focus on content creation and high-level strategies.
|
||||
|
||||
|
||||
import sys
|
||||
# from googlesearch import search # Temporarily disabled for future enhancement
|
||||
from loguru import logger
|
||||
from lib.ai_web_researcher.firecrawl_web_crawler import scrape_website
|
||||
from lib.gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
from lib.ai_web_researcher.firecrawl_web_crawler import scrape_url
|
||||
import smtplib
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
|
||||
# Configure logger
|
||||
logger.remove()
|
||||
logger.add(sys.stdout,
|
||||
colorize=True,
|
||||
format="<level>{level}</level>|<green>{file}:{line}:{function}</green>| {message}"
|
||||
)
|
||||
|
||||
def generate_search_queries(keyword):
|
||||
"""
|
||||
Generate a list of search queries for finding guest post opportunities.
|
||||
|
||||
Args:
|
||||
keyword (str): The keyword to base the search queries on.
|
||||
|
||||
Returns:
|
||||
list: A list of search queries.
|
||||
"""
|
||||
return [
|
||||
f"{keyword} + 'Guest Contributor'",
|
||||
f"{keyword} + 'Add Guest Post'",
|
||||
f"{keyword} + 'Guest Bloggers Wanted'",
|
||||
f"{keyword} + 'Write for Us'",
|
||||
f"{keyword} + 'Submit Guest Post'",
|
||||
f"{keyword} + 'Become a Guest Blogger'",
|
||||
f"{keyword} + 'guest post opportunities'",
|
||||
f"{keyword} + 'Submit article'",
|
||||
]
|
||||
|
||||
def find_backlink_opportunities(keyword):
|
||||
"""
|
||||
Find backlink opportunities by scraping websites based on search queries.
|
||||
|
||||
Args:
|
||||
keyword (str): The keyword to search for backlink opportunities.
|
||||
|
||||
Returns:
|
||||
list: A list of results from the scraped websites.
|
||||
"""
|
||||
search_queries = generate_search_queries(keyword)
|
||||
results = []
|
||||
|
||||
# Temporarily disabled Google search functionality
|
||||
# for query in search_queries:
|
||||
# urls = search_for_urls(query)
|
||||
# for url in urls:
|
||||
# website_data = scrape_website(url)
|
||||
# logger.info(f"Scraped Website content for {url}: {website_data}")
|
||||
# if website_data:
|
||||
# contact_info = extract_contact_info(website_data)
|
||||
# logger.info(f"Contact details found for {url}: {contact_info}")
|
||||
|
||||
# Placeholder return for now
|
||||
return []
|
||||
|
||||
def search_for_urls(query):
|
||||
"""
|
||||
Search for URLs using Google search.
|
||||
|
||||
Args:
|
||||
query (str): The search query.
|
||||
|
||||
Returns:
|
||||
list: List of URLs found.
|
||||
"""
|
||||
# Temporarily disabled Google search functionality
|
||||
# return list(search(query, num_results=10))
|
||||
return []
|
||||
|
||||
def compose_personalized_email(website_data, insights, user_proposal):
|
||||
"""
|
||||
Compose a personalized outreach email using AI LLM based on website data, insights, and user proposal.
|
||||
|
||||
Args:
|
||||
website_data (dict): The data of the website including metadata and contact info.
|
||||
insights (str): Insights generated by the LLM about the website.
|
||||
user_proposal (dict): The user's proposal for a guest post or content contribution.
|
||||
|
||||
Returns:
|
||||
str: A personalized email message.
|
||||
"""
|
||||
contact_name = website_data.get("contact_info", {}).get("name", "Webmaster")
|
||||
site_name = website_data.get("metadata", {}).get("title", "your site")
|
||||
proposed_topic = user_proposal.get("topic", "a guest post")
|
||||
user_name = user_proposal.get("user_name", "Your Name")
|
||||
user_email = user_proposal.get("user_email", "your_email@example.com")
|
||||
|
||||
# Refined prompt for email generation
|
||||
email_prompt = f"""
|
||||
You are an AI assistant tasked with composing a highly personalized outreach email for guest posting.
|
||||
|
||||
Contact Name: {contact_name}
|
||||
Website Name: {site_name}
|
||||
Proposed Topic: {proposed_topic}
|
||||
|
||||
User Details:
|
||||
Name: {user_name}
|
||||
Email: {user_email}
|
||||
|
||||
Website Insights: {insights}
|
||||
|
||||
Please compose a professional and engaging email that includes:
|
||||
1. A personalized introduction addressing the recipient.
|
||||
2. A mention of the website's content focus.
|
||||
3. A proposal for a guest post.
|
||||
4. A call to action to discuss the guest post opportunity.
|
||||
5. A polite closing with user contact details.
|
||||
"""
|
||||
|
||||
return llm_text_gen(email_prompt)
|
||||
|
||||
def send_email(smtp_server, smtp_port, smtp_user, smtp_password, to_email, subject, body):
|
||||
"""
|
||||
Send an email using an SMTP server.
|
||||
|
||||
Args:
|
||||
smtp_server (str): The SMTP server address.
|
||||
smtp_port (int): The SMTP server port.
|
||||
smtp_user (str): The SMTP server username.
|
||||
smtp_password (str): The SMTP server password.
|
||||
to_email (str): The recipient's email address.
|
||||
subject (str): The email subject.
|
||||
body (str): The email body.
|
||||
|
||||
Returns:
|
||||
bool: True if the email was sent successfully, False otherwise.
|
||||
"""
|
||||
try:
|
||||
msg = MIMEMultipart()
|
||||
msg['From'] = smtp_user
|
||||
msg['To'] = to_email
|
||||
msg['Subject'] = subject
|
||||
msg.attach(MIMEText(body, 'plain'))
|
||||
|
||||
server = smtplib.SMTP(smtp_server, smtp_port)
|
||||
server.starttls()
|
||||
server.login(smtp_user, smtp_password)
|
||||
server.send_message(msg)
|
||||
server.quit()
|
||||
|
||||
logger.info(f"Email sent successfully to {to_email}")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to send email to {to_email}: {e}")
|
||||
return False
|
||||
|
||||
def extract_contact_info(website_data):
|
||||
"""
|
||||
Extract contact information from website data.
|
||||
|
||||
Args:
|
||||
website_data (dict): Scraped data from the website.
|
||||
|
||||
Returns:
|
||||
dict: Extracted contact information such as name, email, etc.
|
||||
"""
|
||||
# Placeholder for extracting contact information logic
|
||||
return {
|
||||
"name": website_data.get("contact", {}).get("name", "Webmaster"),
|
||||
"email": website_data.get("contact", {}).get("email", ""),
|
||||
}
|
||||
|
||||
def find_backlink_opportunities_for_keywords(keywords):
|
||||
"""
|
||||
Find backlink opportunities for multiple keywords.
|
||||
|
||||
Args:
|
||||
keywords (list): A list of keywords to search for backlink opportunities.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary with keywords as keys and a list of results as values.
|
||||
"""
|
||||
all_results = {}
|
||||
for keyword in keywords:
|
||||
results = find_backlink_opportunities(keyword)
|
||||
all_results[keyword] = results
|
||||
return all_results
|
||||
|
||||
def log_sent_email(keyword, email_info):
|
||||
"""
|
||||
Log the information of a sent email.
|
||||
|
||||
Args:
|
||||
keyword (str): The keyword associated with the email.
|
||||
email_info (dict): Information about the sent email (e.g., recipient, subject, body).
|
||||
"""
|
||||
with open(f"{keyword}_sent_emails.log", "a") as log_file:
|
||||
log_file.write(f"{email_info}\n")
|
||||
|
||||
def check_email_responses(imap_server, imap_user, imap_password):
|
||||
"""
|
||||
Check email responses using an IMAP server.
|
||||
|
||||
Args:
|
||||
imap_server (str): The IMAP server address.
|
||||
imap_user (str): The IMAP server username.
|
||||
imap_password (str): The IMAP server password.
|
||||
|
||||
Returns:
|
||||
list: A list of email responses.
|
||||
"""
|
||||
responses = []
|
||||
try:
|
||||
mail = imaplib.IMAP4_SSL(imap_server)
|
||||
mail.login(imap_user, imap_password)
|
||||
mail.select('inbox')
|
||||
|
||||
status, data = mail.search(None, 'UNSEEN')
|
||||
mail_ids = data[0]
|
||||
id_list = mail_ids.split()
|
||||
|
||||
for mail_id in id_list:
|
||||
status, data = mail.fetch(mail_id, '(RFC822)')
|
||||
msg = email.message_from_bytes(data[0][1])
|
||||
if msg.is_multipart():
|
||||
for part in msg.walk():
|
||||
if part.get_content_type() == 'text/plain':
|
||||
responses.append(part.get_payload(decode=True).decode())
|
||||
else:
|
||||
responses.append(msg.get_payload(decode=True).decode())
|
||||
|
||||
mail.logout()
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to check email responses: {e}")
|
||||
|
||||
return responses
|
||||
|
||||
def send_follow_up_email(smtp_server, smtp_port, smtp_user, smtp_password, to_email, subject, body):
|
||||
"""
|
||||
Send a follow-up email using an SMTP server.
|
||||
|
||||
Args:
|
||||
smtp_server (str): The SMTP server address.
|
||||
smtp_port (int): The SMTP server port.
|
||||
smtp_user (str): The SMTP server username.
|
||||
smtp_password (str): The SMTP server password.
|
||||
to_email (str): The recipient's email address.
|
||||
subject (str): The email subject.
|
||||
body (str): The email body.
|
||||
|
||||
Returns:
|
||||
bool: True if the email was sent successfully, False otherwise.
|
||||
"""
|
||||
return send_email(smtp_server, smtp_port, smtp_user, smtp_password, to_email, subject, body)
|
||||
|
||||
def main_backlinking_workflow(keywords, smtp_config, imap_config, user_proposal):
|
||||
"""
|
||||
Main workflow for the AI-powered backlinking feature.
|
||||
|
||||
Args:
|
||||
keywords (list): A list of keywords to search for backlink opportunities.
|
||||
smtp_config (dict): SMTP configuration for sending emails.
|
||||
imap_config (dict): IMAP configuration for checking email responses.
|
||||
user_proposal (dict): The user's proposal for a guest post or content contribution.
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
all_results = find_backlink_opportunities_for_keywords(keywords)
|
||||
|
||||
for keyword, results in all_results.items():
|
||||
for result in results:
|
||||
email_body = compose_personalized_email(result, result['insights'], user_proposal)
|
||||
email_sent = send_email(
|
||||
smtp_config['server'],
|
||||
smtp_config['port'],
|
||||
smtp_config['user'],
|
||||
smtp_config['password'],
|
||||
result['contact_info']['email'],
|
||||
f"Guest Post Proposal for {result['metadata']['title']}",
|
||||
email_body
|
||||
)
|
||||
if email_sent:
|
||||
log_sent_email(keyword, {
|
||||
"to": result['contact_info']['email'],
|
||||
"subject": f"Guest Post Proposal for {result['metadata']['title']}",
|
||||
"body": email_body
|
||||
})
|
||||
|
||||
responses = check_email_responses(imap_config['server'], imap_config['user'], imap_config['password'])
|
||||
for response in responses:
|
||||
# TBD : Process and possibly send follow-up emails based on responses
|
||||
pass
|
||||
@@ -0,0 +1,60 @@
|
||||
import streamlit as st
|
||||
import pandas as pd
|
||||
from st_aggrid import AgGrid, GridOptionsBuilder, GridUpdateMode
|
||||
from lib.ai_marketing_tools.ai_backlinker.ai_backlinking import find_backlink_opportunities, compose_personalized_email
|
||||
|
||||
|
||||
# Streamlit UI function
|
||||
def backlinking_ui():
|
||||
st.title("AI Backlinking Tool")
|
||||
|
||||
# Step 1: Get user inputs
|
||||
keyword = st.text_input("Enter a keyword", value="technology")
|
||||
|
||||
# Step 2: Generate backlink opportunities
|
||||
if st.button("Find Backlink Opportunities"):
|
||||
if keyword:
|
||||
backlink_opportunities = find_backlink_opportunities(keyword)
|
||||
|
||||
# Convert results to a DataFrame for display
|
||||
df = pd.DataFrame(backlink_opportunities)
|
||||
|
||||
# Create a selectable table using st-aggrid
|
||||
gb = GridOptionsBuilder.from_dataframe(df)
|
||||
gb.configure_selection('multiple', use_checkbox=True, groupSelectsChildren=True)
|
||||
gridOptions = gb.build()
|
||||
|
||||
grid_response = AgGrid(
|
||||
df,
|
||||
gridOptions=gridOptions,
|
||||
update_mode=GridUpdateMode.SELECTION_CHANGED,
|
||||
height=200,
|
||||
width='100%'
|
||||
)
|
||||
|
||||
selected_rows = grid_response['selected_rows']
|
||||
|
||||
if selected_rows:
|
||||
st.write("Selected Opportunities:")
|
||||
st.table(pd.DataFrame(selected_rows))
|
||||
|
||||
# Step 3: Option to generate personalized emails for selected opportunities
|
||||
if st.button("Generate Emails for Selected Opportunities"):
|
||||
user_proposal = {
|
||||
"user_name": st.text_input("Your Name", value="John Doe"),
|
||||
"user_email": st.text_input("Your Email", value="john@example.com")
|
||||
}
|
||||
|
||||
emails = []
|
||||
for selected in selected_rows:
|
||||
insights = f"Insights based on content from {selected['url']}."
|
||||
email = compose_personalized_email(selected, insights, user_proposal)
|
||||
emails.append(email)
|
||||
|
||||
st.subheader("Generated Emails:")
|
||||
for email in emails:
|
||||
st.write(email)
|
||||
st.markdown("---")
|
||||
|
||||
else:
|
||||
st.error("Please enter a keyword.")
|
||||
@@ -0,0 +1,370 @@
|
||||
Google Ads Generator
|
||||
Google Ads Generator Logo
|
||||
|
||||
Overview
|
||||
The Google Ads Generator is an AI-powered tool designed to create high-converting Google Ads based on industry best practices. This tool helps marketers, business owners, and advertising professionals create optimized ad campaigns that maximize ROI and conversion rates.
|
||||
|
||||
By leveraging advanced AI algorithms and proven advertising frameworks, the Google Ads Generator creates compelling ad copy, suggests optimal keywords, generates relevant extensions, and provides performance predictions—all tailored to your specific business needs and target audience.
|
||||
|
||||
Table of Contents
|
||||
Features
|
||||
Getting Started
|
||||
User Interface
|
||||
Ad Creation Process
|
||||
Ad Types
|
||||
Quality Analysis
|
||||
Performance Simulation
|
||||
Best Practices
|
||||
Export Options
|
||||
Advanced Features
|
||||
Technical Details
|
||||
FAQ
|
||||
Troubleshooting
|
||||
Updates and Roadmap
|
||||
Features
|
||||
Core Features
|
||||
AI-Powered Ad Generation: Create compelling, high-converting Google Ads in seconds
|
||||
Multiple Ad Types: Support for Responsive Search Ads, Expanded Text Ads, Call-Only Ads, and Dynamic Search Ads
|
||||
Industry-Specific Templates: Tailored templates for 20+ industries
|
||||
Ad Extensions Generator: Automatically create Sitelinks, Callouts, and Structured Snippets
|
||||
Quality Score Analysis: Comprehensive scoring based on Google's quality factors
|
||||
Performance Prediction: Estimate CTR, conversion rates, and ROI
|
||||
A/B Testing: Generate multiple variations for testing
|
||||
Export Options: Export to CSV, Excel, Google Ads Editor CSV, and JSON
|
||||
Advanced Features
|
||||
Keyword Research Integration: Find high-performing keywords for your ads
|
||||
Competitor Analysis: Analyze competitor ads and identify opportunities
|
||||
Landing Page Suggestions: Recommendations for landing page optimization
|
||||
Budget Optimization: Suggestions for optimal budget allocation
|
||||
Ad Schedule Recommendations: Identify the best times to run your ads
|
||||
Audience Targeting Suggestions: Recommendations for demographic targeting
|
||||
Local Ad Optimization: Special features for local businesses
|
||||
E-commerce Ad Features: Product-specific ad generation
|
||||
Getting Started
|
||||
Prerequisites
|
||||
Alwrity AI Writer platform
|
||||
Basic understanding of Google Ads concepts
|
||||
Information about your business, products/services, and target audience
|
||||
Accessing the Tool
|
||||
Navigate to the Alwrity AI Writer platform
|
||||
Select "AI Google Ads Generator" from the tools menu
|
||||
Follow the guided setup process
|
||||
User Interface
|
||||
The Google Ads Generator features a user-friendly, tabbed interface designed to guide you through the ad creation process:
|
||||
|
||||
Tab 1: Ad Creation
|
||||
This is where you'll input your business information and ad requirements:
|
||||
|
||||
Business Information: Company name, industry, products/services
|
||||
Campaign Goals: Select from options like brand awareness, lead generation, sales, etc.
|
||||
Target Audience: Define your ideal customer
|
||||
Ad Type Selection: Choose from available ad formats
|
||||
USP and Benefits: Input your unique selling propositions and key benefits
|
||||
Keywords: Add target keywords or generate suggestions
|
||||
Landing Page URL: Specify where users will go after clicking your ad
|
||||
Budget Information: Set daily/monthly budget for performance predictions
|
||||
Tab 2: Ad Performance
|
||||
After generating ads, this tab provides detailed analysis:
|
||||
|
||||
Quality Score: Overall score (1-10) with detailed breakdown
|
||||
Strengths & Improvements: What's good and what could be better
|
||||
Keyword Relevance: Analysis of keyword usage in ad elements
|
||||
CTR Prediction: Estimated click-through rate based on ad quality
|
||||
Conversion Potential: Estimated conversion rate
|
||||
Mobile Friendliness: Assessment of how well the ad performs on mobile
|
||||
Ad Policy Compliance: Check for potential policy violations
|
||||
Tab 3: Ad History
|
||||
Keep track of your generated ads:
|
||||
|
||||
Saved Ads: Previously generated and saved ads
|
||||
Favorites: Ads you've marked as favorites
|
||||
Version History: Track changes and iterations
|
||||
Performance Notes: Add notes about real-world performance
|
||||
Tab 4: Best Practices
|
||||
Educational resources to improve your ads:
|
||||
|
||||
Industry Guidelines: Best practices for your specific industry
|
||||
Ad Type Tips: Specific guidance for each ad type
|
||||
Quality Score Optimization: How to improve quality score
|
||||
Extension Strategies: How to effectively use ad extensions
|
||||
A/B Testing Guide: How to test and optimize your ads
|
||||
Ad Creation Process
|
||||
Step 1: Define Your Campaign
|
||||
Select your industry from the dropdown menu
|
||||
Choose your primary campaign goal
|
||||
Define your target audience
|
||||
Set your budget parameters
|
||||
Step 2: Input Business Details
|
||||
Enter your business name
|
||||
Provide your website URL
|
||||
Input your unique selling propositions
|
||||
List key product/service benefits
|
||||
Add any promotional offers or discounts
|
||||
Step 3: Keyword Selection
|
||||
Enter your primary keywords
|
||||
Use the integrated keyword research tool to find additional keywords
|
||||
Select keyword match types (broad, phrase, exact)
|
||||
Review keyword competition and volume metrics
|
||||
Step 4: Ad Type Selection
|
||||
Choose your preferred ad type
|
||||
Review the requirements and limitations for that ad type
|
||||
Select any additional features specific to that ad type
|
||||
Step 5: Generate Ads
|
||||
Click the "Generate Ads" button
|
||||
Review the generated ads
|
||||
Request variations if needed
|
||||
Save your favorite versions
|
||||
Step 6: Add Extensions
|
||||
Select which extension types to include
|
||||
Review and edit the generated extensions
|
||||
Add any custom extensions
|
||||
Step 7: Analyze and Optimize
|
||||
Review the quality score and analysis
|
||||
Make suggested improvements
|
||||
Regenerate ads if necessary
|
||||
Compare different versions
|
||||
Step 8: Export
|
||||
Choose your preferred export format
|
||||
Select which ads to include
|
||||
Download the file for import into Google Ads
|
||||
Ad Types
|
||||
Responsive Search Ads (RSA)
|
||||
The most flexible and recommended ad type, featuring:
|
||||
|
||||
Up to 15 headlines (3 shown at a time)
|
||||
Up to 4 descriptions (2 shown at a time)
|
||||
Dynamic combination of elements based on performance
|
||||
Automatic testing of different combinations
|
||||
Expanded Text Ads (ETA)
|
||||
A more controlled ad format with:
|
||||
|
||||
3 headlines
|
||||
2 descriptions
|
||||
Display URL with two path fields
|
||||
Fixed layout with no dynamic combinations
|
||||
Call-Only Ads
|
||||
Designed to drive phone calls rather than website visits:
|
||||
|
||||
Business name
|
||||
Phone number
|
||||
Call-to-action text
|
||||
Description lines
|
||||
Verification URL (not shown to users)
|
||||
Dynamic Search Ads (DSA)
|
||||
Ads that use your website content to target relevant searches:
|
||||
|
||||
Dynamic headline generation based on search queries
|
||||
Custom descriptions
|
||||
Landing page selection based on website content
|
||||
Requires website URL for crawling
|
||||
Quality Analysis
|
||||
Our comprehensive quality analysis evaluates your ads based on factors that influence Google's Quality Score:
|
||||
|
||||
Headline Analysis
|
||||
Keyword Usage: Presence of keywords in headlines
|
||||
Character Count: Optimal length for visibility
|
||||
Power Words: Use of emotionally compelling words
|
||||
Clarity: Clear communication of value proposition
|
||||
Call to Action: Presence of action-oriented language
|
||||
Description Analysis
|
||||
Keyword Density: Optimal keyword usage
|
||||
Benefit Focus: Clear articulation of benefits
|
||||
Feature Inclusion: Mention of key features
|
||||
Urgency Elements: Time-limited offers or scarcity
|
||||
Call to Action: Clear next steps for the user
|
||||
URL Path Analysis
|
||||
Keyword Inclusion: Relevant keywords in display paths
|
||||
Readability: Clear, understandable paths
|
||||
Relevance: Connection to landing page content
|
||||
Overall Ad Relevance
|
||||
Keyword-to-Ad Relevance: Alignment between keywords and ad copy
|
||||
Ad-to-Landing Page Relevance: Consistency across the user journey
|
||||
Intent Match: Alignment with search intent
|
||||
Performance Simulation
|
||||
Our tool provides data-driven performance predictions based on:
|
||||
|
||||
Click-Through Rate (CTR) Prediction
|
||||
Industry benchmarks
|
||||
Ad quality factors
|
||||
Keyword competition
|
||||
Ad position estimates
|
||||
Conversion Rate Prediction
|
||||
Industry averages
|
||||
Landing page quality
|
||||
Offer strength
|
||||
Call-to-action effectiveness
|
||||
Cost Estimation
|
||||
Keyword competition
|
||||
Quality Score impact
|
||||
Industry CPC averages
|
||||
Budget allocation
|
||||
ROI Calculation
|
||||
Estimated clicks
|
||||
Predicted conversions
|
||||
Average conversion value
|
||||
Cost projections
|
||||
Best Practices
|
||||
Our tool incorporates these Google Ads best practices:
|
||||
|
||||
Headline Best Practices
|
||||
Include primary keywords in at least 2 headlines
|
||||
Use numbers and statistics when relevant
|
||||
Address user pain points directly
|
||||
Include your unique selling proposition
|
||||
Create a sense of urgency when appropriate
|
||||
Keep headlines under 30 characters for full visibility
|
||||
Use title case for better readability
|
||||
Include at least one call-to-action headline
|
||||
Description Best Practices
|
||||
Include primary and secondary keywords naturally
|
||||
Focus on benefits, not just features
|
||||
Address objections proactively
|
||||
Include specific offers or promotions
|
||||
End with a clear call to action
|
||||
Use all available character space (90 characters per description)
|
||||
Maintain consistent messaging with headlines
|
||||
Include trust signals (guarantees, social proof, etc.)
|
||||
Extension Best Practices
|
||||
Create at least 8 sitelinks for maximum visibility
|
||||
Use callouts to highlight additional benefits
|
||||
Include structured snippets relevant to your industry
|
||||
Ensure extensions don't duplicate headline content
|
||||
Make each extension unique and valuable
|
||||
Use specific, action-oriented language
|
||||
Keep sitelink text under 25 characters for mobile visibility
|
||||
Ensure landing pages for sitelinks are relevant and optimized
|
||||
Campaign Structure Best Practices
|
||||
Group closely related keywords together
|
||||
Create separate ad groups for different themes
|
||||
Align ad copy closely with keywords in each ad group
|
||||
Use a mix of match types for each keyword
|
||||
Include negative keywords to prevent irrelevant clicks
|
||||
Create separate campaigns for different goals or audiences
|
||||
Set appropriate bid adjustments for devices, locations, and schedules
|
||||
Implement conversion tracking for performance measurement
|
||||
Export Options
|
||||
The Google Ads Generator offers multiple export formats to fit your workflow:
|
||||
|
||||
CSV Format
|
||||
Standard CSV format compatible with most spreadsheet applications
|
||||
Includes all ad elements and extensions
|
||||
Contains quality score and performance predictions
|
||||
Suitable for analysis and record-keeping
|
||||
Excel Format
|
||||
Formatted Excel workbook with multiple sheets
|
||||
Separate sheets for ads, extensions, and analysis
|
||||
Includes charts and visualizations of predicted performance
|
||||
Color-coded quality indicators
|
||||
Google Ads Editor CSV
|
||||
Specially formatted CSV for direct import into Google Ads Editor
|
||||
Follows Google's required format specifications
|
||||
Includes all necessary fields for campaign creation
|
||||
Ready for immediate upload to Google Ads Editor
|
||||
JSON Format
|
||||
Structured data format for programmatic use
|
||||
Complete ad data in machine-readable format
|
||||
Suitable for integration with other marketing tools
|
||||
Includes all metadata and analysis results
|
||||
Advanced Features
|
||||
Keyword Research Integration
|
||||
Access to keyword volume data
|
||||
Competition analysis
|
||||
Cost-per-click estimates
|
||||
Keyword difficulty scores
|
||||
Seasonal trend information
|
||||
Question-based keyword suggestions
|
||||
Long-tail keyword recommendations
|
||||
Competitor Analysis
|
||||
Identify competitors bidding on similar keywords
|
||||
Analyze competitor ad copy and messaging
|
||||
Identify gaps and opportunities
|
||||
Benchmark your ads against competitors
|
||||
Receive suggestions for differentiation
|
||||
Landing Page Suggestions
|
||||
Alignment with ad messaging
|
||||
Key elements to include
|
||||
Conversion optimization tips
|
||||
Mobile responsiveness recommendations
|
||||
Page speed improvement suggestions
|
||||
Call-to-action placement recommendations
|
||||
Local Ad Optimization
|
||||
Location extension suggestions
|
||||
Local keyword recommendations
|
||||
Geo-targeting strategies
|
||||
Local offer suggestions
|
||||
Community-focused messaging
|
||||
Location-specific call-to-actions
|
||||
Technical Details
|
||||
System Requirements
|
||||
Modern web browser (Chrome, Firefox, Safari, Edge)
|
||||
Internet connection
|
||||
Access to Alwrity AI Writer platform
|
||||
Data Privacy
|
||||
No permanent storage of business data
|
||||
Secure processing of all inputs
|
||||
Option to save ads to your account
|
||||
Compliance with data protection regulations
|
||||
API Integration
|
||||
Available API endpoints for programmatic access
|
||||
Documentation for developers
|
||||
Rate limits and authentication requirements
|
||||
Sample code for common use cases
|
||||
FAQ
|
||||
General Questions
|
||||
Q: How accurate are the performance predictions? A: Performance predictions are based on industry benchmarks and Google's published data. While they provide a good estimate, actual performance may vary based on numerous factors including competition, seasonality, and market conditions.
|
||||
|
||||
Q: Can I edit the generated ads? A: Yes, all generated ads can be edited before export. You can modify headlines, descriptions, paths, and extensions to better fit your needs.
|
||||
|
||||
Q: How many ads can I generate? A: The tool allows unlimited ad generation within your Alwrity subscription limits.
|
||||
|
||||
Q: Are the generated ads compliant with Google's policies? A: The tool is designed to create policy-compliant ads, but we recommend reviewing Google's latest advertising policies as they may change over time.
|
||||
|
||||
Technical Questions
|
||||
Q: Can I import my existing ads for optimization? A: Currently, the tool does not support importing existing ads, but this feature is on our roadmap.
|
||||
|
||||
Q: How do I import the exported files into Google Ads? A: For Google Ads Editor CSV files, open Google Ads Editor, go to File > Import, and select your exported file. For other formats, you may need to manually create campaigns using the generated content.
|
||||
|
||||
Q: Can I schedule automatic ad generation? A: Automated scheduling is not currently available but is planned for a future release.
|
||||
|
||||
Troubleshooting
|
||||
Common Issues
|
||||
Issue: Generated ads don't include my keywords Solution: Ensure your keywords are relevant to your business description and offerings. Try using more specific keywords or providing more detailed business information.
|
||||
|
||||
Issue: Quality score is consistently low Solution: Review the improvement suggestions in the Ad Performance tab. Common issues include keyword relevance, landing page alignment, and benefit clarity.
|
||||
|
||||
Issue: Export file isn't importing correctly into Google Ads Editor Solution: Ensure you're selecting the "Google Ads Editor CSV" export format. If problems persist, check for special characters in your ad copy that might be causing formatting issues.
|
||||
|
||||
Issue: Performance predictions seem unrealistic Solution: Adjust your industry selection and budget information to get more accurate predictions. Consider providing more specific audience targeting information.
|
||||
|
||||
Updates and Roadmap
|
||||
Recent Updates
|
||||
Added support for Performance Max campaign recommendations
|
||||
Improved keyword research integration
|
||||
Enhanced mobile ad optimization
|
||||
Added 5 new industry templates
|
||||
Improved quality score algorithm
|
||||
Coming Soon
|
||||
Competitor ad analysis tool
|
||||
A/B testing performance simulator
|
||||
Landing page builder integration
|
||||
Automated ad scheduling recommendations
|
||||
Video ad script generator
|
||||
Google Shopping ad support
|
||||
Multi-language ad generation
|
||||
Custom template builder
|
||||
Support
|
||||
For additional help with the Google Ads Generator:
|
||||
|
||||
Visit our Help Center
|
||||
Email support at support@example.com
|
||||
Join our Community Forum
|
||||
License
|
||||
The Google Ads Generator is part of the Alwrity AI Writer platform and is subject to the platform's terms of service and licensing agreements.
|
||||
|
||||
Acknowledgments
|
||||
Google Ads API documentation
|
||||
Industry best practices from leading digital marketing experts
|
||||
User feedback and feature requests
|
||||
Last updated: [Current Date]
|
||||
|
||||
Version: 1.0.0
|
||||
@@ -0,0 +1,9 @@
|
||||
"""
|
||||
Google Ads Generator Module
|
||||
|
||||
This module provides functionality for generating high-converting Google Ads.
|
||||
"""
|
||||
|
||||
from .google_ads_generator import write_google_ads
|
||||
|
||||
__all__ = ["write_google_ads"]
|
||||
@@ -0,0 +1,327 @@
|
||||
"""
|
||||
Ad Analyzer Module
|
||||
|
||||
This module provides functions for analyzing and scoring Google Ads.
|
||||
"""
|
||||
|
||||
import re
|
||||
from typing import Dict, List, Any, Tuple
|
||||
import random
|
||||
from urllib.parse import urlparse
|
||||
|
||||
def analyze_ad_quality(ad: Dict, primary_keywords: List[str], secondary_keywords: List[str],
|
||||
business_name: str, call_to_action: str) -> Dict:
|
||||
"""
|
||||
Analyze the quality of a Google Ad based on best practices.
|
||||
|
||||
Args:
|
||||
ad: Dictionary containing ad details
|
||||
primary_keywords: List of primary keywords
|
||||
secondary_keywords: List of secondary keywords
|
||||
business_name: Name of the business
|
||||
call_to_action: Call to action text
|
||||
|
||||
Returns:
|
||||
Dictionary with analysis results
|
||||
"""
|
||||
# Initialize results
|
||||
strengths = []
|
||||
improvements = []
|
||||
|
||||
# Get ad components
|
||||
headlines = ad.get("headlines", [])
|
||||
descriptions = ad.get("descriptions", [])
|
||||
path1 = ad.get("path1", "")
|
||||
path2 = ad.get("path2", "")
|
||||
|
||||
# Check headline count
|
||||
if len(headlines) >= 10:
|
||||
strengths.append("Good number of headlines (10+) for optimization")
|
||||
elif len(headlines) >= 5:
|
||||
strengths.append("Adequate number of headlines for testing")
|
||||
else:
|
||||
improvements.append("Add more headlines (aim for 10+) to give Google's algorithm more options")
|
||||
|
||||
# Check description count
|
||||
if len(descriptions) >= 4:
|
||||
strengths.append("Good number of descriptions (4+) for optimization")
|
||||
elif len(descriptions) >= 2:
|
||||
strengths.append("Adequate number of descriptions for testing")
|
||||
else:
|
||||
improvements.append("Add more descriptions (aim for 4+) to give Google's algorithm more options")
|
||||
|
||||
# Check headline length
|
||||
long_headlines = [h for h in headlines if len(h) > 30]
|
||||
if long_headlines:
|
||||
improvements.append(f"{len(long_headlines)} headline(s) exceed 30 characters and may be truncated")
|
||||
else:
|
||||
strengths.append("All headlines are within the recommended length")
|
||||
|
||||
# Check description length
|
||||
long_descriptions = [d for d in descriptions if len(d) > 90]
|
||||
if long_descriptions:
|
||||
improvements.append(f"{len(long_descriptions)} description(s) exceed 90 characters and may be truncated")
|
||||
else:
|
||||
strengths.append("All descriptions are within the recommended length")
|
||||
|
||||
# Check keyword usage in headlines
|
||||
headline_keywords = []
|
||||
for kw in primary_keywords:
|
||||
if any(kw.lower() in h.lower() for h in headlines):
|
||||
headline_keywords.append(kw)
|
||||
|
||||
if len(headline_keywords) == len(primary_keywords):
|
||||
strengths.append("All primary keywords are used in headlines")
|
||||
elif headline_keywords:
|
||||
strengths.append(f"{len(headline_keywords)} out of {len(primary_keywords)} primary keywords used in headlines")
|
||||
missing_kw = [kw for kw in primary_keywords if kw not in headline_keywords]
|
||||
improvements.append(f"Add these primary keywords to headlines: {', '.join(missing_kw)}")
|
||||
else:
|
||||
improvements.append("No primary keywords found in headlines - add keywords to improve relevance")
|
||||
|
||||
# Check keyword usage in descriptions
|
||||
desc_keywords = []
|
||||
for kw in primary_keywords:
|
||||
if any(kw.lower() in d.lower() for d in descriptions):
|
||||
desc_keywords.append(kw)
|
||||
|
||||
if len(desc_keywords) == len(primary_keywords):
|
||||
strengths.append("All primary keywords are used in descriptions")
|
||||
elif desc_keywords:
|
||||
strengths.append(f"{len(desc_keywords)} out of {len(primary_keywords)} primary keywords used in descriptions")
|
||||
missing_kw = [kw for kw in primary_keywords if kw not in desc_keywords]
|
||||
improvements.append(f"Add these primary keywords to descriptions: {', '.join(missing_kw)}")
|
||||
else:
|
||||
improvements.append("No primary keywords found in descriptions - add keywords to improve relevance")
|
||||
|
||||
# Check for business name
|
||||
if any(business_name.lower() in h.lower() for h in headlines):
|
||||
strengths.append("Business name is included in headlines")
|
||||
else:
|
||||
improvements.append("Consider adding your business name to at least one headline")
|
||||
|
||||
# Check for call to action
|
||||
if any(call_to_action.lower() in h.lower() for h in headlines) or any(call_to_action.lower() in d.lower() for d in descriptions):
|
||||
strengths.append("Call to action is included in the ad")
|
||||
else:
|
||||
improvements.append(f"Add your call to action '{call_to_action}' to at least one headline or description")
|
||||
|
||||
# Check for numbers and statistics
|
||||
has_numbers = any(bool(re.search(r'\d+', h)) for h in headlines) or any(bool(re.search(r'\d+', d)) for d in descriptions)
|
||||
if has_numbers:
|
||||
strengths.append("Ad includes numbers or statistics which can improve CTR")
|
||||
else:
|
||||
improvements.append("Consider adding numbers or statistics to increase credibility and CTR")
|
||||
|
||||
# Check for questions
|
||||
has_questions = any('?' in h for h in headlines) or any('?' in d for d in descriptions)
|
||||
if has_questions:
|
||||
strengths.append("Ad includes questions which can engage users")
|
||||
else:
|
||||
improvements.append("Consider adding a question to engage users")
|
||||
|
||||
# Check for emotional triggers
|
||||
emotional_words = ['you', 'free', 'because', 'instantly', 'new', 'save', 'proven', 'guarantee', 'love', 'discover']
|
||||
has_emotional = any(any(word in h.lower() for word in emotional_words) for h in headlines) or \
|
||||
any(any(word in d.lower() for word in emotional_words) for d in descriptions)
|
||||
|
||||
if has_emotional:
|
||||
strengths.append("Ad includes emotional trigger words which can improve engagement")
|
||||
else:
|
||||
improvements.append("Consider adding emotional trigger words to increase engagement")
|
||||
|
||||
# Check for path relevance
|
||||
if any(kw.lower() in path1.lower() or kw.lower() in path2.lower() for kw in primary_keywords):
|
||||
strengths.append("Display URL paths include keywords which improves relevance")
|
||||
else:
|
||||
improvements.append("Add keywords to your display URL paths to improve relevance")
|
||||
|
||||
# Return the analysis results
|
||||
return {
|
||||
"strengths": strengths,
|
||||
"improvements": improvements
|
||||
}
|
||||
|
||||
def calculate_quality_score(ad: Dict, primary_keywords: List[str], landing_page: str, ad_type: str) -> Dict:
|
||||
"""
|
||||
Calculate a quality score for a Google Ad based on best practices.
|
||||
|
||||
Args:
|
||||
ad: Dictionary containing ad details
|
||||
primary_keywords: List of primary keywords
|
||||
landing_page: Landing page URL
|
||||
ad_type: Type of Google Ad
|
||||
|
||||
Returns:
|
||||
Dictionary with quality score components
|
||||
"""
|
||||
# Initialize scores
|
||||
keyword_relevance = 0
|
||||
ad_relevance = 0
|
||||
cta_effectiveness = 0
|
||||
landing_page_relevance = 0
|
||||
|
||||
# Get ad components
|
||||
headlines = ad.get("headlines", [])
|
||||
descriptions = ad.get("descriptions", [])
|
||||
path1 = ad.get("path1", "")
|
||||
path2 = ad.get("path2", "")
|
||||
|
||||
# Calculate keyword relevance (0-10)
|
||||
# Check if keywords are in headlines, descriptions, and paths
|
||||
keyword_in_headline = sum(1 for kw in primary_keywords if any(kw.lower() in h.lower() for h in headlines))
|
||||
keyword_in_description = sum(1 for kw in primary_keywords if any(kw.lower() in d.lower() for d in descriptions))
|
||||
keyword_in_path = sum(1 for kw in primary_keywords if kw.lower() in path1.lower() or kw.lower() in path2.lower())
|
||||
|
||||
# Calculate score based on keyword presence
|
||||
if len(primary_keywords) > 0:
|
||||
headline_score = min(10, (keyword_in_headline / len(primary_keywords)) * 10)
|
||||
description_score = min(10, (keyword_in_description / len(primary_keywords)) * 10)
|
||||
path_score = min(10, (keyword_in_path / len(primary_keywords)) * 10)
|
||||
|
||||
# Weight the scores (headlines most important)
|
||||
keyword_relevance = (headline_score * 0.6) + (description_score * 0.3) + (path_score * 0.1)
|
||||
else:
|
||||
keyword_relevance = 5 # Default score if no keywords provided
|
||||
|
||||
# Calculate ad relevance (0-10)
|
||||
# Check for ad structure and content quality
|
||||
|
||||
# Check headline count and length
|
||||
headline_count_score = min(10, (len(headlines) / 10) * 10) # Ideal: 10+ headlines
|
||||
headline_length_score = 10 - min(10, (sum(1 for h in headlines if len(h) > 30) / max(1, len(headlines))) * 10)
|
||||
|
||||
# Check description count and length
|
||||
description_count_score = min(10, (len(descriptions) / 4) * 10) # Ideal: 4+ descriptions
|
||||
description_length_score = 10 - min(10, (sum(1 for d in descriptions if len(d) > 90) / max(1, len(descriptions))) * 10)
|
||||
|
||||
# Check for emotional triggers, questions, numbers
|
||||
emotional_words = ['you', 'free', 'because', 'instantly', 'new', 'save', 'proven', 'guarantee', 'love', 'discover']
|
||||
emotional_score = min(10, sum(1 for h in headlines if any(word in h.lower() for word in emotional_words)) +
|
||||
sum(1 for d in descriptions if any(word in d.lower() for word in emotional_words)))
|
||||
|
||||
question_score = min(10, (sum(1 for h in headlines if '?' in h) + sum(1 for d in descriptions if '?' in d)) * 2)
|
||||
|
||||
number_score = min(10, (sum(1 for h in headlines if bool(re.search(r'\d+', h))) +
|
||||
sum(1 for d in descriptions if bool(re.search(r'\d+', d)))) * 2)
|
||||
|
||||
# Calculate overall ad relevance score
|
||||
ad_relevance = (headline_count_score * 0.15) + (headline_length_score * 0.15) + \
|
||||
(description_count_score * 0.15) + (description_length_score * 0.15) + \
|
||||
(emotional_score * 0.2) + (question_score * 0.1) + (number_score * 0.1)
|
||||
|
||||
# Calculate CTA effectiveness (0-10)
|
||||
# Check for clear call to action
|
||||
cta_phrases = ['get', 'buy', 'shop', 'order', 'sign up', 'register', 'download', 'learn', 'discover', 'find', 'call',
|
||||
'contact', 'request', 'start', 'try', 'join', 'subscribe', 'book', 'schedule', 'apply']
|
||||
|
||||
cta_in_headline = any(any(phrase in h.lower() for phrase in cta_phrases) for h in headlines)
|
||||
cta_in_description = any(any(phrase in d.lower() for phrase in cta_phrases) for d in descriptions)
|
||||
|
||||
if cta_in_headline and cta_in_description:
|
||||
cta_effectiveness = 10
|
||||
elif cta_in_headline:
|
||||
cta_effectiveness = 8
|
||||
elif cta_in_description:
|
||||
cta_effectiveness = 7
|
||||
else:
|
||||
cta_effectiveness = 4
|
||||
|
||||
# Calculate landing page relevance (0-10)
|
||||
# In a real implementation, this would analyze the landing page content
|
||||
# For this example, we'll use a simplified approach
|
||||
|
||||
if landing_page:
|
||||
# Check if domain seems relevant to keywords
|
||||
domain = urlparse(landing_page).netloc
|
||||
|
||||
# Check if keywords are in the domain or path
|
||||
keyword_in_url = any(kw.lower() in landing_page.lower() for kw in primary_keywords)
|
||||
|
||||
# Check if URL structure seems appropriate
|
||||
has_https = landing_page.startswith('https://')
|
||||
|
||||
# Calculate landing page score
|
||||
landing_page_relevance = 5 # Base score
|
||||
|
||||
if keyword_in_url:
|
||||
landing_page_relevance += 3
|
||||
|
||||
if has_https:
|
||||
landing_page_relevance += 2
|
||||
|
||||
# Cap at 10
|
||||
landing_page_relevance = min(10, landing_page_relevance)
|
||||
else:
|
||||
landing_page_relevance = 5 # Default score if no landing page provided
|
||||
|
||||
# Calculate overall quality score (0-10)
|
||||
overall_score = (keyword_relevance * 0.4) + (ad_relevance * 0.3) + (cta_effectiveness * 0.2) + (landing_page_relevance * 0.1)
|
||||
|
||||
# Calculate estimated CTR based on quality score
|
||||
# This is a simplified model - in reality, CTR depends on many factors
|
||||
base_ctr = {
|
||||
"Responsive Search Ad": 3.17,
|
||||
"Expanded Text Ad": 2.83,
|
||||
"Call-Only Ad": 3.48,
|
||||
"Dynamic Search Ad": 2.69
|
||||
}.get(ad_type, 3.0)
|
||||
|
||||
# Adjust CTR based on quality score (±50%)
|
||||
quality_factor = (overall_score - 5) / 5 # -1 to 1
|
||||
estimated_ctr = base_ctr * (1 + (quality_factor * 0.5))
|
||||
|
||||
# Calculate estimated conversion rate
|
||||
# Again, this is simplified - actual conversion rates depend on many factors
|
||||
base_conversion_rate = 3.75 # Average conversion rate for search ads
|
||||
|
||||
# Adjust conversion rate based on quality score (±40%)
|
||||
estimated_conversion_rate = base_conversion_rate * (1 + (quality_factor * 0.4))
|
||||
|
||||
# Return the quality score components
|
||||
return {
|
||||
"keyword_relevance": round(keyword_relevance, 1),
|
||||
"ad_relevance": round(ad_relevance, 1),
|
||||
"cta_effectiveness": round(cta_effectiveness, 1),
|
||||
"landing_page_relevance": round(landing_page_relevance, 1),
|
||||
"overall_score": round(overall_score, 1),
|
||||
"estimated_ctr": round(estimated_ctr, 2),
|
||||
"estimated_conversion_rate": round(estimated_conversion_rate, 2)
|
||||
}
|
||||
|
||||
def analyze_keyword_relevance(keywords: List[str], ad_text: str) -> Dict:
|
||||
"""
|
||||
Analyze the relevance of keywords to ad text.
|
||||
|
||||
Args:
|
||||
keywords: List of keywords to analyze
|
||||
ad_text: Combined ad text (headlines and descriptions)
|
||||
|
||||
Returns:
|
||||
Dictionary with keyword relevance analysis
|
||||
"""
|
||||
results = {}
|
||||
|
||||
for keyword in keywords:
|
||||
# Check if keyword is in ad text
|
||||
is_present = keyword.lower() in ad_text.lower()
|
||||
|
||||
# Check if keyword is in the first 100 characters
|
||||
is_in_beginning = keyword.lower() in ad_text.lower()[:100]
|
||||
|
||||
# Count occurrences
|
||||
occurrences = ad_text.lower().count(keyword.lower())
|
||||
|
||||
# Calculate density
|
||||
density = (occurrences * len(keyword)) / len(ad_text) * 100 if len(ad_text) > 0 else 0
|
||||
|
||||
# Store results
|
||||
results[keyword] = {
|
||||
"present": is_present,
|
||||
"in_beginning": is_in_beginning,
|
||||
"occurrences": occurrences,
|
||||
"density": round(density, 2),
|
||||
"optimal_density": 0.5 <= density <= 2.5
|
||||
}
|
||||
|
||||
return results
|
||||
@@ -0,0 +1,320 @@
|
||||
"""
|
||||
Ad Extensions Generator Module
|
||||
|
||||
This module provides functions for generating various types of Google Ads extensions.
|
||||
"""
|
||||
|
||||
from typing import Dict, List, Any, Optional
|
||||
import re
|
||||
from ...gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
|
||||
def generate_extensions(business_name: str, business_description: str, industry: str,
|
||||
primary_keywords: List[str], unique_selling_points: List[str],
|
||||
landing_page: str) -> Dict:
|
||||
"""
|
||||
Generate a complete set of ad extensions based on business information.
|
||||
|
||||
Args:
|
||||
business_name: Name of the business
|
||||
business_description: Description of the business
|
||||
industry: Industry of the business
|
||||
primary_keywords: List of primary keywords
|
||||
unique_selling_points: List of unique selling points
|
||||
landing_page: Landing page URL
|
||||
|
||||
Returns:
|
||||
Dictionary with generated extensions
|
||||
"""
|
||||
# Generate sitelinks
|
||||
sitelinks = generate_sitelinks(business_name, business_description, industry, primary_keywords, landing_page)
|
||||
|
||||
# Generate callouts
|
||||
callouts = generate_callouts(business_name, unique_selling_points, industry)
|
||||
|
||||
# Generate structured snippets
|
||||
snippets = generate_structured_snippets(business_name, business_description, industry, primary_keywords)
|
||||
|
||||
# Return all extensions
|
||||
return {
|
||||
"sitelinks": sitelinks,
|
||||
"callouts": callouts,
|
||||
"structured_snippets": snippets
|
||||
}
|
||||
|
||||
def generate_sitelinks(business_name: str, business_description: str, industry: str,
|
||||
primary_keywords: List[str], landing_page: str) -> List[Dict]:
|
||||
"""
|
||||
Generate sitelink extensions based on business information.
|
||||
|
||||
Args:
|
||||
business_name: Name of the business
|
||||
business_description: Description of the business
|
||||
industry: Industry of the business
|
||||
primary_keywords: List of primary keywords
|
||||
landing_page: Landing page URL
|
||||
|
||||
Returns:
|
||||
List of dictionaries with sitelink information
|
||||
"""
|
||||
# Define common sitelink types by industry
|
||||
industry_sitelinks = {
|
||||
"E-commerce": ["Shop Now", "Best Sellers", "New Arrivals", "Sale Items", "Customer Reviews", "About Us"],
|
||||
"SaaS/Technology": ["Features", "Pricing", "Demo", "Case Studies", "Support", "Blog"],
|
||||
"Healthcare": ["Services", "Locations", "Providers", "Insurance", "Patient Portal", "Contact Us"],
|
||||
"Education": ["Programs", "Admissions", "Campus", "Faculty", "Student Life", "Apply Now"],
|
||||
"Finance": ["Services", "Rates", "Calculators", "Locations", "Apply Now", "About Us"],
|
||||
"Real Estate": ["Listings", "Sell Your Home", "Neighborhoods", "Agents", "Mortgage", "Contact Us"],
|
||||
"Legal": ["Practice Areas", "Attorneys", "Results", "Testimonials", "Free Consultation", "Contact"],
|
||||
"Travel": ["Destinations", "Deals", "Book Now", "Reviews", "FAQ", "Contact Us"],
|
||||
"Food & Beverage": ["Menu", "Locations", "Order Online", "Reservations", "Catering", "About Us"]
|
||||
}
|
||||
|
||||
# Get sitelinks for the specified industry, or use default
|
||||
sitelink_types = industry_sitelinks.get(industry, ["About Us", "Services", "Products", "Contact Us", "Testimonials", "FAQ"])
|
||||
|
||||
# Generate sitelinks
|
||||
sitelinks = []
|
||||
base_url = landing_page.rstrip('/') if landing_page else ""
|
||||
|
||||
for sitelink_type in sitelink_types:
|
||||
# Generate URL path based on sitelink type
|
||||
path = sitelink_type.lower().replace(' ', '-')
|
||||
url = f"{base_url}/{path}" if base_url else f"https://example.com/{path}"
|
||||
|
||||
# Generate description based on sitelink type
|
||||
description = ""
|
||||
if sitelink_type == "About Us":
|
||||
description = f"Learn more about {business_name} and our mission."
|
||||
elif sitelink_type == "Services" or sitelink_type == "Products":
|
||||
description = f"Explore our range of {primary_keywords[0] if primary_keywords else 'offerings'}."
|
||||
elif sitelink_type == "Contact Us":
|
||||
description = f"Get in touch with our team for assistance."
|
||||
elif sitelink_type == "Testimonials" or sitelink_type == "Reviews":
|
||||
description = f"See what our customers say about us."
|
||||
elif sitelink_type == "FAQ":
|
||||
description = f"Find answers to common questions."
|
||||
elif sitelink_type == "Pricing" or sitelink_type == "Rates":
|
||||
description = f"View our competitive pricing options."
|
||||
elif sitelink_type == "Shop Now" or sitelink_type == "Order Online":
|
||||
description = f"Browse and purchase our {primary_keywords[0] if primary_keywords else 'products'} online."
|
||||
|
||||
# Add the sitelink
|
||||
sitelinks.append({
|
||||
"text": sitelink_type,
|
||||
"url": url,
|
||||
"description": description
|
||||
})
|
||||
|
||||
return sitelinks
|
||||
|
||||
def generate_callouts(business_name: str, unique_selling_points: List[str], industry: str) -> List[str]:
|
||||
"""
|
||||
Generate callout extensions based on business information.
|
||||
|
||||
Args:
|
||||
business_name: Name of the business
|
||||
unique_selling_points: List of unique selling points
|
||||
industry: Industry of the business
|
||||
|
||||
Returns:
|
||||
List of callout texts
|
||||
"""
|
||||
# Use provided USPs if available
|
||||
if unique_selling_points and len(unique_selling_points) >= 4:
|
||||
# Ensure callouts are not too long (25 characters max)
|
||||
callouts = []
|
||||
for usp in unique_selling_points:
|
||||
if len(usp) <= 25:
|
||||
callouts.append(usp)
|
||||
else:
|
||||
# Try to truncate at a space
|
||||
truncated = usp[:22] + "..."
|
||||
callouts.append(truncated)
|
||||
|
||||
return callouts[:8] # Return up to 8 callouts
|
||||
|
||||
# Define common callouts by industry
|
||||
industry_callouts = {
|
||||
"E-commerce": ["Free Shipping", "24/7 Customer Service", "Secure Checkout", "Easy Returns", "Price Match Guarantee", "Next Day Delivery", "Satisfaction Guaranteed", "Exclusive Deals"],
|
||||
"SaaS/Technology": ["24/7 Support", "Free Trial", "No Credit Card Required", "Easy Integration", "Data Security", "Cloud-Based", "Regular Updates", "Customizable"],
|
||||
"Healthcare": ["Board Certified", "Most Insurance Accepted", "Same-Day Appointments", "Compassionate Care", "State-of-the-Art Facility", "Experienced Staff", "Convenient Location", "Telehealth Available"],
|
||||
"Education": ["Accredited Programs", "Expert Faculty", "Financial Aid", "Career Services", "Small Class Sizes", "Flexible Schedule", "Online Options", "Hands-On Learning"],
|
||||
"Finance": ["FDIC Insured", "No Hidden Fees", "Personalized Service", "Online Banking", "Mobile App", "Low Interest Rates", "Financial Planning", "Retirement Services"],
|
||||
"Real Estate": ["Free Home Valuation", "Virtual Tours", "Experienced Agents", "Local Expertise", "Financing Available", "Property Management", "Commercial & Residential", "Investment Properties"],
|
||||
"Legal": ["Free Consultation", "No Win No Fee", "Experienced Attorneys", "24/7 Availability", "Proven Results", "Personalized Service", "Multiple Practice Areas", "Aggressive Representation"]
|
||||
}
|
||||
|
||||
# Get callouts for the specified industry, or use default
|
||||
callouts = industry_callouts.get(industry, ["Professional Service", "Experienced Team", "Customer Satisfaction", "Quality Guaranteed", "Competitive Pricing", "Fast Service", "Personalized Solutions", "Trusted Provider"])
|
||||
|
||||
return callouts
|
||||
|
||||
def generate_structured_snippets(business_name: str, business_description: str, industry: str, primary_keywords: List[str]) -> Dict:
|
||||
"""
|
||||
Generate structured snippet extensions based on business information.
|
||||
|
||||
Args:
|
||||
business_name: Name of the business
|
||||
business_description: Description of the business
|
||||
industry: Industry of the business
|
||||
primary_keywords: List of primary keywords
|
||||
|
||||
Returns:
|
||||
Dictionary with structured snippet information
|
||||
"""
|
||||
# Define common snippet headers and values by industry
|
||||
industry_snippets = {
|
||||
"E-commerce": {
|
||||
"header": "Brands",
|
||||
"values": ["Nike", "Adidas", "Apple", "Samsung", "Sony", "LG", "Dell", "HP"]
|
||||
},
|
||||
"SaaS/Technology": {
|
||||
"header": "Services",
|
||||
"values": ["Cloud Storage", "Data Analytics", "CRM", "Project Management", "Email Marketing", "Cybersecurity", "API Integration", "Automation"]
|
||||
},
|
||||
"Healthcare": {
|
||||
"header": "Services",
|
||||
"values": ["Preventive Care", "Diagnostics", "Treatment", "Surgery", "Rehabilitation", "Counseling", "Telemedicine", "Wellness Programs"]
|
||||
},
|
||||
"Education": {
|
||||
"header": "Courses",
|
||||
"values": ["Business", "Technology", "Healthcare", "Design", "Engineering", "Education", "Arts", "Sciences"]
|
||||
},
|
||||
"Finance": {
|
||||
"header": "Services",
|
||||
"values": ["Checking Accounts", "Savings Accounts", "Loans", "Mortgages", "Investments", "Retirement Planning", "Insurance", "Wealth Management"]
|
||||
},
|
||||
"Real Estate": {
|
||||
"header": "Types",
|
||||
"values": ["Single-Family Homes", "Condos", "Townhouses", "Apartments", "Commercial", "Land", "New Construction", "Luxury Homes"]
|
||||
},
|
||||
"Legal": {
|
||||
"header": "Services",
|
||||
"values": ["Personal Injury", "Family Law", "Criminal Defense", "Estate Planning", "Business Law", "Immigration", "Real Estate Law", "Intellectual Property"]
|
||||
}
|
||||
}
|
||||
|
||||
# Get snippets for the specified industry, or use default
|
||||
snippet_info = industry_snippets.get(industry, {
|
||||
"header": "Services",
|
||||
"values": ["Consultation", "Assessment", "Implementation", "Support", "Maintenance", "Training", "Customization", "Analysis"]
|
||||
})
|
||||
|
||||
# If we have primary keywords, try to incorporate them
|
||||
if primary_keywords:
|
||||
# Try to determine a better header based on keywords
|
||||
service_keywords = ["service", "support", "consultation", "assistance", "help"]
|
||||
product_keywords = ["product", "item", "good", "merchandise"]
|
||||
brand_keywords = ["brand", "make", "manufacturer"]
|
||||
|
||||
for kw in primary_keywords:
|
||||
kw_lower = kw.lower()
|
||||
if any(service_word in kw_lower for service_word in service_keywords):
|
||||
snippet_info["header"] = "Services"
|
||||
break
|
||||
elif any(product_word in kw_lower for product_word in product_keywords):
|
||||
snippet_info["header"] = "Products"
|
||||
break
|
||||
elif any(brand_word in kw_lower for brand_word in brand_keywords):
|
||||
snippet_info["header"] = "Brands"
|
||||
break
|
||||
|
||||
return snippet_info
|
||||
|
||||
def generate_custom_extensions(business_info: Dict, extension_type: str) -> Any:
|
||||
"""
|
||||
Generate custom extensions using AI based on business information.
|
||||
|
||||
Args:
|
||||
business_info: Dictionary with business information
|
||||
extension_type: Type of extension to generate
|
||||
|
||||
Returns:
|
||||
Generated extension data
|
||||
"""
|
||||
# Extract business information
|
||||
business_name = business_info.get("business_name", "")
|
||||
business_description = business_info.get("business_description", "")
|
||||
industry = business_info.get("industry", "")
|
||||
primary_keywords = business_info.get("primary_keywords", [])
|
||||
unique_selling_points = business_info.get("unique_selling_points", [])
|
||||
|
||||
# Create a prompt based on extension type
|
||||
if extension_type == "sitelinks":
|
||||
prompt = f"""
|
||||
Generate 6 sitelink extensions for a Google Ads campaign for the following business:
|
||||
|
||||
Business Name: {business_name}
|
||||
Business Description: {business_description}
|
||||
Industry: {industry}
|
||||
Keywords: {', '.join(primary_keywords)}
|
||||
|
||||
For each sitelink, provide:
|
||||
1. Link text (max 25 characters)
|
||||
2. Description line 1 (max 35 characters)
|
||||
3. Description line 2 (max 35 characters)
|
||||
|
||||
Format the response as a JSON array of objects with "text", "description1", and "description2" fields.
|
||||
"""
|
||||
elif extension_type == "callouts":
|
||||
prompt = f"""
|
||||
Generate 8 callout extensions for a Google Ads campaign for the following business:
|
||||
|
||||
Business Name: {business_name}
|
||||
Business Description: {business_description}
|
||||
Industry: {industry}
|
||||
Keywords: {', '.join(primary_keywords)}
|
||||
Unique Selling Points: {', '.join(unique_selling_points)}
|
||||
|
||||
Each callout should:
|
||||
1. Be 25 characters or less
|
||||
2. Highlight a feature, benefit, or unique selling point
|
||||
3. Be concise and impactful
|
||||
|
||||
Format the response as a JSON array of strings.
|
||||
"""
|
||||
elif extension_type == "structured_snippets":
|
||||
prompt = f"""
|
||||
Generate structured snippet extensions for a Google Ads campaign for the following business:
|
||||
|
||||
Business Name: {business_name}
|
||||
Business Description: {business_description}
|
||||
Industry: {industry}
|
||||
Keywords: {', '.join(primary_keywords)}
|
||||
|
||||
Provide:
|
||||
1. The most appropriate header type (e.g., Brands, Services, Products, Courses, etc.)
|
||||
2. 8 values that are relevant to the business (each 25 characters or less)
|
||||
|
||||
Format the response as a JSON object with "header" and "values" fields.
|
||||
"""
|
||||
else:
|
||||
return None
|
||||
|
||||
# Generate the extensions using the LLM
|
||||
try:
|
||||
response = llm_text_gen(prompt)
|
||||
|
||||
# Process the response based on extension type
|
||||
# In a real implementation, you would parse the JSON response
|
||||
# For this example, we'll return a placeholder
|
||||
|
||||
if extension_type == "sitelinks":
|
||||
return [
|
||||
{"text": "About Us", "description1": "Learn about our company", "description2": "Our history and mission"},
|
||||
{"text": "Services", "description1": "Explore our service offerings", "description2": "Solutions for your needs"},
|
||||
{"text": "Products", "description1": "Browse our product catalog", "description2": "Quality items at great prices"},
|
||||
{"text": "Contact Us", "description1": "Get in touch with our team", "description2": "We're here to help you"},
|
||||
{"text": "Testimonials", "description1": "See what customers say", "description2": "Real reviews from real people"},
|
||||
{"text": "FAQ", "description1": "Frequently asked questions", "description2": "Find quick answers here"}
|
||||
]
|
||||
elif extension_type == "callouts":
|
||||
return ["Free Shipping", "24/7 Support", "Money-Back Guarantee", "Expert Team", "Premium Quality", "Fast Service", "Affordable Prices", "Satisfaction Guaranteed"]
|
||||
elif extension_type == "structured_snippets":
|
||||
return {"header": "Services", "values": ["Consultation", "Installation", "Maintenance", "Repair", "Training", "Support", "Design", "Analysis"]}
|
||||
else:
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error generating extensions: {str(e)}")
|
||||
return None
|
||||
@@ -0,0 +1,219 @@
|
||||
"""
|
||||
Ad Templates Module
|
||||
|
||||
This module provides templates for different ad types and industries.
|
||||
"""
|
||||
|
||||
from typing import Dict, List, Any
|
||||
|
||||
def get_industry_templates(industry: str) -> Dict:
|
||||
"""
|
||||
Get ad templates specific to an industry.
|
||||
|
||||
Args:
|
||||
industry: The industry to get templates for
|
||||
|
||||
Returns:
|
||||
Dictionary with industry-specific templates
|
||||
"""
|
||||
# Define templates for different industries
|
||||
templates = {
|
||||
"E-commerce": {
|
||||
"headline_templates": [
|
||||
"{product} - {benefit} | {business_name}",
|
||||
"Shop {product} - {discount} Off Today",
|
||||
"Top-Rated {product} - Free Shipping",
|
||||
"{benefit} with Our {product}",
|
||||
"New {product} Collection - {benefit}",
|
||||
"{discount}% Off {product} - Limited Time",
|
||||
"Buy {product} Online - Fast Delivery",
|
||||
"{product} Sale Ends {timeframe}",
|
||||
"Best-Selling {product} from {business_name}",
|
||||
"Premium {product} - {benefit}"
|
||||
],
|
||||
"description_templates": [
|
||||
"Shop our selection of {product} and enjoy {benefit}. Free shipping on orders over ${amount}. Order now!",
|
||||
"Looking for quality {product}? Get {benefit} with our {product}. {discount} off your first order!",
|
||||
"{business_name} offers premium {product} with {benefit}. Shop online or visit our store today!",
|
||||
"Discover our {product} collection. {benefit} guaranteed or your money back. Order now and save {discount}!"
|
||||
],
|
||||
"emotional_triggers": ["exclusive", "limited time", "sale", "discount", "free shipping", "bestseller", "new arrival"],
|
||||
"call_to_actions": ["Shop Now", "Buy Today", "Order Online", "Get Yours", "Add to Cart", "Save Today"]
|
||||
},
|
||||
"SaaS/Technology": {
|
||||
"headline_templates": [
|
||||
"{product} Software - {benefit}",
|
||||
"Try {product} Free for {timeframe}",
|
||||
"{benefit} with Our {product} Platform",
|
||||
"{product} - Rated #1 for {feature}",
|
||||
"New {feature} in Our {product} Software",
|
||||
"{business_name} - {benefit} Software",
|
||||
"Streamline {pain_point} with {product}",
|
||||
"{product} Software - {discount} Off",
|
||||
"Enterprise-Grade {product} for {audience}",
|
||||
"{product} - {benefit} Guaranteed"
|
||||
],
|
||||
"description_templates": [
|
||||
"{business_name}'s {product} helps you {benefit}. Try it free for {timeframe}. No credit card required.",
|
||||
"Struggling with {pain_point}? Our {product} provides {benefit}. Join {number}+ satisfied customers.",
|
||||
"Our {product} platform offers {feature} to help you {benefit}. Rated {rating}/5 by {source}.",
|
||||
"{product} by {business_name}: {benefit} for your business. Plans starting at ${price}/month."
|
||||
],
|
||||
"emotional_triggers": ["efficient", "time-saving", "seamless", "integrated", "secure", "scalable", "innovative"],
|
||||
"call_to_actions": ["Start Free Trial", "Request Demo", "Learn More", "Sign Up Free", "Get Started", "See Plans"]
|
||||
},
|
||||
"Healthcare": {
|
||||
"headline_templates": [
|
||||
"{service} in {location} | {business_name}",
|
||||
"Expert {service} - {benefit}",
|
||||
"Quality {service} for {audience}",
|
||||
"{business_name} - {credential} {professionals}",
|
||||
"Same-Day {service} Appointments",
|
||||
"{service} Specialists in {location}",
|
||||
"Affordable {service} - {benefit}",
|
||||
"{symptom}? Get {service} Today",
|
||||
"Advanced {service} Technology",
|
||||
"Compassionate {service} Care"
|
||||
],
|
||||
"description_templates": [
|
||||
"{business_name} provides expert {service} with {benefit}. Our {credential} team is ready to help. Schedule today!",
|
||||
"Experiencing {symptom}? Our {professionals} offer {service} with {benefit}. Most insurance accepted.",
|
||||
"Quality {service} in {location}. {benefit} from our experienced team. Call now to schedule your appointment.",
|
||||
"Our {service} center provides {benefit} for {audience}. Open {days} with convenient hours."
|
||||
],
|
||||
"emotional_triggers": ["trusted", "experienced", "compassionate", "advanced", "personalized", "comprehensive", "gentle"],
|
||||
"call_to_actions": ["Schedule Now", "Book Appointment", "Call Today", "Free Consultation", "Learn More", "Find Relief"]
|
||||
},
|
||||
"Real Estate": {
|
||||
"headline_templates": [
|
||||
"{property_type} in {location} | {business_name}",
|
||||
"{property_type} for {price_range} - {location}",
|
||||
"Find Your Dream {property_type} in {location}",
|
||||
"{feature} {property_type} - {location}",
|
||||
"New {property_type} Listings in {location}",
|
||||
"Sell Your {property_type} in {timeframe}",
|
||||
"{business_name} - {credential} {professionals}",
|
||||
"{property_type} {benefit} - {location}",
|
||||
"Exclusive {property_type} Listings",
|
||||
"{number}+ {property_type} Available Now"
|
||||
],
|
||||
"description_templates": [
|
||||
"Looking for {property_type} in {location}? {business_name} offers {benefit}. Browse our listings or call us today!",
|
||||
"Sell your {property_type} in {location} with {business_name}. Our {professionals} provide {benefit}. Free valuation!",
|
||||
"{business_name}: {credential} {professionals} helping you find the perfect {property_type} in {location}. Call now!",
|
||||
"Discover {feature} {property_type} in {location}. Prices from {price_range}. Schedule a viewing today!"
|
||||
],
|
||||
"emotional_triggers": ["dream home", "exclusive", "luxury", "investment", "perfect location", "spacious", "modern"],
|
||||
"call_to_actions": ["View Listings", "Schedule Viewing", "Free Valuation", "Call Now", "Learn More", "Get Pre-Approved"]
|
||||
}
|
||||
}
|
||||
|
||||
# Return templates for the specified industry, or a default if not found
|
||||
return templates.get(industry, {
|
||||
"headline_templates": [
|
||||
"{product/service} - {benefit} | {business_name}",
|
||||
"Professional {product/service} - {benefit}",
|
||||
"{benefit} with Our {product/service}",
|
||||
"{business_name} - {credential} {product/service}",
|
||||
"Quality {product/service} for {audience}",
|
||||
"Affordable {product/service} - {benefit}",
|
||||
"{product/service} in {location}",
|
||||
"{feature} {product/service} by {business_name}",
|
||||
"Experienced {product/service} Provider",
|
||||
"{product/service} - Satisfaction Guaranteed"
|
||||
],
|
||||
"description_templates": [
|
||||
"{business_name} offers professional {product/service} with {benefit}. Contact us today to learn more!",
|
||||
"Looking for quality {product/service}? {business_name} provides {benefit}. Call now for more information.",
|
||||
"Our {product/service} helps you {benefit}. Trusted by {number}+ customers. Contact us today!",
|
||||
"{business_name}: {credential} {product/service} provider. We offer {benefit} for {audience}. Learn more!"
|
||||
],
|
||||
"emotional_triggers": ["professional", "quality", "trusted", "experienced", "affordable", "reliable", "satisfaction"],
|
||||
"call_to_actions": ["Contact Us", "Learn More", "Call Now", "Get Quote", "Visit Website", "Schedule Consultation"]
|
||||
})
|
||||
|
||||
def get_ad_type_templates(ad_type: str) -> Dict:
|
||||
"""
|
||||
Get templates specific to an ad type.
|
||||
|
||||
Args:
|
||||
ad_type: The ad type to get templates for
|
||||
|
||||
Returns:
|
||||
Dictionary with ad type-specific templates
|
||||
"""
|
||||
# Define templates for different ad types
|
||||
templates = {
|
||||
"Responsive Search Ad": {
|
||||
"headline_count": 15,
|
||||
"description_count": 4,
|
||||
"headline_max_length": 30,
|
||||
"description_max_length": 90,
|
||||
"best_practices": [
|
||||
"Include at least 3 headlines with keywords",
|
||||
"Create headlines with different lengths",
|
||||
"Include at least 1 headline with a call to action",
|
||||
"Include at least 1 headline with your brand name",
|
||||
"Create descriptions that complement each other",
|
||||
"Include keywords in at least 2 descriptions",
|
||||
"Include a call to action in at least 1 description"
|
||||
]
|
||||
},
|
||||
"Expanded Text Ad": {
|
||||
"headline_count": 3,
|
||||
"description_count": 2,
|
||||
"headline_max_length": 30,
|
||||
"description_max_length": 90,
|
||||
"best_practices": [
|
||||
"Include keywords in Headline 1",
|
||||
"Use a call to action in Headline 2 or 3",
|
||||
"Include your brand name in one headline",
|
||||
"Make descriptions complementary but able to stand alone",
|
||||
"Include keywords in at least one description",
|
||||
"Include a call to action in at least one description"
|
||||
]
|
||||
},
|
||||
"Call-Only Ad": {
|
||||
"headline_count": 2,
|
||||
"description_count": 2,
|
||||
"headline_max_length": 30,
|
||||
"description_max_length": 90,
|
||||
"best_practices": [
|
||||
"Focus on encouraging phone calls",
|
||||
"Include language like 'Call now', 'Speak to an expert', etc.",
|
||||
"Mention phone availability (e.g., '24/7', 'Available now')",
|
||||
"Include benefits of calling rather than clicking",
|
||||
"Be clear about who will answer the call",
|
||||
"Include any special offers for callers"
|
||||
]
|
||||
},
|
||||
"Dynamic Search Ad": {
|
||||
"headline_count": 0, # Headlines are dynamically generated
|
||||
"description_count": 2,
|
||||
"headline_max_length": 0, # N/A
|
||||
"description_max_length": 90,
|
||||
"best_practices": [
|
||||
"Create descriptions that work with any dynamically generated headline",
|
||||
"Focus on your unique selling points",
|
||||
"Include a strong call to action",
|
||||
"Highlight benefits that apply across your product/service range",
|
||||
"Avoid specific product mentions that might not match the dynamic headline"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# Return templates for the specified ad type, or a default if not found
|
||||
return templates.get(ad_type, {
|
||||
"headline_count": 3,
|
||||
"description_count": 2,
|
||||
"headline_max_length": 30,
|
||||
"description_max_length": 90,
|
||||
"best_practices": [
|
||||
"Include keywords in headlines",
|
||||
"Use a call to action",
|
||||
"Include your brand name",
|
||||
"Make descriptions informative and compelling",
|
||||
"Include keywords in descriptions",
|
||||
"Highlight unique selling points"
|
||||
]
|
||||
})
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user