File size: 16,518 Bytes
35a1590
9461e13
56af34b
bc46207
7409805
7a6b77d
1d72d1e
24b72ba
7a6b77d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68833e7
9461e13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7a6b77d
 
 
 
 
 
 
 
9461e13
c3d3689
cc53428
 
51ff7fb
c3d3689
 
 
 
 
 
 
 
 
1d72d1e
c3d3689
1d72d1e
 
 
 
56af34b
1d72d1e
 
 
 
c3d3689
 
 
 
 
56af34b
1d72d1e
 
 
56af34b
c3d3689
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1d72d1e
c3d3689
1d72d1e
9461e13
7a6b77d
9461e13
 
 
56af34b
 
9461e13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56af34b
9461e13
 
 
b5df9d3
7a6b77d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1d72d1e
7a6b77d
1d72d1e
 
 
 
7a6b77d
1d72d1e
9461e13
1d72d1e
 
 
9461e13
1d72d1e
 
7a6b77d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1d72d1e
 
9461e13
 
 
7a6b77d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9461e13
 
 
 
 
 
 
1d72d1e
9461e13
1d72d1e
9461e13
 
 
 
 
 
 
 
 
 
 
b5df9d3
9461e13
 
 
 
b5df9d3
7a6b77d
 
b5df9d3
9461e13
56af34b
9461e13
 
 
 
56af34b
9461e13
35a1590
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9461e13
b5df9d3
9461e13
b5df9d3
9461e13
 
 
 
 
 
 
 
 
 
 
7a6b77d
 
b5df9d3
9461e13
 
 
c3d3689
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9461e13
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
import streamlit as st
st.set_page_config(page_title="B2B Problem Solver", layout="wide")

import requests
import os
import json
from bs4 import BeautifulSoup

# API Configuration options
API_OPTIONS = {
    "OpenAI": {
        "endpoint": "https://api.openai.com/v1/chat/completions",
        "env_key": "OPENAI_API_KEY",
        "models": ["gpt-4", "gpt-3.5-turbo"]
    },
    "Anthropic": {
        "endpoint": "https://api.anthropic.com/v1/messages",
        "env_key": "ANTHROPIC_API_KEY",
        "models": ["claude-3-opus-20240229", "claude-3-sonnet-20240229", "claude-3-haiku-20240307"]
    },
    "Azure OpenAI": {
        "endpoint": os.getenv("AZURE_OPENAI_ENDPOINT", "https://your-resource-name.openai.azure.com/openai/deployments/your-deployment-name/chat/completions?api-version=2023-05-15"),
        "env_key": "AZURE_OPENAI_API_KEY",
        "models": ["your-deployment-name"]
    }
}

# Define common business problem categories
PROBLEM_CATEGORIES = [
    "Sales Pipeline Issues",
    "Lead Generation Challenges",
    "Customer Retention Problems",
    "Marketing ROI Concerns",
    "Product-Market Fit",
    "Team Performance Issues",
    "Competitive Positioning",
    "Pricing Strategy",
    "Market Expansion Difficulties",
    "Digital Transformation Challenges",
    "Customer Acquisition Costs",
    "Other (Please Specify)"
]

# Get API settings from session state or initialize them
if 'api_provider' not in st.session_state:
    st.session_state.api_provider = "OpenAI"
if 'api_model' not in st.session_state:
    st.session_state.api_model = API_OPTIONS["OpenAI"]["models"][0]
if 'api_key' not in st.session_state:
    st.session_state.api_key = os.getenv(API_OPTIONS["OpenAI"]["env_key"], "")

def scrape_company_info(url):
    """Scrapes business information from the given company website URL with improved error handling."""
    if not url.startswith("http"):
        url = f"https://{url}"
    
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
        "Accept-Language": "en-US,en;q=0.5",
        "Connection": "keep-alive",
        "Upgrade-Insecure-Requests": "1",
        "Cache-Control": "max-age=0"
    }
    
    try:
        response = requests.get(url, headers=headers, timeout=15)
        response.raise_for_status()
        soup = BeautifulSoup(response.content, "html.parser")
        
        content = []
        # Extract meta description if available
        meta_description = soup.find("meta", {"name": "description"})
        if meta_description and meta_description.get("content"):
            content.append(meta_description["content"])
        
        # Extract text from title tag
        title = soup.find("title")
        if title and title.string:
            content.append(title.string.strip())
        
        # Extract text from h1, h2, and p tags
        for tag in ['h1', 'h2', 'p']:
            elements = soup.find_all(tag)
            content.extend([elem.get_text(strip=True) for elem in elements if elem.get_text(strip=True)])
            
        extracted_content = " ".join(content[:1500])
        
        if not extracted_content or len(extracted_content.split()) < 10:
            return f"Unable to extract sufficient information from {url}. Please enter company details manually."
            
        return extracted_content
    except requests.exceptions.HTTPError as e:
        if e.response.status_code == 403:
            return f"Cannot access {url} - Website has blocked our request (403 Forbidden). Please enter company details manually."
        elif e.response.status_code == 404:
            return f"Website {url} not found (404). Please check the URL and try again."
        else:
            return f"HTTP Error: {str(e)}. Please enter company details manually."
    except requests.exceptions.ConnectionError:
        return f"Failed to connect to {url}. Please check the URL or your internet connection."
    except requests.exceptions.Timeout:
        return f"Request to {url} timed out. The website may be slow or unavailable."
    except requests.exceptions.RequestException as e:
        return f"Error scraping website: {str(e)}. Please enter company details manually."
    except Exception as e:
        return f"Unexpected error: {str(e)}. Please enter company details manually."

