LinkedIn hashtag intelligence prototype for market monitoring, competitive analysis, and marketing strategy validation.
This project was built as an automation and research prototype while I was working at Panorays. Its purpose is to analyze LinkedIn-wide hashtag visibility based on a target hashtag or keyword, collect chart-ready metrics, and surface who publishes the most articles or posts around that hashtag. The output helps monitor whether a specific marketing strategy is gaining visibility across a competitive landscape.
- Searches LinkedIn result pages by hashtag or keyword.
- Counts result-page volume for a tracked list of competitive hashtags.
- Collects people who shared or published content around a selected hashtag.
- Converts collected data into JSON graph fixtures with
{ Letter, Freq }points. - Generates offline HTML, SVG, PNG, and JSON report artifacts from
graph.json. - Builds trend summaries from dated fixture snapshots, including author/share-frequency snapshots.
- Supports a CI-safe fixture analytics test that validates the ranking logic without hitting LinkedIn.
The existing sample dataset focuses on third-party risk, vendor risk, cybersecurity, and security-assurance competitors. panorays is highlighted in the generated chart so the output can be used as a competitive benchmark.
Marketing teams often need to know more than whether a campaign was posted. They need to see whether the market is reacting, which hashtags create more reach, and which people or companies dominate a conversation.
This repository demonstrates a pragmatic automation workflow for that problem:
- Define the hashtag or keyword landscape.
- Collect searchable LinkedIn visibility signals.
- Normalize the data into chart-ready fixtures.
- Rank competitors and content publishers.
- Use the result as an input for marketing strategy monitoring.
Cypress specs
-> LinkedIn search navigation
-> result-page and author extraction
-> fixture writer
-> graph-ready JSON output
-> CI-safe validation over captured fixtures
Key files:
src/config/hashtagMarket.ts- typed market configuration for tracked hashtags, categories, and highlighted tags.src/analytics/graph.ts- shared ranking, summary, and author-count helpers.cypress/e2e/hashtagAnalytics.cy.ts- analytics smoke test plus skipped live LinkedIn collection flows.cypress/support/commands.ts- reusable Cypress commands for login, navigation, pagination, and network-idle waits.scripts/generate-report.ts- report generator for HTML, SVG, PNG, and summary JSON artifacts.scripts/generate-trends.ts- trend analysis over date-stamped hashtag or author-frequency fixtures.docs/architecture.md- data-flow architecture overview.cypress/fixtures/shortCompaniesGraph.json- compact ranked fixture used by CI.cypress/fixtures/graph.json- default graph input for offline report generation.cypress/fixtures/companiesGraph.json- fuller competitive hashtag dataset.images/status.png- example visualization generated from captured data.cypress.config.ts- Cypress 15 configuration for e2e specs, browser launch hooks, retries, and viewport settings..github/workflows/main.yml- GitHub Actions CI for typecheck, formatting, and Cypress validation.
Use Node.js 20 for the most predictable Cypress 15.x runtime.
npm install
npm run validateUseful commands:
npm run typecheck
npm run analytics:offline
npm run report
npm run trend
npm run format:check
npm run cypress:run
npm run openThe default CI flow does not log in to LinkedIn and does not scrape live pages. Live collection is intentionally skipped in the spec because it depends on credentials, LinkedIn UI state, account permissions, and LinkedIn platform rules.
To run the live flow locally, unskip the live LinkedIn collection block and provide credentials through Cypress env values:
npm run cypress:chrome -- -e username=<LINKEDIN_EMAIL>,password=<LINKEDIN_PASSWORD>Generated files are written to cypress/fixtures/graph.json and to a date-stamped fixture such as cypress/fixtures/2026-06-16.json.
Generate the current market report and trend summary without touching LinkedIn:
npm run analytics:offlineOutputs are written to reports/:
hashtag-report.htmlhashtag-report.svghashtag-report.pnghashtag-report-summary.jsontrend-summary.jsontrend-summary.md
docker build -t hashtags-linkedin .
docker run --rm hashtags-linkedinFor live LinkedIn runs, prefer local Cypress execution so credentials remain in your local shell history or secret manager rather than inside an image layer.
GitHub Actions runs on every push, pull request, weekly schedule, and manual dispatch:
- Install dependencies with
npm ci. - Run TypeScript typechecking.
- Verify formatting with Prettier.
- Generate offline HTML, PNG, JSON, and trend report artifacts.
- Run the Cypress fixture analytics test.
- Upload the
reports/directory as a workflow artifact.
The badge at the top of this README reflects the current status of .github/workflows/main.yml. After the workflow passes on GitHub, it will render as a green CI badge.
This repository does not include LinkedIn credentials, private Panorays data, or internal company assets. Fixture files are sample outputs that demonstrate the analytics shape expected by the charting workflow.
When running live automation, use an account and data source that you are authorized to access, respect LinkedIn's platform rules, and avoid storing personal data that is not required for the analysis.
- Persist collection metadata such as date, query, region, account context, and source URL.
- Split live collection from offline analytics so CI stays deterministic while the collector can run as an explicit job.
- Add
npm auditor Dependabot checks to keep the automation stack current. - Add a lightweight dashboard UI for comparing multiple markets side by side.
- Add regression thresholds for brand visibility deltas so CI can flag unusual market movement.
