npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@open-wa/integration-cloudflare

v5.6.6

Published

Cloudflare Tunnel integration plugin for open-wa

Readme

@open-wa/cf-proxy

@open-wa/cf-proxy is the Cloudflare Worker reverse tunnel for open-wa Easy API sessions. The local runtime opens an outbound WebSocket to the Worker, so the local machine does not need an inbound port. The Worker remains a remotely reachable authenticated entry point.

The package is private to the open-wa monorepo. It is not an npm consumer package, so deployment starts from this repository's packages/cf-proxy entrypoint.

Topology and authentication

Remote consumer --HTTPS/WebSocket--> Cloudflare Worker --Durable Object--> local TunnelClient --HTTP--> Easy API

The Worker uses two independent secrets:

  • UPSTREAM_TOKEN authenticates the local runtime at /sessions/:sessionId/upstream.
  • CONSUMER_TOKEN authenticates remote callers on other session paths.

The Worker routes each session ID to a Durable Object. An absent upstream returns 503 Session offline; a request that waits more than 30 seconds returns 504 Gateway Timeout from session upstream. Hibernation can reduce active Durable Object compute while the connection is idle, but it does not make Worker requests, storage, egress, domains, or account-plan charges free. Check Cloudflare Workers pricing for the account and plan in use.

Deploy the Worker

From a clean checkout:

git clone https://github.com/open-wa/wa-automate-nodejs.git
cd wa-automate-nodejs
corepack enable
pnpm install
cd packages/cf-proxy
pnpm exec wrangler login
pnpm exec wrangler whoami

wrangler.jsonc binds the SESSION_TUNNEL Durable Object to SessionTunnel. Set the secret values through Wrangler without committing them:

export OPENWA_PROXY_UPSTREAM_TOKEN="$(openssl rand -hex 32)"
export OPENWA_PROXY_CONSUMER_TOKEN="$(openssl rand -hex 32)"
printf '%s' "$OPENWA_PROXY_UPSTREAM_TOKEN" | pnpm exec wrangler secret put UPSTREAM_TOKEN
printf '%s' "$OPENWA_PROXY_CONSUMER_TOKEN" | pnpm exec wrangler secret put CONSUMER_TOKEN
pnpm exec wrangler deploy

Record the deployed hostname as OPENWA_PROXY_HOST, for example https://open-wa-proxy.<account>.workers.dev. The local runtime needs the upstream value; remote callers need the consumer value.

Contributors with an existing checkout can run pnpm install from the repository root and use pnpm --filter @open-wa/cf-proxy exec wrangler whoami followed by pnpm --filter @open-wa/cf-proxy exec wrangler deploy. Run secret put again only when rotating a value.

Attach a local session

Run the CLI on the machine that owns the WhatsApp browser session:

export OPENWA_PROXY_HOST='https://open-wa-proxy.<account>.workers.dev'
npx @open-wa/[email protected] \
  --session-id sales \
  --port 8080 \
  --proxy-host "$OPENWA_PROXY_HOST" \
  --proxy-token "$OPENWA_PROXY_UPSTREAM_TOKEN"

The CLI converts the HTTPS host to a WebSocket host and connects to /sessions/sales/upstream. WhatsApp Web and Easy API stay on the local machine; the Worker does not run the browser or change session readiness.

Consume a session

Use the consumer token in an Authorization: Bearer header rather than a URL query when making HTTP calls:

curl -i \
  "$OPENWA_PROXY_HOST/sessions/sales/api/getHostNumber" \
  -H "Authorization: Bearer $OPENWA_PROXY_CONSUMER_TOKEN"

For a command that is protected by the local Easy API key, send both credentials:

curl -i -X POST \
  "$OPENWA_PROXY_HOST/sessions/sales/api/sendText" \
  -H "Authorization: Bearer $OPENWA_PROXY_CONSUMER_TOKEN" \
  -H "X-API-Key: $OPENWA_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"args":["[email protected]","Hello through Cloudflare"]}'

Node clients can use the compatibility URL. The client converts it to the tunnel WebSocket and sends the consumer token to /sessions/<sessionId>/connect:

import { SocketClient } from '@open-wa/socket-client';

const client = await SocketClient.connect(
  `cf-proxy://open-wa-proxy.<account>.workers.dev?sessionId=sales&token=${encodeURIComponent(process.env.OPENWA_PROXY_CONSUMER_TOKEN)}`,
);
console.log(await client.getHostNumber());

The remote caller still receives the local Easy API's authentication or readiness response. A valid consumer token does not replace the local X-API-Key.

Troubleshooting

| Symptom | Command or observation | Expected result | Next action | | --- | --- | --- | --- | | Worker deploy fails | pnpm exec wrangler whoami and inspect wrangler.jsonc | The intended account is authenticated and SESSION_TUNNEL binds SessionTunnel. | Log in to the intended account and deploy from packages/cf-proxy; fix binding or migration data before retrying. | | Local runtime gets 401 Unauthorized Upstream | Compare --proxy-token with pnpm exec wrangler secret list. | The local runtime connects to the upstream WebSocket for the same session ID. | Rotate UPSTREAM_TOKEN, pass the exact value to the CLI, and restart it. | | Consumer gets 401 Unauthorized Consumer | Repeat the HTTP request with the Authorization header above. | A matching consumer token reaches the Worker. | Rotate CONSUMER_TOKEN if necessary and reconnect callers. | | Consumer gets 503 Session offline | Inspect the local runtime log for the upstream connection and match the session ID in the URL. | The upstream WebSocket is open for that session. | Start the local runtime or correct --session-id; then check local Easy API readiness. | | Consumer gets 504 | Call the same API path against http://127.0.0.1:8080. | The local API completes within 30 seconds. | Fix the local API, browser, or Easy API key before investigating Worker routing. |

Development

pnpm --filter @open-wa/cf-proxy dev

The Worker entrypoint is packages/cf-proxy/src/index.ts; the Durable Object is src/tunnel-do.ts.

Documentation

See the Cloudflare Session Proxy guide.

License

H-DNH 1.1 - Hippocratic + Do Not Harm