<!DOCTYPE HTML>
<html>
<head>
<title>plan9 - discord</title>
<style media="screen, handheld">
body { display: flex; flex-wrap: wrap; font-family: sans;}
header { flex-basis: 100%; flex-shrink: 0; }
article { flex-basis: 60%; padding-left: 1em; }
footer { flex-basis: 100%; flex-shrink: 0; }
header nav { display: flex; justify-content: space-between; }
nav a, header a { text-decoration: none ; color: inherit; }
header h1 span { margin-left: 1em; font-size: 50%; font-style: italic; }
.mainContent > nav { flex-basis: content; padding-right: 1vw; min-width: 16em; }
nav ul { display: flex; flex-direction: column; list-style-type: none; list-style-position: outside; padding-left: 0; }
nav li ul { padding-left: 0.6em }
footer { display: flex; justify-content: space-between; }
/* cut here to leave vanity behind */
body { margin:0; padding: 0; font-size: 84%; font-family: Helvetica, Verdana, Arial, 'Liberation Sans', FreeSans, sans-serif; }
a { text-decoration: none; color: }
a:hover { text-decoration: underline; }
.thisPage { color: black; }
/* header and top bar */
header nav { background-color: rgb(100,135,220); color: white; padding: 0.3em; border-bottom: 2px solid black; font-size: 91%; }
header h1 { background-color: #ff6d06; color: black; margin: 0; border-bottom: 2px solid black; font-weight: normal; padding: 0.25ex; font-size: 233%; }
header a:hover { text-decoration: none; }
/* sidebar */
.mainContent > nav { border-right: 1px solid #ddd; padding: 0; }
.mainContent > nav > div { border-bottom: 1px solid #ddd; }
.mainContent > nav > div a { color: rgb(0, 102, 204); display: block; text-transform: capitalize; font-weight: bold; padding: 0.25em 1ex 0.25em 2mm; font-size: 102%}
.mainContent > nav > div a:hover { color: white; background-color: rgb(100,135,220); border-left: black solid 0.2em; text-decoration: none; }
.mainContent > nav > div p { font-weight: bold; margin: 0 0 0.5em 2mm; padding: 1em 0 0 0; }
/* main copy */
article { padding: 0.5ex 0 5vh 1vw; }
article h1, article h2 { color: rgb(0,102,204); font-weight: bold; margin: 2em 0 0 0; border-bottom: 2px solid rgb(0,102,204); }
article h3, article h4, article h5 { color: rgb(0,102,204); font-weight: bold; margin: 2em 0 0 0; }
article h6, article h7, article h8 { color: rgb(0,102,204); font-weight: bold; margin: 2em 0 0 0; }
article a { color: rgb(0,102,204); }
article a:hover { color: rgb(100,135,220); }
article pre { font-size: 1.2em; }
/* footer */
footer { color: white; background-color: rgb(100,135,220); }
footer a { color: inherit; }
footer div { padding: 1em; }
/* tables */
table { border: 1px solid rgba(128,128,128,0.5); padding: 0; }
th { color: white; background-color: rgb(100,135,220); }
tr:nth-child(odd) { background-color: rgba(128,128,128,0.1) }
/* modifications */
img {
max-width: 100%;
border: 1px solid black;
}
body {
}
header h1 {
background-color: #c2d2c6;
}
html {
font-size: 1.2em;
}
header nav, footer {
background-color: #442a13;
}
code > pre {
border: 2px solid #442a13;
background-color: #c2d2c6;
width: max-content;
padding: 0 0.5em;
}
.mainContent > nav > div a, article a:hover {
color: #442a13;
}
.mainContent > nav > div a:hover {
color: #442a13;
background-color: #c2d2c6;
}
article h1, article h2 {
color: #c48f3b;
border-bottom: 2px solid #442a13;
}
article a, .thisPage, footer, header nav {
color: #c48f3b;
}
footer {
padding: 0.5em;
flex-shrink: 1;
flex-basis: unset;
}
header {
flex-basis: unset;
}
html {
display: flex;
min-height: 100%;
}
body {
flex-direction: column;
flex: 1;
background-color: #e3dfd7;
}
.mainContent {
display: flex;
flex-grow: 1;
} </style>
<link rel="shortcut icon" href="https://images.pmikkelsen.com/favicon.ico" type="image/vnd.microsoft.icon">
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<header>
<nav>
<div class="left">
<a href="https://pmikkelsen.com">notes</a> |
<a href="https://git.pmikkelsen.com">git</a> |
<a href="https://images.pmikkelsen.com">images</a> |
<a href="https://files.pmikkelsen.com">files</a> |
<a href="https://prolog.pmikkelsen.com">PProlog</a> |
<a href="https://apl.pmikkelsen.com">APL9</a> |
<a href="https://aplwc.org">aplwc</a>
</div>
<div class="right">
<a href="https://git.sr.ht/~pmikkelsen">sourcehut</a> |
<a href="https://9front.org">9front</a> |
<a href="https://openbsd.org">OpenBSD</a> |
<a href="https://dyalog.com">Dyalog</a>
</div>
</nav>
<h1><a href="../index.html">Peter's website <span id="headerSubTitle">- random notes</span></a></h1>
</header>
<div class=mainContent>
<nav id="side-bar">
<div>
<ul>
<li><a href="../APL-and-J/index.html">› APL and J/</a></li>
<li><a href="../OpenBSD/index.html">› OpenBSD/</a></li>
<li><a href="../contact.html">› contact</a></li>
<li><a href="../facts/index.html">› facts/</a></li>
<li><a href="../haskell/index.html">› haskell/</a></li>
<li><a href="../linux/index.html">› linux/</a></li>
<li><a href="../mainframe/index.html">› mainframe/</a></li>
<li><a href="../me/index.html">› me/</a></li>
<li><a href="../opinions/index.html">› opinions/</a></li>
<li><a href="index.html" class="thisPage">»<i> plan9/</i></a></li>
<li><ul>
<li><a href="basic_9p_server.html">› basic 9p server</a></li>
<li><a href="discord.html" class="thisPage">»<i> discord</i></a></li>
<li><a href="dns.html">› dns</a></li>
<li><a href="fonts.html">› fonts</a></li>
<li><a href="lets_encrypt.html">› lets encrypt</a></li>
<li><a href="mounting-9p-over-drawterm.html">› mounting 9p over drawterm</a></li>
<li><a href="network_booting.html">› network booting</a></li>
<li><a href="trellofs.html">› trellofs</a></li>
<li><a href="using_irc.html">› using irc</a></li>
<li><a href="webfs-websocket.html">› webfs websocket</a></li>
</ul></li>
<li><a href="../prolog/index.html">› prolog/</a></li>
<li><a href="../web/index.html">› web/</a></li>
</ul>
</div>
</nav>
<article>
<h1>Chatting on discord from 9front</h1>
<p>Sometimes you work with people who doesn't want to use the same communication tools as you do. A sad example is when your team members wants to use discord, and not something simpler like IRC. Oh well, gotta deal with it.</p>
<p>This is the reason I wrote a "discord bot" (ugh) which can run on your 9front system and allow you to chat on discord anyways.</p>
<h2>Example gif</h2>
<p>The example below just opens two chat windows with different channels in each. While it works both in acme and in the terminal, I like having everything together inside acme.</p>
<p><a href="https://images.pmikkelsen.com/discordgif.gif" /><img src="https://images.pmikkelsen.com/discordgif.gif" alt="An animated gif showing discord chats from 9front" /></a></p>
<h2>The code</h2>
<p>The project is made of a few scripts and a go program. The only thing that actually communicates with discord is the go program, and the scripts just makes it easier to send and recieve on the correct channels. The code is available <a href="https://git.sr.ht/~pmikkelsen/discordfront">here</a>, and there is a precompiled version of the go program included (compiled for 9front amd64).</p>
<h2>Usage</h2>
<p>To use the service, you must first create a bot on discord and get the access token. I personally found this step much more confusing then the actual coding itself, which either tells you something about my google skills, or about discord.. Oh, and then you must invite the bot to your discord server..</p>
<p>Next, the server part of the bot must be started:</p>
<code><pre>
`discordsrv YOURTOKEN`
</pre></code>
<p>This will post a pipe in /srv/discordfront, where messages can be send and recieved from, but you should not read from it directly. The <code>discordsrv</code> script does this for you as well, and it takes each line and dumps it in a nice readable format into <code>$home/lib/discord/logs/$serverName/$channelName</code> where the server name is the name of a discord server (or guild?), and the channel name is, well, the name of the channel.</p>
<p>Now that the server is started, you can either run <code>discordacme</code> which opens an acme with the file <code>$home/lib/discord/channels</code> open. This file is not handled by any of the scripts, so it is just a handy text file to keep shortcuts to various channels (see the gif for an example). Inside <code>discordacme</code>, the <code>openChat</code> command will open a new chat window, using the simpler <code>discord</code> script.</p>
<p>The <code>discord</code> script simply runs <code>tail -f</code> on the given channel's logfile while it reads messages from standard input and sends them to /srv/discordfront at the same time.</p>
<h2>Using remotely</h2>
<p>Since this program does not fetch previous messages, it might be a good idea to run the server part <code>discordsrv</code> on a machine that is always online, so that all messages gets logged. Since this is plan9, it is almost trivial to still use the client on your local machine, just by using <code>rimport</code> to import the relevant file trees from the server.</p>
<p>Here is what I do (in a seperate script which is run at startup):</p>
<code><pre>
#!/bin/rc
rfork
rimport -ac -p $serverhost /srv
rimport -c -p $serverhost /usr/glenda/lib/discord
discordacme
</pre></code>
<p>I don't even notice it is not running locally.</p>
<h2>Notes</h2>
<ul>
<li>
Yes, the names of the scripts suck.
</li><li>
Yes, there is a lot of missing functionality.
</li><li>
No, this has not been tested very much, it just seems to do the job well enough for now.
</li>
</ul>
</article>
</div>
<footer>
<a href="http://werc.cat-v.org">Powered by werc</a> © Peter Mikkelsen 2019-2025
</footer>
</body></html>