This workspace combines FastAPI backend services, Playwright- and RabbitMQ-powered data collectors, and a desktop Electron client to showcase the sample ingestion, creator outreach, seller-side RPA, and chatbot automation flows that support the INFound influencer pipeline. The materials are curated for an UCSD MS committee presentation, so every sensitive string has been sanitized.
infound-backend-serviceshouses the internal ingestion API, creator portals, request filters, scheduler, and MQ producers that run inside FastAPI processes.infound-data-collectionimplements RabbitMQ consumers, Playwright crawlers, and chatbot dispatchers (now covering partner, creator, and seller/shop portals) that normalize TikTok data and hand it to the backend.infound-desktop-clientis a pnpm monorepo built with Electron + Vue 3 + TypeScript; it contains the operator desktop app plus an RPA simulation app for seller login, outreach, sample-management, chatbot, and creator-detail flows.- Shared helpers in
common/modules centralize multi-environment config, structured logging, SQLAlchemy/Redis sessions, RabbitMQ connections, and model definitions so business logic can stay focused.
.
├── infound-backend-services/ # FastAPI APIs, schedulers, MQ producers
├── infound-data-collection/ # Playwright crawlers, RabbitMQ consumers, chatbots
└── infound-desktop-client/ # Electron desktop app + seller RPA simulation app
- Internal ingestion APIs under
apps/portal_inner_open_apirely onSampleIngestionService,RequestFilterMiddleware, and Pydantic models to validate rows, deduplicatesamples/sample_contents, persist*_crawl_logs, and maintainsample_chatbot_schedules. ChatbotSchedulePublisherperiodically polls due schedules, builds follow-up content viachatbot_message_builder, and publishes tasks tochatbot.topicthrough the sharedRabbitMQProducer;/chatbot/messagesaccepts prebuilt payloads as well.- Creator portals under
apps/portal_creator_open_apiprovide login plus sample/chatbot endpoints, while the inner API exposes/creators/ingest,/outreach_tasks/ingest, and/chatbot/messagesso crawlers can ingest creator metadata, sync outreach task state, and request message dispatch. - Common infrastructure (
common/core/config.py,common/core/logger.py,common/core/database.py,common/services/redis_service.py, etc.) keeps configuration, logging, database pooling, and Redis helpers consistent across services.
common/mqcontains a resilientRabbitMQConnectionandConsumerBasethat every consumer inherits; they auto-handle reconnection, error classification (MessageProcessingError,ValueError), and JSON parsing with contextual logs.apps/portal_tiktok_sample_crawler_htmlrebuilds the legacysample_all.py/sample_process.pyworkflow withCrawlerRunnerService, Playwright browser pools, Gmail code handlers, account/region selection, tab navigation, view-content/logistics extraction, and data normalization/export routines that still align withsamples,sample_contents, andsample_chatbot_schedulesthroughSampleIngestionClient.apps/portal_tiktok_campaign_crawlerlogs into TikTok Shop Partner Center, crawls campaign/product tables, optionally exports Excel snapshots, and posts normalized payloads to/campaigns/ingestand/products/ingestviaCampaignIngestionClient.apps/portal_tiktok_creator_crawlergathers creator metadata, contact info, and outreach-relevant stats, then posts them to the inner API endpoints for creator ingestion, outreach task syncing, and chatbot scheduling.apps/portal_tiktok_shop_creator_crawlertargets the seller/shop portal to pull creator-connection lists, persist them through/creators/ingest, and (optionally) publish shop-outreach chatbot tasks tochatbot.topic.apps/sample_chatbot,apps/outreach_chatbot, andapps/unified_chatbotconsume thechatbot.topicexchange, respect DLQs, and use Playwright instances to send sample and outreach messages, while providing manual overrides for accounts/regions and retry limits.apps/portal_tiktok_shop_chatbotconsumes shop-outreach messages (topic-based) and drives seller-portal IM to creators with the same Playwright/Gmail fallback stack as other chatbots.- RabbitMQ tasks are routed through
crawler.direct,chatbot.topic, and their DLQs; each consumer can also be run withAT_MOST_ONCEsemantics or batched delivery and can export normalized rows todata/manage_sample/ordata/manage_campaign/whenexportExcelis enabled.
apps/frontend.desktopis the operator-facing Electron app. It splits logic across Electron main/preload/renderer layers, persists non-sensitive state viaelectron-store, and stores tokens in the OS credential store.apps/frontend.rpa.simulationis a lightweight Electron shell for seller-side Playwright execution. It can start a reusable browser session and dispatch independent tasks for seller login, outreach, sample management, chatbot messaging, and creator-detail extraction.packages/frontend.desktop.sharedholds shared RPA abstractions, task executors, logger helpers, time helpers, and cross-app TypeScript types.- The desktop client complements the backend/data-collection services: it is primarily for interactive operator workflows and RPA debugging, while the Python services remain the production ingestion and MQ automation path.
- Sample crawler story: the Playwright-backed
portal_tiktok_sample_crawler_htmlservice drives[region, tab, campaign]exploration, extracts content/logistics/promotions, enforces the same normalization rules assample_process.py, exports verification files, then hands every batch to/samples/ingestviaSampleIngestionClient. This chain demonstrates the playbook for how TikTok sample requests become structured data. - Campaign crawler story:
portal_tiktok_campaign_crawlerlogs into Partner Center, scans campaigns or specific IDs, opens campaign detail tables, exports optional spreadsheets, and ships campaign/product rows to/campaigns/ingestand/products/ingestfor catalog seeding and monitoring. - Creator crawler story:
portal_tiktok_creator_crawlerlogs into the partner creator portal, scrolls results, captures creator stats/contact info, and calls/creators/ingest//outreach_tasks/ingestto sync records with the backend. It showcases how outreach datasets and creator contact pipelines are seeded before any chatbot outreach is scheduled. - Seller/shop outreach story:
portal_tiktok_shop_creator_crawlerlogs into the seller portal creator-connection page, applies keyword/brand filters, sends normalized creator rows to/creators/ingest, and emitschatbot.shop_outreach.*MQ messages so the shop chatbot can DM those creators without human intervention. - Chatbot story:
sample_chatbot,outreach_chatbot, andunified_chatbotconsumechatbot.topic, honor DLQs, and use Playwright to send the prepared sequences from the inner API. The scheduler + RabbitMQ flow demonstrates how the platform closes the loop, moving from discovery (sample & creator crawlers) to automated engagement without human-in-the-loop tweaks once the MQ payloads arrive.
- Operators publish RabbitMQ jobs (typically
function: "sample"or outreach tasks) tocrawler.direct. - Playwright crawlers log into TikTok partner portals, read tab states, parse actions/logistics/promotions, and normalize each row into the schema the backend expects.
- Normalized rows or creator/outreach payloads are POSTed to the inner API (
/samples/ingest,/creators/ingest,/outreach_tasks/ingest), withX-INFound-Inner-Service-Tokenheaders validated byRequestFilterMiddleware. - The inner API upserts MySQL tables, writes
sample_chatbot_schedules, and publishes chatbot jobs viaRabbitMQProducertochatbot.topicwith routing keys likechatbot.sample.batchorchatbot.outreach.batch. sample_chatbot/outreach_chatbot/unified_chatbotconsume those jobs, launch Playwright sessions, and send the prepared message sequences; failures go to DLQs for manual or scripted re-processing.
cd infound-backend-services
poetry install
export SERVICE_NAME=portal_inner_open_api
export ENV=dev
poetry run python main.py- Switch
SERVICE_NAMEtoportal_creator_open_apior other services to run additional FastAPI apps. - Override
configs/base.yamlplaceholders by creating environment-specific YAML files or by setting environment variables (e.g.,MYSQL_HOST,RABBITMQ__PASSWORD,AUTH__VALID_TOKENS).
cd infound-data-collection
poetry install --no-root
poetry run playwright install
export SERVICE_NAME=portal_tiktok_sample_crawler_html
export ENV=dev
poetry run python main.py --consumer portal_tiktok_sample_crawler_html --env "$ENV"- Swap
SERVICE_NAME/--consumerto runportal_tiktok_campaign_crawler,portal_tiktok_creator_crawler,sample_chatbot,outreach_chatbot, orunified_chatbot. - Playwright credentials, Gmail app passwords, and RabbitMQ/inner API hosts are loaded through environment variables or local YAML overrides (see
common/core/config.pyfor aliasing rules). - Replace every
<...>placeholder in the YAML configs with real values before deploying (RabbitMQ hosts, MySQL credentials, inner API tokens, etc.).
cd infound-desktop-client
pnpm install
# Operator desktop app
pnpm --filter frontend.desktop dev
# Seller RPA simulation app
pnpm --filter frontend.rpa.simulation dev- Production/staging endpoints in
apps/frontend.desktop/.env.*have been replaced with placeholders; define local values before running against a real environment. - The desktop app uses Electron main-process services for auth and state persistence, while the RPA simulation app expects local Playwright runtime data under ignored
data/paths. - See
infound-desktop-client/README.mdand theinfound-desktop-client/docs/folder for desktop architecture, IPC contracts, and RPA payload examples.
cd infound-data-collection
export SERVICE_NAME=portal_tiktok_sample_crawler_html
export ENV=dev
export PLAYWRIGHT_HEADLESS=false
poetry run python main.py --consumer portal_tiktok_sample_crawler_html --env "$ENV"cd infound-data-collection
export SERVICE_NAME=portal_tiktok_campaign_crawler
export ENV=dev
export PLAYWRIGHT_HEADLESS=false
poetry run python main.py --consumer portal_tiktok_campaign_crawler --env "$ENV"cd infound-data-collection
export SERVICE_NAME=portal_tiktok_creator_crawler
export ENV=dev
export PLAYWRIGHT_HEADLESS=false
poetry run python main.py --consumer portal_tiktok_creator_crawler --env "$ENV"cd infound-data-collection
export SERVICE_NAME=portal_tiktok_shop_creator_crawler
export ENV=dev
export PLAYWRIGHT_HEADLESS=false # set true for headless
# Optional overrides:
# export SHOP_OUTREACH_DEFAULT_REGION=MX
# export SHOP_OUTREACH_ACCOUNT_NAME=MX1 # match configs/accounts.json
poetry run python main.py --consumer portal_tiktok_shop_creator_crawler --env "$ENV"cd infound-data-collection
export SERVICE_NAME=sample_chatbot
export ENV=dev
poetry run python main.py --consumer sample_chatbot --env "$ENV"cd infound-data-collection
export SERVICE_NAME=outreach_chatbot
export ENV=dev
poetry run python main.py --consumer outreach_chatbot --env "$ENV"cd infound-data-collection
export SERVICE_NAME=unified_chatbot
export ENV=dev
poetry run python main.py --consumer unified_chatbot --env "$ENV"cd infound-data-collection
export SERVICE_NAME=portal_tiktok_shop_chatbot
export ENV=dev
export PLAYWRIGHT_HEADLESS=false # false to watch browser
# Optional: export SHOP_CHATBOT_ACCOUNT_NAME=MX1 # pick account from configs/accounts.json
poetry run python main.py --consumer portal_tiktok_shop_chatbot --env "$ENV"This presentation copy removes all secrets: IP addresses, hostnames, tokens, Gmail credentials, passwords, demo account identifiers, and embedded git remotes are shown as <PLACEHOLDER> values or example.com domains. Treat the placeholders in every YAML or .env file (infound-backend-services/configs/base.yaml, infound-data-collection/configs/base.yaml, infound-desktop-client/apps/frontend.desktop/.env.*, etc.) as prompts to load production values from a secure store before running.
- Refer to
infound-backend-services/readme.mdfor detailed sample ingestion contracts, chatbot scheduling, creator/outreach APIs, and SQL model generation guidance. - Refer to
infound-data-collection/readme.mdfor consumer configuration, RabbitMQ routing keys, Playwright behavior, data exports, and chatbot/creator crawler operations.