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