logo
Technology

Supercharge Your Gupshup Campaigns with Cloudflare workers

Rajender Joshi
Sep 5, 2025
5 minutes

Introduction

Gupshup is a powerful customer engagement platform that enables marketing teams to create personalized campaigns. One of its key features is the ability to generate parameterized short links, which allow marketers to:

  • Track user behavior across different campaigns.
  • Deep link users directly into specific app screens based on campaign parameters.
  • Customize user journeys with UTMs and other tracking mechanisms.

However, for these short links to work seamlessly across web and mobile, they require proper deep linking setup, including hosting assetlinks.json and apple-app-site-association files. Without these, the short links open in a browser first, causing friction in the user experience.

Before implementing this solution, users clicking on short links from marketing campaigns faced a frustrating experience:

  1. The short link first opened a web browser.
  2. The browser then redirected to the app store or the app itself.
  3. This unnecessary intermediate step caused friction, slowed down the process, and led to a poor user experience.

From a marketing perspective, this issue was a nightmare. The team relied on seamless deep linking for campaign effectiveness, but without these JSON files, the user journey was inconsistent and frustrating. They felt helpless, as the broken experience impacted conversion rates, increased drop-offs, and reduced engagement.

Problem Statement

My goal was to serve .well-known/assetlinks.json and .well-known/apple-app-site-association on:

  • The primary domain mapped to short.io
  • Two subdomains which are CNAME entries pointing to a Gupshup

Since these subdomains were on Route53 and not directly managed under Cloudflare account, I had to configure Cloudflare Workers to serve these files reliably while addressing SSL certificate challenges between Cloudflare and Gupshup.

Why Use Cloudflare Workers for This?

Cloudflare Workers provide a lightweight, serverless execution environment that allows you to run JavaScript at the edge. Here’s why they were the perfect choice for this implementation:

  • No Infrastructure Management: Workers eliminate the need for dedicated backend servers.
  • Edge Deployment: Requests are served quickly from the nearest Cloudflare data center.
  • Custom Routing: Workers can dynamically serve files based on URL patterns.
  • Improved Security: Cloudflare handles SSL termination, reducing attack vectors.
  • Bypass Third-Party Restrictions: Since Gupshup doesn't allow hosting these JSON files directly, Workers provided a way to serve them without modifying Clevertap’s infrastructure.

Challenges and Complexities

1. Subdomains as CNAME Entries

The two subdomains were set as CNAME records pointing to Gupshup. Since Clevertap controls these subdomains, I could not directly serve the required files from their servers. This meant I needed an alternative way to host and serve these files while keeping the deep linking functionality intact.

2. SSL Certificate Handling

Gupshup uses its own SSL certificates for the subdomains, whereas Cloudflare uses its Universal SSL for the primary domain. This can cause conflicts when Cloudflare proxies requests through its network. To resolve this:

  • I ensured Cloudflare was set to "Full" SSL mode, which allows secure communication between Cloudflare and Gupshup.
  • I verified that Cloudflare's edge servers were not interfering with the SSL certificates managed by Gupshup.
  • I checked that Cloudflare's Universal SSL covered the primary domain to ensure a seamless HTTPS experience.

Solution: Cloudflare Worker for Serving Assets

To address this issue, create a Cloudflare Worker that dynamically fetches and serves the required JSON files from my root domain when requested from any subdomain. This approach allowed me to bypass the limitations of Gupshup’s infrastructure while keeping deep linking functional.

Enabling Cloudflare Proxy and Route Mapping

  1. DNS Configuration: Enable Cloudflare proxy mode for the subdomains in the DNS settings, ensuring that all traffic is routed through Cloudflare’s network.
  2. Custom Routes: Map the required routes (e.g., /.well-known/assetlinks.json and /.well-known/apple-app-site-association) to the Cloudflare Worker, ensuring that these files are served correctly without needing changes on Gupshup’s end.
  3. Traffic Handling: The Worker inspects incoming requests and conditionally fetches the appropriate JSON file from my root domain, providing a seamless experience without modifying existing Gupshup infrastructure.

Here’s the Worker script I used:

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    
    const sourceBase = 'https://xx.sh';
    const path = url.pathname;
    
    if (path === '/.well-known/apple-app-site-association' || path === '/.well-known/assetlinks.json') {
      const sourceUrl = `$sourceBase$path`;
      const response = await fetch(sourceUrl);
      
      if (response.ok) {
        return new Response(await response.text(), {
          headers: { 'Content-Type': response.headers.get('Content-Type') },
        });
      } else {
        return new Response('Error fetching resource from the source.', { status: 500 });
      }
    }

    return fetch(request);
  },
};

Fetching these JSON files from the root domain is not ideal, but I opted for this approach because my root domain is pointed to short.io, which offers a user-friendly interface for managing these JSON files for both iOS and Android.

You can choose any strategy that best suits your requirements.

How It Works

  1. The worker intercepts requests made to .well-known/assetlinks.json and .well-known/apple-app-site-association.
  2. It fetches the corresponding file from https://xx.sh.
  3. If the fetch is successful, it serves the response with the correct Content-Type header.
  4. If the fetch fails, it returns an error response.
  5. All other requests are forwarded as usual.

Handling Edge Cases

1. Network Failures

  • If the request to xx.sh fails, the worker returns a 500 status.

2. Incorrect Content-Type Headers

  • The worker ensures that the Content-Type header matches what is received from the source.

3. Requests to Unhandled Paths

  • Any request that does not match .well-known/assetlinks.json or .well-known/apple-app-site-association is forwarded as-is, ensuring that all other requests are served directly from Gupshup without interference.

Deploying Cloudflare Workers via CLI

To deploy this Worker, I used the Cloudflare CLI (wrangler). Here are the steps:

1. Authenticate Cloudflare Account

Login to Cloudflare using:

npx wrangler login

3. Create a New Worker

npx wrangler init my-worker
cd my-worker

4. Deploy the Worker

npx wrangler publish

Verifying the Deployment

Once deployed, you can verify that the Worker is serving the files correctly:

curl -i https://xx.sh/.well-known/apple-app-site-association
curl -i https://xx.sh/.well-known/assetlinks.json

If the response contains the correct JSON data, the Worker is working as expected.

Conclusion

By leveraging Cloudflare Workers, I was able to serve Apple App Site Association and Android Asset Links from my primary domain while ensuring compatibility with subdomains that use third-party services like Gupshup. This approach also helped in overcoming SSL complexities and streamlined the deep linking implementation across all platforms.

Loved this article?

Hit the like button

Share this article

Spread the knowledge