sumitdwivedi23 commited on
Commit
5a3b99b
·
1 Parent(s): d2dc48f

Add files via upload

Browse files
Files changed (1) hide show
  1. app.py +213 -0
app.py ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ from agno.agent import Agent
4
+ from agno.tools.firecrawl import FirecrawlTools
5
+ from agno.models.groq import Groq
6
+ from firecrawl import FirecrawlApp
7
+ from pydantic import BaseModel, Field
8
+ from typing import List
9
+ from composio_agno import Action, ComposioToolSet
10
+ import json
11
+
12
+ class QuoraUserInteractionSchema(BaseModel):
13
+ username: str = Field(description="The username of the user who posted the question or answer")
14
+ bio: str = Field(description="The bio or description of the user")
15
+ post_type: str = Field(description="The type of post, either 'question' or 'answer'")
16
+ timestamp: str = Field(description="When the question or answer was posted")
17
+ upvotes: int = Field(default=0, description="Number of upvotes received")
18
+ links: List[str] = Field(default_factory=list, description="Any links included in the post")
19
+
20
+ class QuoraPageSchema(BaseModel):
21
+ interactions: List[QuoraUserInteractionSchema] = Field(description="List of all user interactions (questions and answers) on the page")
22
+
23
+ def search_for_urls(company_description: str, firecrawl_api_key: str, num_links: int) -> List[str]:
24
+ url = "https://api.firecrawl.dev/v1/search"
25
+ headers = {
26
+ "Authorization": f"Bearer {firecrawl_api_key}",
27
+ "Content-Type": "application/json"
28
+ }
29
+ query1 = f"quora websites where people are looking for {company_description} services"
30
+ payload = {
31
+ "query": query1,
32
+ "limit": num_links,
33
+ "lang": "en",
34
+ "location": "United States",
35
+ "timeout": 60000,
36
+ }
37
+ response = requests.post(url, json=payload, headers=headers)
38
+ if response.status_code == 200:
39
+ data = response.json()
40
+ if data.get("success"):
41
+ results = data.get("data", [])
42
+ return [result["url"] for result in results]
43
+ return []
44
+
45
+ def extract_user_info_from_urls(urls: List[str], firecrawl_api_key: str) -> List[dict]:
46
+ user_info_list = []
47
+ firecrawl_app = FirecrawlApp(api_key=firecrawl_api_key)
48
+
49
+ try:
50
+ for url in urls:
51
+ response = firecrawl_app.extract(
52
+ [url],
53
+ {
54
+ 'prompt': 'Extract all user information including username, bio, post type (question/answer), timestamp, upvotes, and any links from Quora posts. Focus on identifying potential leads who are asking questions or providing answers related to the topic.',
55
+ 'schema': QuoraPageSchema.model_json_schema(),
56
+ }
57
+ )
58
+
59
+ if response.get('success') and response.get('status') == 'completed':
60
+ interactions = response.get('data', {}).get('interactions', [])
61
+ if interactions:
62
+ user_info_list.append({
63
+ "website_url": url,
64
+ "user_info": interactions
65
+ })
66
+ except Exception:
67
+ pass
68
+
69
+ return user_info_list
70
+
71
+ def format_user_info_to_flattened_json(user_info_list: List[dict]) -> List[dict]:
72
+ flattened_data = []
73
+
74
+ for info in user_info_list:
75
+ website_url = info["website_url"]
76
+ user_info = info["user_info"]
77
+
78
+ for interaction in user_info:
79
+ flattened_interaction = {
80
+ "Website URL": website_url,
81
+ "Username": interaction.get("username", ""),
82
+ "Bio": interaction.get("bio", ""),
83
+ "Post Type": interaction.get("post_type", ""),
84
+ "Timestamp": interaction.get("timestamp", ""),
85
+ "Upvotes": interaction.get("upvotes", 0),
86
+ "Links": ", ".join(interaction.get("links", [])),
87
+ }
88
+ flattened_data.append(flattened_interaction)
89
+
90
+ return flattened_data
91
+
92
+ def create_google_sheets_agent(composio_api_key: str, groq_api_key: str) -> Agent:
93
+ composio_toolset = ComposioToolSet(api_key=composio_api_key)
94
+ google_sheets_tool = composio_toolset.get_tools(actions=[Action.GOOGLESHEETS_SHEET_FROM_JSON])[0]
95
+
96
+ google_sheets_agent = Agent(
97
+ model=Groq(id="llama-3.3-70b-versatile",api_key=groq_api_key),
98
+ tools=[google_sheets_tool],
99
+ show_tool_calls=True,
100
+ markdown=True
101
+ )
102
+
103
+ # Set the system prompt after creating the agent
104
+ google_sheets_agent.system_prompt = (
105
+ "You are an expert at creating and updating Google Sheets. "
106
+ "You will be given user information in JSON format, and you need to write it into a new Google Sheet."
107
+ )
108
+
109
+ return google_sheets_agent
110
+
111
+ def write_to_google_sheets(flattened_data: List[dict], composio_api_key: str, groq_api_key: str) -> str:
112
+ google_sheets_agent = create_google_sheets_agent(composio_api_key, groq_api_key)
113
+
114
+ try:
115
+ message = (
116
+ "Create a new Google Sheet with this data. "
117
+ "The sheet should have these columns: Website URL, Username, Bio, Post Type, Timestamp, Upvotes, and Links in the same order as mentioned. "
118
+ "Here's the data in JSON format:\n\n"
119
+ f"{json.dumps(flattened_data, indent=2)}"
120
+ )
121
+
122
+ create_sheet_response = google_sheets_agent.run(message)
123
+ print("Google Sheets Agent Response:", create_sheet_response.content)
124
+
125
+ if "https://docs.google.com/spreadsheets/d/" in create_sheet_response.content:
126
+ google_sheets_link = create_sheet_response.content.split("https://docs.google.com/spreadsheets/d/")[1].split(" ")[0]
127
+ return f"https://docs.google.com/spreadsheets/d/{google_sheets_link}"
128
+ except Exception:
129
+ pass
130
+ return None
131
+
132
+ def create_prompt_transformation_agent(groq_api_key: str) -> Agent:
133
+ prompt_transformation_agent = Agent(
134
+ model=Groq(id="llama-3.3-70b-versatile",api_key=groq_api_key),
135
+ markdown=True
136
+ )
137
+
138
+ # Set the system prompt after creating the agent
139
+ prompt_transformation_agent.system_prompt = (
140
+ "You are an expert at transforming detailed user queries into concise company descriptions. "
141
+ "Your task is to extract the core business/product focus in 3-4 words.\n\n"
142
+ "Examples:\n"
143
+ "Input: 'Generate leads looking for AI-powered customer support chatbots for e-commerce stores.'\n"
144
+ "Output: 'AI customer support chatbots for e commerce'\n\n"
145
+ "Input: 'Find people interested in voice cloning technology for creating audiobooks and podcasts'\n"
146
+ "Output: 'voice cloning technology'\n\n"
147
+ "Always focus on the core product/service and keep it concise but clear."
148
+ )
149
+
150
+ return prompt_transformation_agent
151
+
152
+ def main():
153
+ st.title("🎯 Lead Generation Agent")
154
+ st.info("This firecrawl powered agent helps you generate leads from Quora by searching for relevant posts and extracting user information.")
155
+
156
+ with st.sidebar:
157
+ st.header("API Keys")
158
+ firecrawl_api_key = st.text_input("Firecrawl API Key", type="password")
159
+ st.caption(" Get your Firecrawl API key from [Firecrawl's website](https://www.firecrawl.dev/app/api-keys)")
160
+ groq_api_key = st.text_input("GROQ API Key", type="password")
161
+ st.caption(" Get your GROQ API key from [GROQ's website](https://console.groq.com/login)")
162
+ composio_api_key = st.text_input("Composio API Key", type="password")
163
+ st.caption(" Get your Composio API key from [Composio's website](https://composio.ai)")
164
+
165
+ num_links = st.number_input("Number of links to search", min_value=1, max_value=10, value=3)
166
+
167
+ if st.button("Reset"):
168
+ st.session_state.clear()
169
+ st.experimental_rerun()
170
+
171
+ user_query = st.text_area(
172
+ "Describe what kind of leads you're looking for:",
173
+ placeholder="e.g., Looking for users who need automated video editing software with AI capabilities",
174
+ help="Be specific about the product/service and target audience. The AI will convert this into a focused search query."
175
+ )
176
+
177
+ if st.button("Generate Leads"):
178
+ if not all([firecrawl_api_key, groq_api_key, composio_api_key, user_query]):
179
+ st.error("Please fill in all the API keys and describe what leads you're looking for.")
180
+ else:
181
+ with st.spinner("Processing your query..."):
182
+ transform_agent = create_prompt_transformation_agent(groq_api_key)
183
+ company_description = transform_agent.run(f"Transform this query into a concise 3-4 word company description: {user_query}")
184
+ st.write("🎯 Searching for:", company_description.content)
185
+
186
+ with st.spinner("Searching for relevant URLs..."):
187
+ urls = search_for_urls(company_description.content, firecrawl_api_key, num_links)
188
+
189
+ if urls:
190
+ st.subheader("Quora Links Used:")
191
+ for url in urls:
192
+ st.write(url)
193
+
194
+ with st.spinner("Extracting user info from URLs..."):
195
+ user_info_list = extract_user_info_from_urls(urls, firecrawl_api_key)
196
+
197
+ with st.spinner("Formatting user info..."):
198
+ flattened_data = format_user_info_to_flattened_json(user_info_list)
199
+
200
+ with st.spinner("Writing to Google Sheets..."):
201
+ google_sheets_link = write_to_google_sheets(flattened_data, composio_api_key, groq_api_key)
202
+
203
+ if google_sheets_link:
204
+ st.success("Lead generation and data writing to Google Sheets completed successfully!")
205
+ st.subheader("Google Sheets Link:")
206
+ st.markdown(f"[View Google Sheet]({google_sheets_link})")
207
+ else:
208
+ st.error("Failed to retrieve the Google Sheets link.")
209
+ else:
210
+ st.warning("No relevant URLs found.")
211
+
212
+ if __name__ == "__main__":
213
+ main()