Snaps and discord-rpc

Hi there,

I wonder if it’s possible to add Discord Rich Presence via the old discord-rpc API to a snap? No matter if I run Discord itself from within a snap or the traditional .deb package from their website, I can’t get the discord integration working in a snap.

I assume just building and adding discord-rpc itself to the app is not enough due to the confined nature of a snap package?

Looking at the docs linked from that site, the IPC involves creating a websocket connection to 127.0.0.1 with one of a number of well known ports:

https://discord.com/developers/docs/topics/rpc#connecting

A snapped client should be able to access that fine if it has the network plug connected (which should auto-connect). As a TCP socket, the snap sandbox shouldn’t be a problem.

You should be able to see if the Discord app is listening by running netstat -lt, and look for something listening on localhost on a port in the range 6463-6472.

Specifically regarding the old method, Discord uses/used Unix sockets and places them in $XDG_RUNTIME_DIR ; every Snap has a different value for this and it’s why no Snap can use the legacy method, as well as the sandboxing restrictions. In theory a content interface could be defined to share Unix sockets between the Discord snap and another snap, but it’s not elegant IMO and it wouldn’t solve native apps being unable to find the right socket either.

The content interface would not currently help, since it won’t handle per-user mounts like this.

Thanks for the feedback! Unfortunately, I don’t see a port exposed by discord-rpc, so connecting network won’t be enough - it uses the discord-ipc-N socket instead.

I think the last resort is to do something like shown in https://github.com/flathub/com.discordapp.Discord/wiki/Rich-Precense-(discord-rpc), but I don’t know if that just refers to Discord distributed as FlatPak itself or FlatPaks connecting to Discord instead.

a little side note …

if such a sentence contains the words ‘connect’ and ‘socket’, you always want network-bind (which auto-connects as well) :wink:

If you’re an application trying to connect to the websocket server run by the Discord app, you shouldn’t need network-bind though. You’d only be establishing outbound connections.

Looks like that indeed it must be ‘something else’ regarding the discord-ipc-X socket file - Discord doesn’t open a local port, so I think the whole network- interfaces are not necessary here (I’m connecting them anyways due to different reasons).

I’ll see if I can do some symlinking magic, maybe the snaps are looking at a different location for the websocket due to the modified $XDG_RUNTIME_DIR.

I missed the text at the top of the page:

For now, RPC is in a private beta. We are not currently accepting any new developers into the program at this time.

So I guess the TCP/websockets based access is not generally available right now, but will be in future.

As far as workarounds go, a symlink probably won’t help since the access will be blocked by AppArmor. You might have luck bind mounting the socket: create an empty file with the right name in the snap’s private XDG_RUNTIME_DIR, then use mount --bind src target to mount the real socket file over the top of the empty file.

Unfortunately, this is not going to happen - this Discord RPC API is deprecated and got replaced with their (proprietary) Discord SDK, which is not GPL-complient and thus can’t be used in the application I’m snapping.

Thanks, I’ll give this a try and check if I can wrap the bind-mount in a launcher script.

No luck so far - the bind-mounts would require permissions the usual user won’t have, so I can’t simply wrap this into a launcher script.

Since the attept symlinking it (like shown in the FlatPak example) didn’t work too, I think we have to consider this as impossible - at least for know.

Unless somebody here has another idea of course :slight_smile: