Inspiration

My inspiration for SalesKit Synthesizer came from witnessing a universal and costly problem in the enterprise world: the "Enterprise Content Velocity Gap." I saw highly-skilled, highly-paid sales professionals spending hours on low-value administrative work. They were constantly jumping between their CRM, like Salesforce, and generic slide decks, manually copying and pasting data to create sales proposals and datasheets. The process was not only slow and inefficient but also a breeding ground for embarrassing errors and off-brand content.

It struck me as a fundamental "last mile" problem. Companies invest millions in CRMs to structure their customer data and millions more in brand guidelines to structure their visual identity. Yet, the final, critical step of merging the two to create revenue-generating documents remained a manual, painful process. I knew there had to be a better way. I envisioned a "workflow hack" that would live directly inside a premier creative tool like Adobe Express, seamlessly bridging these two disconnected worlds and giving sales teams their most valuable resource back: their time.

What it does

SalesKit Synthesizer is an Adobe Express add-on that transforms how enterprise teams create personalized, on-brand sales and marketing collateral. It fundamentally automates the most tedious part of the content creation workflow.

Here’s how it works: A sales or marketing professional opens the add-on within Adobe Express. With a single click, they securely connect to their core enterprise system, like Salesforce or HubSpot. They can then search for any record—a sales opportunity, a customer account, a marketing lead—and select it. After choosing from a gallery of pre-approved, professionally designed "master templates," they hit the "Synthesize" button.

In seconds, the magic happens. The add-on's Synthesis Engine fetches all the relevant data from the CRM and intelligently populates the Adobe Express template. Text placeholders like {{OpportunityName}} and {{Amount}} are replaced with real data. Customer logos are fetched and placed perfectly into image frames. The result is a fully-formed, data-rich, and 100% brand-compliant proposal, case study, or datasheet, ready for final review and export as a polished PDF. It turns a multi-hour manual task into a 30-second automated process.

How I built it

I built SalesKit Synthesizer as a full-stack application, grounded in the powerful and secure architecture of the Adobe Express Add-on platform.

