modal_webhook.py
445 steps
Anthropic
Apify
FastAPI
Google Auth
Google API
Google Sheets
Modal
HTTP Client
This automation system orchestrates various business processes, leveraging AI, Google Sheets, and other web services to find sales leads, generate customized proposals, and analyze YouTube content. It also handles scheduled tasks and provides updates through Slack.
Flow
Click any step to see details
graph TB
n_modal_webhook_33["API: modal.App()"]:::api
subgraph n_modal_webhook_column_letter["column_letter()"]
n_modal_webhook_77{"while n #gt;= 0"}:::decision
end
subgraph n_modal_webhook_send_email_impl["send_email_impl()"]
n_modal_webhook_244{"if creds.expired"}:::decision
n_modal_webhook_254(["Output: logger.info()"]):::output
n_modal_webhook_244 --> n_modal_webhook_254
end
subgraph n_modal_webhook_read_sheet_impl["read_sheet_impl()"]
n_modal_webhook_272{"if creds.expired"}:::decision
n_modal_webhook_282(["Output: logger.info()"]):::output
n_modal_webhook_282[["Transform: len()"]]:::transform
n_modal_webhook_283[["Transform: len()"]]:::transform
n_modal_webhook_272 --> n_modal_webhook_282
n_modal_webhook_282 --> n_modal_webhook_282
n_modal_webhook_282 --> n_modal_webhook_283
end
subgraph n_modal_webhook_update_sheet_impl["update_sheet_impl()"]
n_modal_webhook_300{"if creds.expired"}:::decision
n_modal_webhook_311(["Output: logger.info()"]):::output
n_modal_webhook_300 --> n_modal_webhook_311
end
n_modal_webhook_instantly_get_emails_impl_compact[["instantly_get_emails_impl() — 9 steps (3 Decision, 3 Transform, 2 Output, 1 API)"]]:::compact
subgraph n_modal_webhook_instantly_send_reply_impl["instantly_send_reply_impl()"]
n_modal_webhook_360{"if not api_key"}:::decision
n_modal_webhook_375["API: requests.post()"]:::api
n_modal_webhook_377{"if response.status_code not in [200, 201]"}:::decision
n_modal_webhook_378(["Output: logger.error()"]):::output
n_modal_webhook_381(["Output: logger.info()"]):::output
n_modal_webhook_360 --> n_modal_webhook_375
n_modal_webhook_375 --> n_modal_webhook_377
n_modal_webhook_377 --> n_modal_webhook_378
n_modal_webhook_378 --> n_modal_webhook_381
end
n_modal_webhook_web_search_impl_compact[["web_search_impl() — 13 steps (5 Decision, 5 Transform, 2 Output, 1 API)"]]:::compact
n_modal_webhook_web_fetch_impl_compact[["web_fetch_impl() — 10 steps (5 Transform, 2 Decision, 2 Output, 1 API)"]]:::compact
n_modal_webhook_create_proposal_impl_compact[["create_proposal_impl() — 16 steps (8 API, 4 Transform, 2 Decision, 2 Output)"]]:::compact
subgraph n_modal_webhook_slack_notify["slack_notify()"]
n_modal_webhook_572{"if not webhook_url"}:::decision
n_modal_webhook_576{"if blocks"}:::decision
n_modal_webhook_579{"try/except block"}:::decision
n_modal_webhook_580[["Transform: .encode()"]]:::transform
n_modal_webhook_580[["Transform: .dumps()"]]:::transform
n_modal_webhook_584(["Output: logger.error()"]):::output
n_modal_webhook_572 --> n_modal_webhook_576
n_modal_webhook_576 --> n_modal_webhook_579
n_modal_webhook_579 --> n_modal_webhook_580
n_modal_webhook_580 --> n_modal_webhook_580
n_modal_webhook_580 --> n_modal_webhook_584
end
subgraph n_modal_webhook_slack_directive_start["slack_directive_start()"]
n_modal_webhook_589[["Transform: .dumps()"]]:::transform
end
subgraph n_modal_webhook_slack_thinking["slack_thinking()"]
n_modal_webhook_603[["Transform: len()"]]:::transform
end
subgraph n_modal_webhook_slack_tool_call["slack_tool_call()"]
n_modal_webhook_609[["Transform: .dumps()"]]:::transform
end
subgraph n_modal_webhook_slack_tool_result["slack_tool_result()"]
n_modal_webhook_616[["Transform: len()"]]:::transform
end
subgraph n_modal_webhook_slack_complete["slack_complete()"]
n_modal_webhook_622[["Transform: len()"]]:::transform
end
subgraph n_modal_webhook_run_procedural_script["run_procedural_script()"]
n_modal_webhook_664{"try/except block"}:::decision
n_modal_webhook_670{"if hasattr(module, 'run')"}:::decision
n_modal_webhook_678(["Output: logger.error()"]):::output
n_modal_webhook_679[["Transform: str()"]]:::transform
n_modal_webhook_664 --> n_modal_webhook_670
n_modal_webhook_670 --> n_modal_webhook_678
n_modal_webhook_678 --> n_modal_webhook_679
end
subgraph n_modal_webhook_load_webhook_config["load_webhook_config()"]
n_modal_webhook_689{"if not config_path.exists()"}:::decision
n_modal_webhook_691[["Transform: .loads()"]]:::transform
n_modal_webhook_691[/"File: .read_text()"/]:::fileio
n_modal_webhook_689 --> n_modal_webhook_691
n_modal_webhook_691 --> n_modal_webhook_691
end
subgraph n_modal_webhook_load_directive["load_directive()"]
n_modal_webhook_697{"if not directive_path.exists()"}:::decision
n_modal_webhook_699[/"File: .read_text()"/]:::fileio
n_modal_webhook_697 --> n_modal_webhook_699
end
n_modal_webhook_run_directive_compact[["run_directive() — 26 steps (12 Transform, 11 Decision, 2 Output, 1 API)"]]:::compact
n_modal_webhook_directive_compact[["directive() — 18 steps (8 Transform, 6 Decision, 3 Output, 1 API)"]]:::compact
subgraph n_modal_webhook_list_webhooks["list_webhooks()"]
n_modal_webhook_930["API: modal.fastapi_endpoint()"]:::api
n_modal_webhook_937[["Transform: dict comprehension: #lbrace;slug: #lbrace;'directive': cfg.g..."]]:::transform
n_modal_webhook_930 --> n_modal_webhook_937
end
n_modal_webhook_list_available_directives_compact[["list_available_directives() — 12 steps (8 Transform, 3 Decision, 1 File I/O)"]]:::compact
subgraph n_modal_webhook_list_available_scripts["list_available_scripts()"]
n_modal_webhook_986{"for f in scripts_dir.glob('*.py')"}:::decision
n_modal_webhook_987{"if f.stem.startswith('_')"}:::decision
n_modal_webhook_990[/"File: .read_text()"/]:::fileio
n_modal_webhook_992{"if '#quot;#quot;#quot;' in content"}:::decision
n_modal_webhook_995{"if end #gt; start"}:::decision
n_modal_webhook_996[["Transform: .split()"]]:::transform
n_modal_webhook_996[["Transform: .strip()"]]:::transform
n_modal_webhook_998[["Transform: .append()"]]:::transform
n_modal_webhook_986 --> n_modal_webhook_987
n_modal_webhook_987 --> n_modal_webhook_990
n_modal_webhook_990 --> n_modal_webhook_992
n_modal_webhook_992 --> n_modal_webhook_995
n_modal_webhook_995 --> n_modal_webhook_996
n_modal_webhook_996 --> n_modal_webhook_996
n_modal_webhook_996 --> n_modal_webhook_998
end
n_modal_webhook_run_agent_tool_compact[["run_agent_tool() — 12 steps (9 Decision, 3 Transform)"]]:::compact
n_modal_webhook_general_agent_compact[["general_agent() — 25 steps (13 Transform, 10 Decision, 2 API)"]]:::compact
subgraph n_modal_webhook_load_cron_config["load_cron_config()"]
n_modal_webhook_1233{"if not config_path.exists()"}:::decision
n_modal_webhook_1235[["Transform: .loads()"]]:::transform
n_modal_webhook_1235[/"File: .read_text()"/]:::fileio
n_modal_webhook_1233 --> n_modal_webhook_1235
n_modal_webhook_1235 --> n_modal_webhook_1235
end
subgraph n_modal_webhook_append_to_sheet["append_to_sheet()"]
n_modal_webhook_1252{"if creds.expired"}:::decision
n_modal_webhook_1257[["Transform: .append()"]]:::transform
n_modal_webhook_1252 --> n_modal_webhook_1257
end
subgraph n_modal_webhook_scheduled_welcome_email["scheduled_welcome_email()"]
n_modal_webhook_1284{"try/except block"}:::decision
n_modal_webhook_1286[["Transform: .loads()"]]:::transform
n_modal_webhook_1287{"if not token_data"}:::decision
n_modal_webhook_1299{"if creds.expired"}:::decision
n_modal_webhook_1323(["Output: logger.info()"]):::output
n_modal_webhook_1329(["Output: logger.error()"]):::output
n_modal_webhook_1330[["Transform: str()"]]:::transform
n_modal_webhook_1331[["Transform: str()"]]:::transform
n_modal_webhook_1284 --> n_modal_webhook_1286
n_modal_webhook_1286 --> n_modal_webhook_1287
n_modal_webhook_1287 --> n_modal_webhook_1299
n_modal_webhook_1299 --> n_modal_webhook_1323
n_modal_webhook_1323 --> n_modal_webhook_1329
n_modal_webhook_1329 --> n_modal_webhook_1330
n_modal_webhook_1330 --> n_modal_webhook_1331
end
n_modal_webhook_hourly_lead_scraper_compact[["hourly_lead_scraper() — 17 steps (8 Transform, 6 Decision, 3 Output)"]]:::compact
n_modal_webhook_scrape_leads_background_compact[["scrape_leads_background() — 82 steps (40 Transform, 33 Decision, 5 Output, 4 API)"]]:::compact
n_modal_webhook_scrape_leads_compact[["scrape_leads() — 9 steps (3 Decision, 3 Transform, 2 API, 1 Output)"]]:::compact
n_modal_webhook_generate_proposal_compact[["generate_proposal() — 19 steps (10 API, 5 Transform, 3 Decision, 1 Output)"]]:::compact
subgraph n_modal_webhook_read_demo_transcript["read_demo_transcript()"]
n_modal_webhook_1935["API: modal.fastapi_endpoint()"]:::api
n_modal_webhook_1950{"if name not in transcript_map"}:::decision
n_modal_webhook_1954[["Transform: list()"]]:::transform
n_modal_webhook_1957{"try/except block"}:::decision
n_modal_webhook_1958[/"File: open()"/]:::fileio
n_modal_webhook_1969[["Transform: str()"]]:::transform
n_modal_webhook_1935 --> n_modal_webhook_1950
n_modal_webhook_1950 --> n_modal_webhook_1954
n_modal_webhook_1954 --> n_modal_webhook_1957
n_modal_webhook_1957 --> n_modal_webhook_1958
n_modal_webhook_1958 --> n_modal_webhook_1969
end
n_modal_webhook_create_proposal_from_transcript_compact[["create_proposal_from_transcript() — 24 steps (13 Transform, 5 Decision, 3 API, 2 Output, +1 more)"]]:::compact
n_modal_webhook_scrape_youtube_with_apify_compact[["scrape_youtube_with_apify() — 12 steps (7 Decision, 4 Transform, 1 Output)"]]:::compact
n_modal_webhook_fetch_youtube_transcript_compact[["fetch_youtube_transcript() — 11 steps (4 Decision, 4 Transform, 2 API, 1 Output)"]]:::compact
subgraph n_modal_webhook_summarize_youtube_transcript["summarize_youtube_transcript()"]
n_modal_webhook_2288{"try/except block"}:::decision
end
n_modal_webhook_youtube_outliers_background_compact[["youtube_outliers_background() — 29 steps (18 Transform, 8 Decision, 2 API, 1 Output)"]]:::compact
n_modal_webhook_youtube_outliers_compact[["youtube_outliers() — 14 steps (9 Transform, 2 API, 2 Decision, 1 Output)"]]:::compact
n_modal_webhook_main_compact[["main() — 22 steps (22 Output)"]]:::compact
click n_modal_webhook_33 call showStepDetail("modal_webhook.py", 33)
click n_modal_webhook_77 call showStepDetail("modal_webhook.py", 77)
click n_modal_webhook_244 call showStepDetail("modal_webhook.py", 244)
click n_modal_webhook_254 call showStepDetail("modal_webhook.py", 254)
click n_modal_webhook_272 call showStepDetail("modal_webhook.py", 272)
click n_modal_webhook_282 call showStepDetail("modal_webhook.py", 282)
click n_modal_webhook_282 call showStepDetail("modal_webhook.py", 282)
click n_modal_webhook_283 call showStepDetail("modal_webhook.py", 283)
click n_modal_webhook_300 call showStepDetail("modal_webhook.py", 300)
click n_modal_webhook_311 call showStepDetail("modal_webhook.py", 311)
click n_modal_webhook_360 call showStepDetail("modal_webhook.py", 360)
click n_modal_webhook_375 call showStepDetail("modal_webhook.py", 375)
click n_modal_webhook_377 call showStepDetail("modal_webhook.py", 377)
click n_modal_webhook_378 call showStepDetail("modal_webhook.py", 378)
click n_modal_webhook_381 call showStepDetail("modal_webhook.py", 381)
click n_modal_webhook_572 call showStepDetail("modal_webhook.py", 572)
click n_modal_webhook_576 call showStepDetail("modal_webhook.py", 576)
click n_modal_webhook_579 call showStepDetail("modal_webhook.py", 579)
click n_modal_webhook_580 call showStepDetail("modal_webhook.py", 580)
click n_modal_webhook_580 call showStepDetail("modal_webhook.py", 580)
click n_modal_webhook_584 call showStepDetail("modal_webhook.py", 584)
click n_modal_webhook_589 call showStepDetail("modal_webhook.py", 589)
click n_modal_webhook_603 call showStepDetail("modal_webhook.py", 603)
click n_modal_webhook_609 call showStepDetail("modal_webhook.py", 609)
click n_modal_webhook_616 call showStepDetail("modal_webhook.py", 616)
click n_modal_webhook_622 call showStepDetail("modal_webhook.py", 622)
click n_modal_webhook_664 call showStepDetail("modal_webhook.py", 664)
click n_modal_webhook_670 call showStepDetail("modal_webhook.py", 670)
click n_modal_webhook_678 call showStepDetail("modal_webhook.py", 678)
click n_modal_webhook_679 call showStepDetail("modal_webhook.py", 679)
click n_modal_webhook_689 call showStepDetail("modal_webhook.py", 689)
click n_modal_webhook_691 call showStepDetail("modal_webhook.py", 691)
click n_modal_webhook_691 call showStepDetail("modal_webhook.py", 691)
click n_modal_webhook_697 call showStepDetail("modal_webhook.py", 697)
click n_modal_webhook_699 call showStepDetail("modal_webhook.py", 699)
click n_modal_webhook_930 call showStepDetail("modal_webhook.py", 930)
click n_modal_webhook_937 call showStepDetail("modal_webhook.py", 937)
click n_modal_webhook_986 call showStepDetail("modal_webhook.py", 986)
click n_modal_webhook_987 call showStepDetail("modal_webhook.py", 987)
click n_modal_webhook_990 call showStepDetail("modal_webhook.py", 990)
click n_modal_webhook_992 call showStepDetail("modal_webhook.py", 992)
click n_modal_webhook_995 call showStepDetail("modal_webhook.py", 995)
click n_modal_webhook_996 call showStepDetail("modal_webhook.py", 996)
click n_modal_webhook_996 call showStepDetail("modal_webhook.py", 996)
click n_modal_webhook_998 call showStepDetail("modal_webhook.py", 998)
click n_modal_webhook_1233 call showStepDetail("modal_webhook.py", 1233)
click n_modal_webhook_1235 call showStepDetail("modal_webhook.py", 1235)
click n_modal_webhook_1235 call showStepDetail("modal_webhook.py", 1235)
click n_modal_webhook_1252 call showStepDetail("modal_webhook.py", 1252)
click n_modal_webhook_1257 call showStepDetail("modal_webhook.py", 1257)
click n_modal_webhook_1284 call showStepDetail("modal_webhook.py", 1284)
click n_modal_webhook_1286 call showStepDetail("modal_webhook.py", 1286)
click n_modal_webhook_1287 call showStepDetail("modal_webhook.py", 1287)
click n_modal_webhook_1299 call showStepDetail("modal_webhook.py", 1299)
click n_modal_webhook_1323 call showStepDetail("modal_webhook.py", 1323)
click n_modal_webhook_1329 call showStepDetail("modal_webhook.py", 1329)
click n_modal_webhook_1330 call showStepDetail("modal_webhook.py", 1330)
click n_modal_webhook_1331 call showStepDetail("modal_webhook.py", 1331)
click n_modal_webhook_1935 call showStepDetail("modal_webhook.py", 1935)
click n_modal_webhook_1950 call showStepDetail("modal_webhook.py", 1950)
click n_modal_webhook_1954 call showStepDetail("modal_webhook.py", 1954)
click n_modal_webhook_1957 call showStepDetail("modal_webhook.py", 1957)
click n_modal_webhook_1958 call showStepDetail("modal_webhook.py", 1958)
click n_modal_webhook_1969 call showStepDetail("modal_webhook.py", 1969)
click n_modal_webhook_2288 call showStepDetail("modal_webhook.py", 2288)
classDef api fill:#dbeafe,stroke:#2563eb,color:#1e3a5f
classDef fileio fill:#dcfce7,stroke:#16a34a,color:#14532d
classDef dbop fill:#f3e8ff,stroke:#9333ea,color:#3b0764
classDef decision fill:#ffedd5,stroke:#ea580c,color:#7c2d12
classDef output fill:#f3f4f6,stroke:#6b7280,color:#1f2937
classDef transform fill:#ccfbf1,stroke:#0d9488,color:#134e4a
classDef entry fill:#dcfce7,stroke:#16a34a,stroke-width:3px,color:#14532d
classDef compact fill:#f0f4ff,stroke:#6366f1,color:#312e81,stroke-width:2px
API Call
File I/O
Database
Decision
Output
Transform
All Steps
Step Detail
Select a step from the diagram or list to see its details.
Services
- Anthropic (anthropic)
- Apify (apify_client)
- FastAPI (fastapi)
- Google Auth (google.oauth2)
- Google API (googleapiclient)
- Google Sheets (gspread)
- Modal (modal)
- HTTP Client (requests)
Secrets
- ANTHROPIC_API_KEY
- ANYMAILFINDER_API_KEY
- APIFY_API_TOKEN
- GOOGLE_TOKEN_JSON
- INSTANTLY_API_KEY
- PANDADOC_API_KEY
- SLACK_WEBHOOK_URL
Imports
External
- anthropic
- apify_client
- base64
- concurrent.futures
- datetime
- email.mime.text
- fastapi.responses
- google.auth.transport.requests
- google.oauth2.credentials
- googleapiclient.discovery
- gspread
- importlib.util
- json
- logging
- modal
- os
- pandas
- pathlib
- re
- requests
- subprocess
- sys
- urllib.parse
- urllib.request