Use Record for componentStanza context

componentStanza is a rediculous procedure with far too many branches, and as a
result it gets bits of context relavant to this branch or that one, but most
branches use only a few of the bits of context.  This change bundles the context
up into a record and only unpacks the fields used by a given branch.

While this does not fix the underlying design issues, it *is* more readable than
a long string of underscores that one must count through, and adding a new bit
of context will no longer require editing every single branch.  This seems like
a win.
Later versions have a bug
Add Origin-ID to Messages from Adhoc Bot

We noticed that Dino was de-duping our messages, so if we typed "help"
two times in a row, the second appeared to hang.

Worst, the helper text on parse fails is also the same every time, so if
you typed something wrong, you'd get a message telling you how to fix
it. But if you typed the wrong thing again, even on a different question
in the same minute, you'd just get nothing back.

Not good!

So after looking in their code, it looks like it uses the origin-id from
XEP-0359 if present, so we're now adding one.

The facilitate that, I've switched the "sendMessage" method from STM ()
to (Unexceptional m) => m (), to allow me to generate UUIDs

On the one hand, m () is a bit carte-blanche, but on the other hand STM
was perhaps exposing too much of the underlying implementation.

It doesn't have to be writing to a queue, that's just what we've got.

I did also consider an alternative implementation where we have a TMVar
with a UUID in it, and spin up a new thread that just constantly tries
to fill the TMVar with a UUID, just so the STM could stay and we could
atomically pull the UUID and write to the chan, but in the end that was
likely overcomplicated for what I wanted to do.

So I did this instead.
Merge branch 'cache-inbound-oob'

* cache-inbound-oob:
  Intrument cacheOOB
  Fetch any OOB URL from route and cache in jingle store
  Set up structure to cache OOB coming from a direct message route
Intrument cacheOOB

Send count to statsd every time we try to cache a URL, based on if the cache
attempt succeeds or fails.
Fetch any OOB URL from route and cache in jingle store

Now we actually cache the data.  Always assumes URLs are HTTP, but they always
are in practise and if one is not it will simply fail and in case of any error
we just pass the oob element through unmodified.
Set up structure to cache OOB coming from a direct message route

Does not actually fetch or cache any OOB data yet, but detects all such data and
has the right types to be able to do it. Replaces all OOB elements with new ones
and replaces all instances of gives URLs with new URLs, just no actual work is
done yet.
Merge branch 'better-thread-exceptions'

* better-thread-exceptions:
  Terminate on fatal exception
  Import forkXMPP from jingle-xmpp
Terminate on fatal exception

This retry loop is too naive for the current state of Cheogram. It is easy to
create a situation where this gets into a retry spin because some thread is
still holding on to the old connection to prosody but this is trying to restart
said connection.  If it gets so bad that exceptions are out here, just bail out
and let monit restart us.
Import forkXMPP from jingle-xmpp

This is a much safer version that rethrows exceptions to the parent instead of
just printing them and terminating the thread.
Translate Adhoc JID to Real JID in configure-direct-message-route

The adhoc commands that exist in the backend are wrapped and proxied
through cheogram, so it's not that different when the adhoc command is
talking to them vs when the client is talking to them. In both cases the
user is escaped and proxied (test\40example.com@cheogram.com)

But the internal command is different, because when a client is talking
to it directly, it really is direct. Whereas commands from the adhoc bot
appear to come from test\40example.com@cheogram.com, so it sees it as a
different user, which is bad.

So now I look at the JID and if it looks like one of our escaped ones,
then I unescape it when deciding which key to use.
Temporary fix for broken mmorph version
Get "configure-direct-message-route" Working with Adhoc Bot

This command works fine with a client that actually uses commands, but
it wasn't working as well with the bot.

There were two things standing it its way:

First, we built the list of adhoc commands by translating the JIDs of
your chosen backend to look like they're coming from cheogram, and then
adding our internal commands to that list.

But, when we were running the commands with the adhoc bot, we don't want
to convert the destinations, since we want to talk directly to the
backend. This makes sense, but meant we were missing out on internal
comamnds too!

So now I add the internal command to our list of untranslated commands
too (by translating an empty list, and then adding that) so the list of
commands we can run should match the list we show the user.

Second, we have a thread that receives messages, and that spins up a new
thread that looks (among other things) to see if this is for the adhoc
bot, and if so forwards the message on.

But in either case, the main "message received" logic would also look at
the stanza to see what it should do with it. That's not good, because in
this case where cheogram's configure-direct-message-route was talking to
its own adhoc bot, it was triggering some other branch which, triggered
some else case, and returned an error. To itself. But then that error
went through the same flow, which also triggered an error. And so it
would just go around and around logging error after error after error

So now I just have a case in my stanza handler that says "if this is an
adhoc message, don't do do anything" because I know the other thread's
already got it.
Also build for Ubuntu LTS

Mostly because that's what psycotica0 uses.
Fix path to the cheogram artifact
Fix CI

jingle-xmpp isn't on hackage (yet?) so we need to install it from git.

Because we install everything from hackage in CI instead of using Debian
packages, installing jingle-xmpp first can cause a version of random not
compatible with some cheogram dependencies to get installed. Easiest fix for
that is to just install a known-good version first, then everything works.
Do not crash when no StatsD listener running

StatsD sends should not block the process from working. Since it's a UDP send
I'm not completely sure how it even can fail, but at least when the target is
localhost it can and indeed did, making dev somewhat annoying.

This just swallows any exceptions produced by the StatsD.push action.
Inform the user that they can ask to cancel the command flow
Merge branch 'cv_more_better_fields'

* cv_more_better_fields:
  Adhoc Boolean Field
  Adhoc Fixed Field
  Adhoc Hidden Field
  Adhoc JID Field
  Adhoc Display List Field Values
  Standardize on (++)