Skip to main content

clawdesk-tunnel

Secure webhook tunnel providing a reverse proxy for exposing the ClawDesk gateway to external webhook callbacks (e.g., Telegram, Slack, Discord webhooks) without a public IP address.

Dependencies

Internal: clawdesk-types

External: reqwest, tokio, serde, tracing, thiserror

Modules

ModuleDescription
clientTunnel client connecting to the relay server
relayRelay server accepting incoming webhook traffic
cryptoEnd-to-end encryption for tunnel traffic
configTunnel configuration and endpoint management

Key Types

/// Tunnel client configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TunnelConfig {
pub relay_url: String,
pub local_port: u16,
pub subdomain: Option<String>,
pub auth_token: Option<String>,
pub tls_enabled: bool,
}

/// Tunnel client — connects local server to relay
pub struct TunnelClient {
config: TunnelConfig,
connection: Option<TunnelConnection>,
}

impl TunnelClient {
/// Start the tunnel and return the public URL
pub async fn start(&mut self) -> Result<TunnelInfo, TunnelError> {
// Establish connection to relay
// Register subdomain
// Return public URL
}

/// Stop the tunnel
pub async fn stop(&mut self) -> Result<(), TunnelError> { /* ... */ }
}

/// Information about an active tunnel
#[derive(Debug, Clone)]
pub struct TunnelInfo {
pub public_url: String,
pub subdomain: String,
pub connected_at: chrono::DateTime<chrono::Utc>,
}

Example Usage

use clawdesk_tunnel::{TunnelClient, TunnelConfig};

let config = TunnelConfig {
relay_url: "wss://tunnel.clawdesk.dev".into(),
local_port: 1420,
subdomain: Some("my-bot".into()),
auth_token: Some("tunnel-token".into()),
tls_enabled: true,
};

let mut tunnel = TunnelClient::new(config);
let info = tunnel.start().await?;

println!("Tunnel active: {}", info.public_url);
// => https://my-bot.tunnel.clawdesk.dev

// Webhooks sent to the public URL are forwarded to localhost:1420

Configuration

[tunnel]
enabled = true
relay_url = "wss://tunnel.clawdesk.dev"
subdomain = "my-bot"
auth_token = "${TUNNEL_AUTH_TOKEN}"
tip

Use the tunnel for development and testing. For production, configure direct webhook URLs pointing to your public-facing server.