def generate_problem_solution(business_info, problem_category, problem_description):
    """Generates a practical solution for the specified business problem using the configured AI provider."""
    prompt = f"""As a senior B2B growth strategist with extensive experience helping sales and marketing executives overcome business challenges, provide a practical solution for the following scenario:

COMPANY INFORMATION:
{business_info}

PROBLEM CATEGORY: {problem_category}

SPECIFIC PROBLEM:
{problem_description}

Please provide:

1. **Problem Analysis**: Briefly analyze the root causes of this issue based on common patterns in B2B companies.

2. **Strategic Solution**: Outline a clear, actionable solution that addresses the core problem.

3. **Implementation Steps**: Provide 3-5 specific, tactical steps to implement the solution.

4. **Expected Outcomes**: Describe the measurable results and timeframe they can expect.

5. **Common Pitfalls**: Note 2-3 potential challenges they might face during implementation and how to avoid them.

6. **Resource Requirements**: Briefly list any tools, skills, or resources needed.

Format your response in clear markdown with headers and bullet points, keeping it concise, practical, and immediately actionable for busy executives."""
    
    provider = st.session_state.api_provider
    model = st.session_state.api_model
    api_key = st.session_state.api_key
    
    if not api_key:
        return f"Error: Missing API key for {provider}. Please configure your API key in the settings."
    
    try:
        if provider == "OpenAI":
            return call_openai_api(prompt, model, api_key)
        elif provider == "Anthropic":
            return call_anthropic_api(prompt, model, api_key)
        elif provider == "Azure OpenAI":
            return call_azure_openai_api(prompt, model, api_key)
        else:
            return "Error: Invalid API provider selected"
    except Exception as e:
        error_message = str(e)
        return f"API Error: {error_message}\n\nPlease check your API configuration in the settings panel."

def call_openai_api(prompt, model, api_key):
    """Call the OpenAI API to generate a response."""
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }
    
    data = {
        "model": model,
        "messages": [
            {"role": "system", "content": "You are a senior B2B growth strategist who specializes in solving critical business challenges for sales and marketing executives."},
            {"role": "user", "content": prompt}
        ],
        "temperature": 0.7,
        "max_tokens": 3500
    }
    
    response = requests.post(API_OPTIONS["OpenAI"]["endpoint"], json=data, headers=headers)
    response.raise_for_status()
    return response.json()["choices"][0]["message"]["content"]

def call_anthropic_api(prompt, model, api_key):
    """Call the Anthropic API to generate a response."""
    headers = {
        "x-api-key": api_key,
        "anthropic-version": "2023-06-01",
        "content-type": "application/json"
    }
    
    data = {
        "model": model,
        "messages": [
            {"role": "user", "content": prompt}
        ],
        "max_tokens": 3500
    }
    
    response = requests.post(API_OPTIONS["Anthropic"]["endpoint"], json=data, headers=headers)
    response.raise_for_status()
    return response.json()["content"][0]["text"]

def call_azure_openai_api(prompt, model, api_key):
    """Call the Azure OpenAI API to generate a response."""
    headers = {
        "api-key": api_key,
        "Content-Type": "application/json"
    }
    
    data = {
        "messages": [
            {"role": "system", "content": "You are a senior B2B growth strategist who specializes in solving critical business challenges for sales and marketing executives."},
            {"role": "user", "content": prompt}
        ],
        "temperature": 0.7,
        "max_tokens": 3500
    }
    
    response = requests.post(API_OPTIONS["Azure OpenAI"]["endpoint"], json=data, headers=headers)
    response.raise_for_status()
    return response.json()["choices"][0]["message"]["content"]

# Streamlit UI
st.title("🚀 B2B Problem Solver")
st.markdown("### Get practical solutions to common business problems hindering your growth")

# API Configuration in sidebar
with st.sidebar:
    st.header("API Settings")
    st.session_state.api_provider = st.selectbox(
        "Select AI Provider", 
        options=list(API_OPTIONS.keys()),
        index=list(API_OPTIONS.keys()).index(st.session_state.api_provider)
    )
    
    st.session_state.api_model = st.selectbox(
        "Select Model",
        options=API_OPTIONS[st.session_state.api_provider]["models"],
        index=min(API_OPTIONS[st.session_state.api_provider]["models"].index(st.session_state.api_model) 
                  if st.session_state.api_model in API_OPTIONS[st.session_state.api_provider]["models"] else 0,
                 len(API_OPTIONS[st.session_state.api_provider]["models"]) - 1)
    )
    
    api_key_env = API_OPTIONS[st.session_state.api_provider]["env_key"]
    api_key_input = st.text_input(
        f"API Key (or set {api_key_env} environment variable)",
        type="password",
        value=st.session_state.api_key
    )
    if api_key_input:
        st.session_state.api_key = api_key_input
    
    st.info(f"Current status: {'✅ API key configured' if st.session_state.api_key else '❌ API key missing'}")

