Client

Proxies

gogram ships four concrete proxy types: Socks5Proxy, Socks4Proxy, HttpProxy, and MTProxy. They all implement the same Proxy interface, so you wire them in the same way.

When you need a proxy

Common reasons:

  • Outbound 443 is blocked on the Telegram DC IP ranges. Run a SOCKS5 or HTTP proxy outside the firewall and route through it.
  • Telegram is region-restricted. An MTProxy or SOCKS5 on a server in a friendlier region.
  • You want a stable egress IP for IP-allowlists on a downstream service that your bot calls.
  • You need to bypass deep packet inspection — MTProxy looks like random TLS traffic.

The Proxy interface

ClientConfig.Proxy takes anything that satisfies the telegram.Proxy interface. Each concrete type embeds BaseProxy (host + port) and adds whatever extra fields its protocol needs. You hand the populated struct to the client and gogram dials through it.

SOCKS5

client, _ := telegram.NewClient(telegram.ClientConfig{
	AppID:   12345,
	AppHash: "...",
	Session: "session.dat",
	Proxy: &telegram.Socks5Proxy{
		BaseProxy: telegram.BaseProxy{Host: "127.0.0.1", Port: 1080},
	},
})
client, _ := telegram.NewClient(telegram.ClientConfig{
	AppID:   12345,
	AppHash: "...",
	Session: "session.dat",
	Proxy: &telegram.Socks5Proxy{
		BaseProxy: telegram.BaseProxy{Host: "127.0.0.1", Port: 1080},
	},
})

gogram dials the SOCKS5 proxy, asks it to open a TCP connection to the chosen DC, and runs MTProto over the resulting stream. The proxy never sees plaintext — everything past the SOCKS handshake is encrypted end-to-end with the DC.

With username/password auth:

Proxy: &telegram.Socks5Proxy{
	BaseProxy: telegram.BaseProxy{Host: "proxy.example.com", Port: 1080},
	Username:  "user",
	Password:  os.Getenv("PROXY_PASS"),
},
Proxy: &telegram.Socks5Proxy{
	BaseProxy: telegram.BaseProxy{Host: "proxy.example.com", Port: 1080},
	Username:  "user",
	Password:  os.Getenv("PROXY_PASS"),
},

SOCKS4

Proxy: &telegram.Socks4Proxy{
	BaseProxy: telegram.BaseProxy{Host: "proxy.example.com", Port: 1080},
	UserID:    "ident",
},
Proxy: &telegram.Socks4Proxy{
	BaseProxy: telegram.BaseProxy{Host: "proxy.example.com", Port: 1080},
	UserID:    "ident",
},

Older protocol, identifies via a userid string rather than username/password. Rare in modern deployments but supported.

HTTP CONNECT

For corporate networks that only allow outbound through an HTTP forward proxy:

Proxy: &telegram.HttpProxy{
	BaseProxy: telegram.BaseProxy{Host: "proxy.corp.local", Port: 8080},
	Username:  "alice",
	Password:  os.Getenv("HTTP_PROXY_PASS"),
},
Proxy: &telegram.HttpProxy{
	BaseProxy: telegram.BaseProxy{Host: "proxy.corp.local", Port: 8080},
	Username:  "alice",
	Password:  os.Getenv("HTTP_PROXY_PASS"),
},

The proxy must understand the CONNECT verb. Username and password are optional.

MTProxy

Telegram's own proxy protocol. To a passive observer it looks like random TLS traffic, which is useful when your network actively inspects connection contents. You get a host/port plus a hex secret from whoever runs the proxy.

Proxy: &telegram.MTProxy{
	BaseProxy: telegram.BaseProxy{Host: "mtproxy.example.com", Port: 443},
	Secret:    "ee" + "00112233445566778899aabbccddeeff" + "676f6f676c652e636f6d",
},
Proxy: &telegram.MTProxy{
	BaseProxy: telegram.BaseProxy{Host: "mtproxy.example.com", Port: 443},
	Secret:    "ee" + "00112233445566778899aabbccddeeff" + "676f6f676c652e636f6d",
},

Secret formats: the bare 16-byte hex secret, the dd-prefixed 17-byte secret for random padding, or the ee-prefixed fake-TLS secret that includes the cover domain. gogram accepts all three.

Proxies and WebSocket

When you combine a proxy with UseWebSocketTLS: true, the chain becomes: you → proxy → WSS to *.web.telegram.org→ MTProto. SOCKS5, SOCKS4, and HTTP proxies handle this transparently. MTProxy does its own framing on top of raw TCP and is incompatible with WSS — stick to the default TCP transport when using MTProxy.