The Frontend Add-on: The user-facing panel was built with Vanilla JavaScript, HTML, and CSS to ensure a lightweight and native feel within the Adobe Express environment. I leveraged the addOnUISdk to manage the add-on's lifecycle and communicate with the host application. A key architectural decision was to adhere strictly to Adobe's dual-environment security model. All user interactions happen in the sandboxed UI , while all direct document manipulation happens in a separate, secure Document Sandbox.</p> <p>The Backend Proxy: To handle enterprise-grade requirements, I built a secure backend service. This server has two critical jobs: first, it securely handles the server-side part of the OAuth 2.0 token exchange, ensuring that sensitive client secrets are never exposed on the client side. Second, it acts as a vital proxy for all CRM API calls, allowing me to manage API keys securely and create a clean abstraction layer.</p> <p>The Core Synthesis Engine: The heart of the add-on is the engine that works with the Adobe Express Document API. It programmatically traverses the document&#39;s scenegraph, identifying placeholder elements by their names. It then intelligently replaces these placeholders with data, handling everything from simple text updates to fetching images from URLs in the CRM and placing them as image fills.</p> <p>Enterprise Data Integration: I built a modular &quot;connector framework&quot; on my backend to handle communication with different CRMs. I implemented the industry-standard OAuth 2.0 Authorization Code Flow, using the addOnUISdk.app.oauth helper to initiate the flow from the client, while my backend service managed the secure token exchange. This framework uses specific connectors for the Salesforce REST API—using efficient SOQL relationship queries—and the HubSpot V3 API, which required a multi-step process to fetch a deal and its associated company data.</p> <h2 id="challenges-i-ran-into">Challenges I ran into</h2> <p>My biggest challenge was architectural: creating a single, elegant system that could handle the very different API designs of Salesforce and HubSpot. Salesforce&#39;s query language, SOQL, allows you to fetch data from related objects in one efficient call. HubSpot, following a more traditional RESTful pattern, requires multiple, chained calls to get the same information. A naive implementation would have resulted in tangled, unmaintainable code.</p> <p>My solution was to design a robust abstraction layer on my backend. I defined a standardized internal data model—a &quot;Sales Kit Data Object.&quot; Each connector&#39;s sole responsibility is to make whatever API calls its platform requires and then translate the results into this common format. The rest of my application, especially the Synthesis Engine, is completely decoupled from the complexities of the source CRM. This was a critical design decision that makes the system dramatically more scalable and maintainable.</p> <p>Another significant challenge was implementing the secure communication bridge between the UI <iframe> and the Document Sandbox. Ensuring that data fetched from the network in the UI context could be securely and asynchronously passed to the sandbox to perform document modifications required a deep understanding of the SDK&#39;s proxy mechanism and careful planning to get right.</p> <h2 id="accomplishments-that-i-m-proud-of">Accomplishments that I’m proud of</h2> <p>I’m incredibly proud of building a tool that solves a tangible, high-value business problem. It’s not just a technical exercise; it&#39;s a solution that can give teams back thousands of hours and help them close more deals.</p> <p>From a technical standpoint, I’m most proud of the extensible data connector framework. The abstraction I designed means that adding support for a new CRM, like Microsoft Dynamics, is now a self-contained task that doesn&#39;t require touching the core application logic. This is the hallmark of enterprise-grade software design and ensures the project&#39;s long-term viability.</p> <p>I&#39;m also proud of the vision for the Synthesis Engine, which goes beyond simple mail-merge. By designing it to understand field types (like Currency or Percentage) and apply conditional formatting rules (like changing a header color if a deal is over a certain value), I&#39;ve laid the foundation for a truly intelligent document construction tool. This semantic mapping capability is what elevates SalesKit Synthesizer from a utility to a strategic asset.</p> <h2 id="what-i-learned">What I learned</h2> <p>This project was a deep dive into what it takes to build a truly enterprise-ready application on a modern platform. I learned just how powerful and well-designed the Adobe Express Add-on SDK is. The built-in support for complex OAuth flows, the secure dual-sandbox architecture, and the rich Document API provided all the building blocks I needed to execute my vision.</p> <p>Most importantly, I learned the critical importance of thinking about the entire user workflow, not just a single feature. By focusing on solving the &quot;last mile&quot; problem and seamlessly bridging the gap between disparate systems, I was able to design a product that provides an order of magnitude more value than a simple asset insertion tool. It reinforced my belief that the most impactful solutions are the ones that eliminate friction and automate entire processes from end to end.</p> <h2 id="whats-next-for-saleskit-synthesizer">What&#39;s next for SalesKit Synthesizer</h2> <p>My initial build represents a powerful and complete foundation, but the vision for SalesKit Synthesizer is much bigger. The next phase is all about making it smarter. </p> <p>I plan to integrate generative AI capabilities, powered by services like Adobe Firefly. This will enable features like an &quot;AI Copy Assist&quot; that can summarize lengthy product notes from a CRM into concise bullet points or rephrase content for a specific tone. I also plan to build a &quot;Brand Compliance AI&quot; that acts as an automated design buddy, analyzing a document to flag non-compliant fonts, colors, or logo placements and offering one-click fixes.</p> <p>Looking further ahead, my goal is to evolve SalesKit Synthesizer into a true platform for enterprise content automation. This involves expanding the connector framework to include Product Information Management (PIM) and Digital Asset Management (DAM) systems, like Adobe Experience Manager Assets. The ultimate feature will be a user-facing, no-code mapping UI that empowers administrators to create their own complex automation rules, turning the add-on into an indispensable part of their company&#39;s operational fabric.</p> <h2 id="my-commitment-to-ship">My Commitment to Ship</h2> <p>I have a clear and actionable roadmap to bring this project to market. The initial MVP I built for the hackathon proved the core concept and technical feasibility. The architecture detailed here is not just a plan; it is the blueprint for the market-ready product that I am actively developing. My commitment is to build out the full, robust Phase 1 functionality—including the live, secure integrations with Salesforce and HubSpot and the necessary backend services—to deliver a product that is not just a demo, but a complete, reliable, and secure solution ready for enterprise deployment. I am dedicated to shipping a product that will become a cornerstone of Adobe&#39;s enterprise content strategy.</p>

Built With

  • adobe-express-add-on-sdk
  • adobe-express-document-api
  • css3
  • db
  • html5
  • hubspot-crm-v3-api
  • javascript
  • json
  • oauth-2.0
  • rest-apis
  • salesforce-object-query-language-(soql)
  • salesforce-rest-api
Share this project:

Updates