with st.expander("💡 How it works", expanded=True):
    st.markdown("""
    1. Enter your company details or website URL
    2. Select your most pressing business challenge
    3. Receive a customized, actionable solution plan
    4. Implement the steps to overcome your growth obstacle
    """)

input_method = st.radio("Choose input method:", ["Enter company details manually", "Use company website URL"])

if input_method == "Enter company details manually":
    company_name = st.text_input("Company Name*")
    industry = st.text_input("Industry*")
    company_description = st.text_area("What does your company do?*", help="Describe your products/services and target market.")
    team_size = st.selectbox("Company Size", ["1-10 employees", "11-50 employees", "51-200 employees", "201-500 employees", "500+ employees"])
    
    st.markdown("### What's your biggest challenge?")
    problem_category = st.selectbox("Select problem category*", PROBLEM_CATEGORIES)
    if problem_category == "Other (Please Specify)":
        custom_category = st.text_input("Please specify your problem category")
        problem_category = custom_category if custom_category else problem_category
    
    problem_description = st.text_area("Describe your specific challenge*", help="Provide details about the problem you're facing and what you've tried so far.")
    
    if st.button("Generate Solution"):
        if not all([company_name, industry, company_description, problem_description]):
            st.error("Please fill in all required fields marked with *")
        elif not st.session_state.api_key:
            st.error(f"Please configure your {st.session_state.api_provider} API key in the sidebar")
        else:
            with st.spinner("Analyzing your business challenge and crafting a solution..."):
                business_info = f"""
Company Name: {company_name}
Industry: {industry}
Company Description: {company_description}
Company Size: {team_size}
"""
                solution = generate_problem_solution(business_info, problem_category, problem_description)
                if solution:
                    if not solution.startswith("Error") and not solution.startswith("API Error"):
                        st.markdown("## Your Customized Solution Plan")
                        st.markdown(solution)
                        
                        with st.expander("Want expert help implementing this solution?"):
                            st.markdown("""
                            Our growth agency specializes in helping B2B companies implement these solutions and achieve measurable results.
                            
                            **Schedule a free 30-minute consultation** to discuss how we can help you overcome this challenge and accelerate your growth.
                            """)
                            contact_email = st.text_input("Your Email")
                            if st.button("Request Consultation"):
                                if contact_email:
                                    st.success("Thank you! We'll be in touch shortly to schedule your consultation.")
                                else:
                                    st.warning("Please enter your email address.")
                    else:
                        st.error(solution)

else:
    website_url = st.text_input("Enter your company website URL*", placeholder="e.g., www.example.com")
    
    st.markdown("### What's your biggest challenge?")
    problem_category = st.selectbox("Select problem category*", PROBLEM_CATEGORIES)
    if problem_category == "Other (Please Specify)":
        custom_category = st.text_input("Please specify your problem category")
        problem_category = custom_category if custom_category else problem_category
    
    problem_description = st.text_area("Describe your specific challenge*", help="Provide details about the problem you're facing and what you've tried so far.")
    
    if st.button("Generate Solution"):
        if not all([website_url, problem_description]):
            st.error("Please fill in all required fields marked with *")
        elif not st.session_state.api_key:
            st.error(f"Please configure your {st.session_state.api_provider} API key in the sidebar")
        else:
            with st.spinner("Extracting company details and generating your solution..."):
                company_info = scrape_company_info(website_url)
                if company_info:
                    if company_info.startswith("Cannot access") or company_info.startswith("Unable to extract") or company_info.startswith("Failed to connect") or company_info.startswith("HTTP Error") or company_info.startswith("Unexpected error"):
                        st.warning(company_info)
                        st.info("Please try entering your company details manually instead.")
                        # Show manual input form
                        company_name = st.text_input("Company Name*")
                        industry = st.text_input("Industry*")
                        company_description = st.text_area("What does your company do?*", help="Describe your products/services and target market.")
                        team_size = st.selectbox("Company Size", ["1-10 employees", "11-50 employees", "51-200 employees", "201-500 employees", "500+ employees"])
                        
                        if st.button("Try Again with Manual Details"):
                            if not all([company_name, industry, company_description]):
                                st.error("Please fill in all required fields marked with *")
                            else:
                                with st.spinner("Analyzing your business challenge and crafting a solution..."):
                                    business_info = f"""
Company Name: {company_name}
Industry: {industry}
Company Description: {company_description}
Company Size: {team_size}
"""
                                    manual_solution = generate_problem_solution(business_info, problem_category, problem_description)
                                    display_solution(manual_solution)
                    else:
                        solution = generate_problem_solution(company_info, problem_category, problem_description)
                        display_solution(solution)

# Add footer with branding
st.markdown("---")
st.markdown("Powered by [Your Growth Agency Name] | Helping B2B companies overcome growth obstacles since [Year]")