hookshot/1.0.0/print.html
2022-03-30 11:53:16 +01:00

1436 lines
97 KiB
HTML

<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Matrix Hookshot</title>
<meta name="robots" content="noindex" />
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="docs/_site/style.css">
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded "><a href="hookshot.html"><strong aria-hidden="true">1.</strong> Hookshot</a></li><li class="chapter-item expanded "><a href="setup.html"><strong aria-hidden="true">2.</strong> Setup</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="setup/sample-configuration.html"><strong aria-hidden="true">2.1.</strong> Sample Configuration</a></li><li class="chapter-item expanded "><a href="setup/github.html"><strong aria-hidden="true">2.2.</strong> GitHub</a></li><li class="chapter-item expanded "><a href="setup/gitlab.html"><strong aria-hidden="true">2.3.</strong> GitLab</a></li><li class="chapter-item expanded "><a href="setup/jira.html"><strong aria-hidden="true">2.4.</strong> JIRA</a></li><li class="chapter-item expanded "><a href="setup/webhooks.html"><strong aria-hidden="true">2.5.</strong> Webhooks</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/dynamic_rooms.html"><strong aria-hidden="true">3.1.</strong> Dynamic Rooms</a></li><li class="chapter-item expanded "><a href="usage/auth.html"><strong aria-hidden="true">3.2.</strong> Authenticating</a></li><li class="chapter-item expanded "><a href="usage/room_configuration.html"><strong aria-hidden="true">3.3.</strong> Room Configuration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/room_configuration/github_repo.html"><strong aria-hidden="true">3.3.1.</strong> GitHub Repo</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="metrics.html"><strong aria-hidden="true">4.</strong> Metrics</a></li><li class="chapter-item expanded "><a href="advanced/provisioning.html"><strong aria-hidden="true">5.</strong> Advanced</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="advanced/provisioning.html"><strong aria-hidden="true">5.1.</strong> Provisioning</a></li><li class="chapter-item expanded "><a href="advanced/workers.html"><strong aria-hidden="true">5.2.</strong> Workers</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Matrix Hookshot</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/half-shot/matrix-hookshot" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="matrix-hookshot"><a class="header" href="#matrix-hookshot">matrix-hookshot</a></h1>
<p><em>Previously matrix-github</em></p>
<p><a href="https://matrix.to/#/#hookshot:half-shot.uk"><img src="https://img.shields.io/matrix/github-bridge:half-shot.uk.svg?server_fqdn=chaotic.half-shot.uk&amp;label=%23hookshot:half-shot.uk&amp;logo=matrix" alt="#hookshot:half-shot.uk" /></a>
<a href="https://hub.docker.com/r/halfshot/matrix-hookshot"><img src="https://img.shields.io/docker/v/halfshot/matrix-hookshot" alt="Docker Image Version (latest by date)" /></a></p>
<p>A bridge between Matrix and multiple project management services, such as GitHub, GitLab and JIRA.</p>
<h2 id="featureset"><a class="header" href="#featureset">Featureset</a></h2>
<p>This bridge bridges:</p>
<ul>
<li>GitHub
<ul>
<li>Webhooks (new issues, pull requests, releases etc)</li>
<li>Commands (create issues, assign issues, start workflows etc)</li>
</ul>
</li>
<li>GitLab
<ul>
<li>Webhooks (new issues, merge requests etc)</li>
<li>Commands</li>
</ul>
</li>
<li>Jira
<ul>
<li>Webhooks (new issues, issue changes)</li>
<li>Commands (create new issues)</li>
</ul>
</li>
<li>Generic webhooks
<ul>
<li>Webhooks (via GET, PUT or POST with optional transformation functions)</li>
</ul>
</li>
</ul>
<h2 id="setup"><a class="header" href="#setup">Setup</a></h2>
<p><a href="https://half-shot.github.io/matrix-hookshot/setup.html">See the setup guide</a></p>
<h2 id="documentation"><a class="header" href="#documentation">Documentation</a></h2>
<p>Documentation can be found on <a href="https://matrix-org.github.io/matrix-appservice-irc">GitHub Pages</a>.</p>
<p>You can build the documentaion yourself by:</p>
<pre><code class="language-sh"># cargo install mdbook
mdbook build
sensible-browser book/index.html
</code></pre>
<h2 id="contact"><a class="header" href="#contact">Contact</a></h2>
<p>TODO...</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="getting-setup"><a class="header" href="#getting-setup">Getting setup</a></h1>
<p>This page explains how to set up Hookshot for use with a Matrix homeserver.</p>
<h2 id="requirements"><a class="header" href="#requirements">Requirements</a></h2>
<p>Hookshot is fairly light on resources, and can run in as low as 100MB or so of memory. Hookshot memory requirements
may increase depending on the traffic and the number of rooms bridged.</p>
<h2 id="local-installation"><a class="header" href="#local-installation">Local installation</a></h2>
<p>This bridge requires at least Node 12 (though 16 is preferred), and Rust installed.</p>
<p>To install Node.JS, <a href="https://github.com/nvm-sh/nvm">nvm</a> is a good option.</p>
<p>To install Rust, <a href="https://rustup.rs/">rustup</a> is the preferred solution to stay up to date.</p>
<p>To clone and install, run:</p>
<pre><code class="language-bash">git clone git@github.com:Half-Shot/matrix-hookshot.git
cd matrix-hookshot
yarn # or npm i
</code></pre>
<p>Starting the bridge (after configuring it), is a matter of running <code>yarn start</code>.</p>
<h2 id="installation-via-docker"><a class="header" href="#installation-via-docker">Installation via Docker</a></h2>
<p>To get started quickly, you can use the Docker image <a href="https://hub.docker.com/r/halfshot/matrix-hookshot"><code>halfshot/matrix-hookshot</code></a></p>
<pre><code class="language-bash">docker run \
--name matrix-hookshot \
-d \
-p 9993:9993 \ # Homeserver port
-p 9000:9000 \ # Webhook port
-p 9002:9002 \ # Metrics port
-v /etc/matrix-hookshot:/data \
halfshot/matrix-hookshot:latest
</code></pre>
<p>Where <code>/etc/matrix-hookshot</code> would contain the configuration files <code>config.yml</code> and <code>registration.yml</code>, along with any other files needed.</p>
<h2 id="configuration"><a class="header" href="#configuration">Configuration</a></h2>
<p>Copy the <code>config.sample.yml</code> to a new file <code>config.yml</code>. The sample config is also hosted
<a href="./setup/sample-configuration.html">here</a> for your convienence.</p>
<p>You should read and fill this in as the bridge will not start without a complete config.</p>
<p>Copy <code>registration.sample.yml</code> into <code>registration.yml</code> and fill in:</p>
<ul>
<li>At a minimum, you will need to replace the <code>as_token</code> and <code>hs_token</code> and change the domain part of the namespaces.</li>
</ul>
<p>You will need to link the registration file to the homeserver. Consult your homeserver documentation
on how to add appservices. <a href="https://matrix-org.github.io/synapse/latest/application_services.html">Synapse documents the process here</a></p>
<h3 id="listeners-configuration"><a class="header" href="#listeners-configuration">Listeners configuration</a></h3>
<p>You will need to configure some listeners to make the bridge functional.</p>
<pre><code class="language-yaml"> # (Optional) HTTP Listener configuration.
# Bind resource endpoints to ports and addresses.
# 'resources' may be any of webhooks, widgets, metrics, provisioning, appservice
#
- port: 9000
bindAddress: 0.0.0.0
resources:
- webhooks
- widgets
- port: 9001
bindAddress: 127.0.0.1
resources:
- metrics
- provisioning
</code></pre>
<p>At a minimum, you should bind the <code>webooks</code> resource to a port and address. You can have multiple resources on the same
port, or one on each.</p>
<p>You will also need to make this port accessible to the internet so services like GitHub can reach the bridge. It
is reccomended to factor hookshot into your load balancer configuration, but currrently this process is left as an
excercise to the user.</p>
<h3 id="services-configuration"><a class="header" href="#services-configuration">Services configuration</a></h3>
<p>You will need to configure some services. Each service has it's own documentation file inside the the setup subdirectory.</p>
<ul>
<li><a href="./setup/github.html">GitHub</a></li>
<li><a href="./setup/gitlab.html">GitLab</a></li>
<li><a href="./setup/jira.html">Jira</a></li>
<li><a href="./setup/webhooks.html">Webhooks</a></li>
</ul>
<div style="break-before: page; page-break-before: always;"></div><h1 id="sample-configuration"><a class="header" href="#sample-configuration">Sample Configuration</a></h1>
<p>Below is a sample bridge configuration file. The configuration file
can be tweaked to change the behaviour of your bridge. A bridge of the server is
required to apply any changes made to this file.</p>
<pre><code class="language-yaml"># This is an example configuration file
bridge:
# Basic homeserver configuration
#
domain: example.com
url: http://localhost:8008
mediaUrl: http://example.com
port: 9993
bindAddress: 127.0.0.1
github:
# (Optional) Configure this to enable GitHub support
#
auth:
# Authentication for the GitHub App.
#
id: 123
privateKeyFile: github-key.pem
webhook:
# Webhook settings for the GitHub app.
#
secret: secrettoken
oauth:
# (Optional) Settings for allowing users to sign in via OAuth.
#
client_id: foo
client_secret: bar
redirect_uri: https://example.com/bridge_oauth/
defaultOptions:
# (Optional) Default options for GitHub connections.
#
showIssueRoomLink: false
gitlab:
# (Optional) Configure this to enable GitLab support
#
instances:
gitlab.com:
url: https://gitlab.com
webhook:
secret: secrettoken
jira:
# (Optional) Configure this to enable Jira support
#
webhook:
secret: secrettoken
oauth:
client_id: foo
client_secret: bar
redirect_uri: https://example.com/bridge_oauth/
generic:
# (Optional) Support for generic webhook events. `allowJsTransformationFunctions` will allow users to write short transformation snippets in code, and thus is unsafe in untrusted environments
#
enabled: false
urlPrefix: https://example.com/mywebhookspath/
allowJsTransformationFunctions: false
userIdPrefix: webhooks_
provisioning:
# (Optional) Provisioning API for integration managers
#
secret: &quot;!secretToken&quot;
passFile:
# A passkey used to encrypt tokens stored inside the bridge.
# Run openssl genpkey -out passkey.pem -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:4096 to generate
#
passkey.pem
bot:
# (Optional) Define profile information for the bot user
#
displayname: GitHub Bot
avatar: mxc://half-shot.uk/2876e89ccade4cb615e210c458e2a7a6883fe17d
metrics:
# (Optional) Prometheus metrics support
#
enabled: true
queue:
# (Optional) Message queue / cache configuration options for large scale deployments
#
monolithic: true
port: 6379
host: localhost
logging:
# (Optional) Logging settings. You can have a severity debug,info,warn,error
#
level: info
listeners:
# (Optional) HTTP Listener configuration.
# Bind resource endpoints to ports and addresses.
# 'resources' may be any of webhooks, widgets, metrics, provisioning, appservice
#
- port: 9000
bindAddress: 0.0.0.0
resources:
- webhooks
- widgets
- port: 9001
bindAddress: 127.0.0.1
resources:
- metrics
- provisioning
</code></pre>
<div style="break-before: page; page-break-before: always;"></div><h1 id="setting-up-github"><a class="header" href="#setting-up-github">Setting up GitHub</a></h1>
<h2 id="github-app"><a class="header" href="#github-app">GitHub App</a></h2>
<p>This bridge requires a <a href="https://github.com/settings/apps/new">GitHub App</a>. You will need to create one.</p>
<p>Most of the configuration can be left up to you, but the important points are:</p>
<ul>
<li>The callback URL should be set if you plan to use OAuth.</li>
<li>The webhook URL should point to the public address of your hookshot instance, at the <code>/</code> path. A secret <strong>must</strong> be given.</li>
<li>A client secret should be generated and stored.</li>
</ul>
<p>You will need to enable the following permissions:</p>
<ul>
<li>Repository
<ul>
<li>Actions (<code>read</code>)</li>
<li>Contents (<code>read</code>)</li>
<li>Discussions (<code>read &amp; write</code>)</li>
<li>Issues (<code>read &amp; write</code>)</li>
<li>Metadata </li>
<li>Projects (<code>read &amp; write</code>)</li>
<li>Pull requests (<code>read &amp; write</code>)</li>
</ul>
</li>
<li>Organisation
<ul>
<li>Discussions (<code>read</code>)</li>
</ul>
</li>
</ul>
<p>Hookshot handles the following webhook event types:</p>
<ul>
<li>Commit comment</li>
<li>Create</li>
<li>Delete</li>
<li>Discussion</li>
<li>Discussion comment</li>
<li>Issue comment</li>
<li>Issues</li>
<li>Project</li>
<li>Project card</li>
<li>Project column</li>
<li>Pull request</li>
<li>Pull request review</li>
<li>Pull request review comment</li>
<li>Push</li>
<li>Release</li>
<li>Repository</li>
<li>Workflow run</li>
</ul>
<p>You can disable any of these to disable the events being handled in Hookshot.</p>
<p>Once you have setup your app, you can move onto configuring the bridge:</p>
<h2 id="configuration-1"><a class="header" href="#configuration-1">Configuration</a></h2>
<p>The GitHub service requires a few connection options.</p>
<pre><code class="language-yaml">github:
auth:
id: 123
privateKeyFile: github-key.pem
webhook:
secret: secrettoken
oauth:
client_id: foo
client_secret: bar
redirect_uri: https://example.com/bridge_oauth/
defaultOptions:
showIssueRoomLink: false
</code></pre>
<p>In the <code>auth</code> section, you will need to supply the <strong>App ID</strong> given in your GitHub App page.
You should also supply the page to a generated private key file.</p>
<p>The <code>webhook</code> section takes a secret, which is <strong>Webhook secret</strong> on the GitHub App page.</p>
<p>The <code>oauth</code> section should include both the <strong>Client ID</strong> and <strong>Client Secret</strong> on the GitHub App page.
The <code>redirect_uri</code> value must be the <strong>public</strong> path to <code>/oauth</code> on the webhooks path. E.g. if your load balancer
points <code>https://example.com/hookshot</code> to the bridge's webhooks port, you should use the path <code>https://example.com/hookshot/oauth</code>.
This value MUST exactly match the <strong>Callback URL</strong> on the GitHub App page.</p>
<p><code>defaultOptions</code> allows you to set some defaults for room connections. Options listed on <a href="setup/../usage/room_configuration/github_repo.html#configuration">this page</a>
are supported.</p>
<h2 id="next-steps"><a class="header" href="#next-steps">Next steps</a></h2>
<p>If you have followed these steps correctly, GitHub should now be configured with hookshot 🥳.</p>
<p>You can now follow the guide on <a href="setup/../usage/auth.html">authenticating with GitHub</a>, and then <a href="setup/../usage/room_configuration/github_repo.html#setting-up">bridging a room</a></p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="gitlab"><a class="header" href="#gitlab">GitLab</a></h1>
<h2 id="configuration-2"><a class="header" href="#configuration-2">Configuration</a></h2>
<p>GitLab configuration is fairly straight-forward:</p>
<pre><code class="language-yaml"> # (Optional) Configure this to enable GitLab support
#
instances:
gitlab:
url: https://gitlab.com
webhook:
secret: secrettoken
</code></pre>
<p>You neeed to list all the instances you plan to connect to in the <code>config.yml</code>. This is
used so that users can give a short name like <code>gitlab</code> or <code>matrix.org</code> when they want
to specify an instance.</p>
<p>The webhooks secret should be generated, for use in your repositories.</p>
<h2 id="adding-a-repository"><a class="header" href="#adding-a-repository">Adding a repository</a></h2>
<p>Adding a repository is a case of navigating to the settings page, and then adding a new webhook.
You will want to give the URL of the public address for the hookshot webhooks port on the <code>/</code> path.</p>
<p>You should add the events you wish to trigger on. Hookshot currently supports:</p>
<ul>
<li>Push events</li>
<li>Tag events</li>
<li>Issues events</li>
<li>Merge request events</li>
<li>Releases events</li>
</ul>
<p>You will need to do this each time you want to a repository to hookshot. </p>
<p>To then bridge a room to GitLab, you will need to add a <code>uk.half-shot.matrix-hookshot.gitlab.repository</code>
<em>state event</em> to a room containing a content of:</p>
<pre><code class="language-json5">{
&quot;instance&quot;: &quot;gitlab&quot;, // your instance name
&quot;path&quot;: &quot;yourusername/repo&quot; // the full path to the repo
}
</code></pre>
<p>Once this is done, you are bridged 🥳.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="jira"><a class="header" href="#jira">JIRA</a></h1>
<h2 id="adding-a-webhook-to-a-jira-organisation"><a class="header" href="#adding-a-webhook-to-a-jira-organisation">Adding a webhook to a JIRA Organisation</a></h2>
<p>This should be done for all JIRA organisations you wish to bridge. The steps may differ for SaaS and on-prem, but
you need to go to the <code>webhooks</code> configuration page under Settings &gt; System.</p>
<p>Next, add a webhook that points to <code>/</code> on the public webhooks address for hookshot. You should also include a
secret value by appending <code>?secret=your-webhook-secret</code>. The secret value can be anything, but should
be reasonably secure and should also be stored in the <code>config.yml</code> file.</p>
<p>Ensure that you enable all the events that you wish to be bridge.</p>
<h2 id="jira-oauth"><a class="header" href="#jira-oauth">JIRA OAuth</a></h2>
<section class="notice">
The JIRA service currently only supports atlassian.com (JIRA SaaS) when handling user authentication.
Support for on-prem deployments is hoping to land soon.
</section>
<p>You will need a Atlassain account with the ability to use the developer tools in order to create the app.</p>
<p>You'll first need to head to https://developer.atlassian.com/console/myapps/create-3lo-app/ to create a
&quot;OAuth 2.0 (3LO)&quot; integration.</p>
<p>Once named and created, you will need to:
- Enable the User REST, Jira Platform REST and User Identity APIs under Permissions.
- Use rotating tokens under Authorisation.
- Set a callback url. This will be the public URL to hookshot with a path of <code>/jira/oauth</code>.
- Copy the client ID and Secret from Settings</p>
<h2 id="configuration-3"><a class="header" href="#configuration-3">Configuration</a></h2>
<p>You can now set some configuration in the bridge <code>config.yml</code></p>
<pre><code class="language-yaml">jira:
webhook:
secret: auto-generated-config
oauth:
client_id: s2tkGiqj5TS1SOBlDP9Mc3e8m15w07pL
client_secret: wQcADRX_rw_6VmuFBOYPi6H9Q_Lh2fNsqTu520cX5IdqoUETH1zStFItmkDtEJtA
redirect_uri: https://f6bd-82-129-52-204.ngrok.io/jira/oauth
</code></pre>
<p>You can leave the <code>oauth</code> section blank if you are not planning to use those capabilities.</p>
<p>The <code>redirect_uri</code> value must be the <strong>public</strong> path to <code>/jira/oauth</code> on the webhooks path. E.g. if your load balancer
points <code>https://example.com/hookshot</code> to the bridge's webhooks port, you should use the path <code>https://example.com/hookshot/oauth</code>.
This value MUST exactly match the <strong>Callback URL</strong> on the JIRA integration page page.</p>
<h2 id="next-steps-1"><a class="header" href="#next-steps-1">Next steps</a></h2>
<p>If you have followed these steps correctly, JIRA should now be configured with hookshot 🥳.</p>
<p>You can now follow the guide on <a href="setup/../usage/auth.html#jira">authenticating with JIRA</a>.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="webhooks"><a class="header" href="#webhooks">Webhooks</a></h1>
<p>Hookshot supports generic webhook support so that services can send messages into Matrix rooms without being aware of the Matrix protocol.</p>
<h2 id="features"><a class="header" href="#features">Features</a></h2>
<p>The webhook connection supports sending messages into a single Matrix room, by hitting an API endpoint.</p>
<h2 id="configuration-4"><a class="header" href="#configuration-4">Configuration</a></h2>
<p>You will need to add the following configuration to the config file.</p>
<pre><code class="language-yaml">generic:
enabled: true
urlPrefix: https://example.com/mywebhookspath/
allowJsTransformationFunctions: false
</code></pre>
<p>The bridge listens for incoming webhooks on the host and port provided in the <code>webhook</code> configuration section. For example,
a internal hook URL (using the default port) would look like <code>http://0.0.0.0:9000/abcdef</code>.</p>
<p><code>urlPrefix</code> describes the public facing URL of your webhook handler. For instance, if your load balancer redirected
webhook requests from <code>https://example.com/mywebhookspath</code> to the bridge, an example webhook URL would look like:
<code>https://example.com/mywebhookspath/abcdef</code>.</p>
<h2 id="adding-a-webhook"><a class="header" href="#adding-a-webhook">Adding a webhook</a></h2>
<p>To add a webhook to your room:</p>
<ul>
<li>Invite the bot user to the room.</li>
<li>Make sure the bot able to send state events (usually the Moderator power level in clients)</li>
<li>Say <code>!setup webhook</code></li>
<li>The bot will respond with the webhook URL to be sent to services.</li>
</ul>
<h2 id="endpoint-options"><a class="header" href="#endpoint-options">Endpoint options</a></h2>
<p>The webhook endpoint can handle a <code>GET</code>,<code>POST</code> or <code>PUT</code> request.</p>
<p>If the request is a <code>GET</code> request, the query parameters are assumed to be the body.
otherwise, the body of the request should be a JSON payload.</p>
<p>If the body contains a <code>text</code> key, then that key will be used as a message body in Matrix.
If the body <em>also</em> contains a <code>username</code> key, then the message will be prepended by the given username.</p>
<p>Otherwise, the full JSON payload will be sent to the room. This can be adapted into a message by creating a <strong>JavaScript transformation function</strong>.</p>
<h2 id="javascript-transformations"><a class="header" href="#javascript-transformations">JavaScript Transformations</a></h2>
<section class="notice">
Although every effort has been made to securely sandbox scripts, running untrusted code from users is always risky. Ensure safe permissions
in your room to prevent users from tampering with the script.
</section>
<p>This bridge support creating small JavaScript snippets to translate an incoming webhook payload into a message for the room, giving
you a very powerful ability to generate messages based on whatever input is coming in.</p>
<p>The input is parsed and exectuted within a seperate JavaScript Virtual Machine context, and is limited to an execution time of 2 seconds.
With that said, the feature is disabled by default and <code>allowJsTransformationFunctions</code> must be enabled in the config.</p>
<p>The code snippets can be edited by editing the Matrix state event corresponding to this connection (with a state type of <code>uk.half-shot.matrix-hookshot.generic.hook</code>).
Because this is a fairly advanced feature, this documentation won't go into how to edit state events from your client.
Please seek out documentation from your client on how to achieve this. </p>
<p>The script string should be set within the state event under the <code>transformationFunction</code> key.</p>
<h3 id="script-api"><a class="header" href="#script-api">Script API</a></h3>
<p>The scripts have a very minimal API. The execution environment will contain a <code>data</code> field, which will be the body
of the incoming request (JSON will be parsed into an <code>Object</code>). Scripts are executed syncronously and a variable <code>result</code>
is expected to be set in the execution, which will be used as the text value for the script. <code>result</code> will be automatically
transformed by a Markdown parser.</p>
<p>If the script contains errors or is otherwise unable to work, the bridge will send an error to the room.</p>
<h3 id="example-script"><a class="header" href="#example-script">Example script</a></h3>
<p>Where <code>data</code> = <code>{&quot;counter&quot;: 5, &quot;maxValue&quot;: 4}</code></p>
<pre><code class="language-js">if (data.counter &gt; data.maxValue) {
result = `**Oh no!** The counter has gone over by ${data.counter - data.maxValue}`
} else {
result = `*Everything is fine*, the counter is under by ${data.maxValue - data.counter}`
}
</code></pre>
<div style="break-before: page; page-break-before: always;"></div><h1 id="usage"><a class="header" href="#usage">Usage</a></h1>
<p>This section covers how to use the bridge, once it's set up. We break these
down into categories:</p>
<ul>
<li>Authentication: How to connect your user account to a remote service to use
rich commands.</li>
<li>Room Connections: How to start connecting rooms to services.</li>
</ul>
<p>If you are looking for help on what bot commands you can run in a room, you can
refer to the help information by saying*:</p>
<ul>
<li><code>!gh help</code> in rooms connected to GitHub.</li>
<li><code>!gl help</code> in rooms connected to GitLab.</li>
<li><code>!jira help</code> in rooms connected to JIRA.</li>
</ul>
<p>*the prefix may vary if the <code>commandPrefix</code> configuration in the room is set.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="dynamic-rooms"><a class="header" href="#dynamic-rooms">Dynamic Rooms</a></h1>
<section class="notice">
Anyone who has access to your homeserver can query these aliases (even over federation), and aliases
do not support checking if a user is authorised to view the content before creation. If you are bridging non-public
content, it is advisable to disable this feature.
</section>
<p>Some bridges support dynamically creating rooms that point to resources based on an alias given by a user.</p>
<p>Presently, the following are supported:</p>
<ul>
<li><code>#github_$owner:example.com</code> - For a Matrix space containing a user's discussions and repositories</li>
<li><code>#github_$owner_$repo:example.com</code> - For GitHub repositories</li>
<li><code>#github_$owner_$repo_$issuenumber:example.com</code> - For GitHub issues</li>
<li><code>#github_disc_$owner_$repo:example.com</code> - For GitHub discussions for a repository</li>
</ul>
<p>Where $word is replaced by the appropriate value.</p>
<p>(Some of these may not be supported, depending on bridge configuration and registration file changes)</p>
<h2 id="disabling-support"><a class="header" href="#disabling-support">Disabling support</a></h2>
<p>This feature can be disabled simply by removing alias fields from the registration file.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="authenticating"><a class="header" href="#authenticating">Authenticating</a></h1>
<p>To authenticate with services, you must first have a DM room with the bridge set up. In this guide,
we are going to assume the bot is called <code>@hookshot:example.com</code> but this will vary for your setup. For all
the instructions below, commands should only be executed in the DM room.</p>
<h2 id="github"><a class="header" href="#github">GitHub</a></h2>
<p>You can authenticate via OAuth or a Personal Access Token (PAT) when using GitHub. Authentication is required
when trying to bridge GitHub resources into rooms.</p>
<section class="notice">
Please note that you will need a Personal Access Token in order to bridge your personal GitHub notifications.
This is a limitation of GitHub's API.
</section>
<p>To authenticate with a personal access token:</p>
<ol>
<li>
<p>Open <a href="https://github.com/settings/tokens">https://github.com/settings/tokens</a> (Github &gt; Settings &gt; Developer Settings / Personal access tokens)</p>
</li>
<li>
<p>Click <strong>Generate new token</strong></p>
</li>
<li>
<p>Give it a good name, and a sensible expiration date. For scopes you will need:</p>
<ul>
<li>Repo (to access repo information)
<ul>
<li>public_repo</li>
<li>repo:status</li>
</ul>
</li>
<li>Workflow (if you want to be able to launch workflows / GitHub actions from Matrix)</li>
<li>Notifications (if you want to bridge in your notifications to Matrix)</li>
<li>User
<ul>
<li>read:user</li>
</ul>
</li>
<li>write:discussion (for GitHub discussion support)
<ul>
<li>read:discussion</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Send the generated token to the bridge by saying <code>github setpersonaltoken %your-token%</code>. You can redact
the message afterwards if you like.</p>
</li>
<li>
<p>The bridge will have connected you. You can check the status at any time by saying <code>github hastoken</code></p>
</li>
</ol>
<h2 id="gitlab-1"><a class="header" href="#gitlab-1">GitLab</a></h2>
<p>You can authenticate with GitLab by supplying a Personal Access Token. OAuth-style authentication isn't supported
yet.</p>
<ul>
<li>You will need to have configured a GitLab instance in your config.yml for the instance you want to login to.</li>
<li>Open https://%instance%/-/profile/personal_access_tokens (GitLab &gt; User Settings &gt; Access Tokens), where instance is your GitLab instance address.
<ul>
<li>For the public GitLab server, this would be &quot;gitlab.com&quot;</li>
</ul>
</li>
<li>Give it a good name, and a sensible expiration date. For scopes you will need to tick <code>api</code>.</li>
<li>Send the generated token to the bridge by saying <code>gitlab personaltoken %instance% %your-token%</code>. You can redact
the message afterwards if you like.</li>
<li>The bridge will have connected you. You can check the status at any time by saying <code>gitlab hastoken %instance% </code></li>
</ul>
<h2 id="jira-1"><a class="header" href="#jira-1">JIRA</a></h2>
<p>You can login to JIRA via OAuth. This means you will need to have configured OAuth support in your <code>config.yml</code>, and
have the endpoints required accessible from the internet. Authentication is required when trying to bridge JIRA resources into rooms.</p>
<ul>
<li>Say <code>jira login</code> to get the URL to authenticate via.</li>
<li>Click the URL sent by the bot.</li>
<li>Follow the steps, ensuring you authenticate with the right user.</li>
<li>If all goes well, you will now be connected. You can check the status and authorisatied instances by saying <code>jira whoami</code></li>
</ul>
<div style="break-before: page; page-break-before: always;"></div><h1 id="room-configuration"><a class="header" href="#room-configuration">Room Configuration</a></h1>
<p>Hookshot works off the principle of <strong>Connections</strong>.</p>
<p>A room can have many connections to different services. The connections are defined
in the room state of a room. A connection defines the service it connects to, the
type of integration (e.g. GitHub repo, Jira Project) and any additional configuration.</p>
<figure>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="128.84227mm"
height="60.402607mm"
viewBox="0 0 128.84227 60.402607"
version="1.1"
id="svg8"
style="background-color: white"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="connections1.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.256313"
inkscape:cx="244.71246"
inkscape:cy="81.676622"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1376"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:lockguides="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-10.574726,-45.0311)">
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.60000002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect10"
width="39.555889"
height="33.94323"
x="99.156998"
y="58.595577" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.60000002;stroke-miterlimit:4;stroke-dasharray:none"
x="103.42371"
y="77.304451"
id="text819"><tspan
sodipodi:role="line"
id="tspan817"
x="103.42371"
y="77.304451"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444447px;font-family:Arial;-inkscape-font-specification:Arial;text-align:start;text-anchor:start;stroke-width:0.60000002;stroke-miterlimit:4;stroke-dasharray:none">Matrix Room</tspan></text>
<g
style="stroke-width:0.60000002;stroke-miterlimit:4;stroke-dasharray:none"
transform="translate(21.130306,42.327584)"
id="g879">
<ellipse
style="fill:#ff9955;fill-opacity:1;stroke:#000000;stroke-width:0.57284814;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path874"
cx="46.504902"
cy="17.1688"
rx="14.847034"
ry="14.178861" />
<text
id="text819-3"
y="18.876226"
x="46.575386"
style="font-style:normal;font-weight:normal;font-size:7.71111298px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.4371655;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.11259365px;font-family:Arial;-inkscape-font-specification:Arial;text-align:center;text-anchor:middle;stroke-width:0.4371655;stroke-miterlimit:4;stroke-dasharray:none"
y="18.876226"
x="46.575386"
id="tspan817-1"
sodipodi:role="line">Connection</tspan></text>
</g>
<ellipse
ry="14.178861"
rx="14.847034"
cy="89.717857"
cx="67.657738"
id="path874-3"
style="fill:#ffe680;fill-opacity:1;stroke:#000000;stroke-width:0.57284814;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:7.71111298px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.4371655;stroke-miterlimit:4;stroke-dasharray:none"
x="67.539238"
y="91.425285"
id="text819-3-4"><tspan
sodipodi:role="line"
id="tspan817-1-0"
x="67.539238"
y="91.425285"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.11259365px;font-family:Arial;-inkscape-font-specification:Arial;text-align:center;text-anchor:middle;stroke-width:0.4371655;stroke-miterlimit:4;stroke-dasharray:none">Connection</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:0.65899998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 99.218749,89.528869 H 82.500017"
id="path984"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path1035"
style="fill:#1b1817;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.05966344"
d="m 25.950026,48.489111 c -5.366124,0 -9.71799,4.351256 -9.71799,9.719176 0,4.293381 2.784503,7.93643 6.646516,9.222177 0.486251,0.08889 0.66346,-0.211208 0.66346,-0.468954 0,-0.230897 -0.0085,-0.841852 -0.01353,-1.652678 -2.703357,0.587089 -3.27373,-1.303048 -3.27373,-1.303048 -0.442109,-1.122867 -1.07932,-1.421781 -1.07932,-1.421781 -0.882425,-0.6026 0.0668,-0.590668 0.0668,-0.590668 0.975494,0.06861 1.488602,1.001749 1.488602,1.001749 0.866916,1.485023 2.274964,1.056044 2.828644,0.807246 0.08828,-0.627659 0.339484,-1.056042 0.616916,-1.298873 -2.158014,-0.245812 -4.427025,-1.079311 -4.427025,-4.803503 0,-1.061413 0.378873,-1.928323 1.000559,-2.60789 -0.100291,-0.245812 -0.433754,-1.233839 0.09556,-2.572091 0,0 0.815587,-0.261324 2.672323,0.995783 0.775031,-0.215384 1.606735,-0.322778 2.433079,-0.326955 0.825734,0.0042 1.656847,0.111571 2.433062,0.326955 1.855534,-1.257107 2.669937,-0.995783 2.669937,-0.995783 0.530409,1.338252 0.196895,2.326279 0.09725,2.572091 0.622886,0.679567 0.998766,1.546477 0.998766,2.60789 0,3.733739 -2.272579,4.555304 -4.437173,4.795747 0.348431,0.300107 0.659282,0.893161 0.659282,1.800047 0,1.298873 -0.01184,2.34716 -0.01184,2.665762 0,0.260133 0.175416,0.562626 0.668228,0.467762 3.859037,-1.288135 6.641138,-4.928201 6.641138,-9.220985 0,-5.36792 -4.351849,-9.719176 -9.719766,-9.719176" />
<path
inkscape:connector-curvature="0"
id="path1125"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.03527778"
d="m 133.67005,94.224236 c -3.17288,0 -5.74605,2.572808 -5.74605,5.74675 0,2.538944 1.64642,4.692654 3.92995,5.452534 0.28751,0.0529 0.39229,-0.12453 0.39229,-0.27693 0,-0.13653 -0.005,-0.49777 -0.008,-0.9772 -1.59844,0.34714 -1.93569,-0.77046 -1.93569,-0.77046 -0.26141,-0.66393 -0.63818,-0.84067 -0.63818,-0.84067 -0.52176,-0.35631 0.0395,-0.34925 0.0395,-0.34925 0.57679,0.0406 0.88018,0.59231 0.88018,0.59231 0.51259,0.87807 1.34514,0.62442 1.67252,0.47731 0.0522,-0.37112 0.20073,-0.62442 0.36477,-0.768 -1.27599,-0.14499 -2.61761,-0.63817 -2.61761,-2.840211 0,-0.627239 0.22402,-1.14053 0.59161,-1.541991 -0.0593,-0.145345 -0.25647,-0.729898 0.0565,-1.520825 0,0 0.48224,-0.154517 1.58009,0.589138 0.45826,-0.127705 0.95003,-0.191205 1.43863,-0.193675 0.48824,0.0025 0.97966,0.06597 1.43862,0.193675 1.09714,-0.743655 1.57868,-0.589138 1.57868,-0.589138 0.31362,0.790927 0.11642,1.37548 0.0575,1.520825 0.3683,0.401461 0.59055,0.914752 0.59055,1.541991 0,2.207681 -1.34373,2.693461 -2.62361,2.835631 0.20602,0.17744 0.38982,0.52811 0.38982,1.06398 0,0.76835 -0.007,1.38818 -0.007,1.57656 0,0.15381 0.10372,0.33267 0.39511,0.27658 2.28177,-0.76165 3.92677,-2.91395 3.92677,-5.452184 0,-3.173942 -2.57316,-5.74675 -5.7471,-5.74675" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000080;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="99.974701"
y="85.711311"
id="text1495"><tspan
sodipodi:role="line"
id="tspan1493"
x="99.974701"
y="85.711311"
style="font-size:4.23333311px;fill:#000080;stroke-width:0.26458332">!foo:example.com</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:0.65899998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 99.073652,61.369644 H 82.35492"
id="path984-6"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.65899998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 52.393597,58.308035 H 35.67486"
id="path984-6-4"
inkscape:connector-curvature="0" />
<path
style="fill:#000000;stroke-width:0.00630857"
d="m 20.801015,96.539047 c -0.0641,-0.0202 -0.11794,-0.0634 -0.13856,-0.11136 -0.0107,-0.0249 -0.34026,-1.09412 -0.34837,-1.13028 -0.005,-0.0215 -0.005,-0.0412 -4.2e-4,-0.0658 0.0185,-0.0999 0.0965,-0.17205 0.19575,-0.18107 0.13953,-0.0127 0.25122,-0.0365 0.35796,-0.0764 0.33057,-0.12348 0.55312,-0.36647 0.63794,-0.69654 0.0417,-0.1623 0.0387,0.11098 0.0387,-3.51276 0,-2.04527 0.002,-3.29842 0.006,-3.32121 0.012,-0.073 0.0547,-0.12801 0.1253,-0.16111 l 0.0358,-0.0168 0.70656,-0.002 c 0.51217,-0.001 0.71817,-2e-5 0.74878,0.005 0.0423,0.007 0.1045,0.0384 0.12301,0.0616 0.0207,0.0259 0.0379,0.0569 0.0449,0.081 0.01,0.0341 0.0109,6.80258 0.001,6.91977 -0.0389,0.46192 -0.18919,0.87846 -0.44419,1.2312 -0.35938,0.49711 -0.90361,0.84076 -1.50647,0.95127 -0.15638,0.0287 -0.23031,0.035 -0.39889,0.0344 -0.11333,-4.5e-4 -0.16554,-0.003 -0.18494,-0.009 z m 4.09921,-0.57229 c -0.0628,-0.019 -0.12974,-0.0889 -0.14636,-0.15291 -0.007,-0.0257 -0.008,-0.80152 -0.008,-4.20151 v -4.16996 l 0.0152,-0.0377 c 0.0203,-0.0505 0.0655,-0.0975 0.11589,-0.12082 l 0.0393,-0.0181 h 0.72548 0.72549 l 0.0378,0.0177 c 0.0493,0.023 0.0924,0.0659 0.11466,0.11413 l 0.0178,0.0385 v 4.18258 4.18258 l -0.0148,0.0368 c -0.008,0.0202 -0.0238,0.047 -0.0347,0.0594 -0.0244,0.0279 -0.0742,0.0598 -0.10891,0.0698 -0.0347,0.01 -1.44537,0.01 -1.47862,-4.6e-4 z m 3.24891,-7e-4 c -0.0191,-0.004 -0.0446,-0.0129 -0.0568,-0.0192 -0.0346,-0.0178 -0.075,-0.0604 -0.0935,-0.0983 l -0.0169,-0.0347 -0.002,-4.17943 c -0.001,-3.17286 -1.4e-4,-4.18714 0.005,-4.21148 0.0151,-0.0655 0.0829,-0.13534 0.14831,-0.15284 0.0362,-0.01 3.56726,-0.0108 3.75625,-10e-4 0.95427,0.0486 1.59816,0.2968 1.99612,0.76957 0.25732,0.30569 0.40804,0.70209 0.46084,1.21195 0.019,0.18345 0.0234,0.41756 0.0205,1.08437 -0.003,0.68067 -0.005,0.73295 -0.0332,0.92567 -0.0537,0.36502 -0.15981,0.65827 -0.3355,0.9274 -0.17444,0.26722 -0.45721,0.50435 -0.77768,0.65216 -0.0447,0.0206 -0.0786,0.0399 -0.0782,0.0446 10e-4,0.0168 1.46822,2.12576 1.47277,2.11734 0.005,-0.008 0.0167,-0.0468 0.21639,-0.68019 0.0607,-0.19257 0.31376,-0.99454 0.56236,-1.78217 0.24861,-0.78762 0.54419,-1.72445 0.65686,-2.08183 0.11267,-0.35738 0.21303,-0.67533 0.22303,-0.70656 0.01,-0.0312 0.17886,-0.56635 0.37527,-1.18916 0.19641,-0.62281 0.36328,-1.148 0.37083,-1.16708 0.0186,-0.047 0.059,-0.0888 0.1074,-0.11117 l 0.0393,-0.0182 h 1.08191 c 1.0268,0 1.08333,5.7e-4 1.10961,0.0113 0.0449,0.0184 0.0818,0.0473 0.10468,0.0822 0.0176,0.0267 0.0832,0.22847 0.36271,1.11456 0.18768,0.59506 0.34382,1.08902 0.34696,1.09769 0.003,0.009 0.442,1.398 0.97524,3.08738 0.96731,3.06462 0.96951,3.07171 0.96644,3.11462 -0.006,0.0813 -0.0582,0.1521 -0.136,0.18351 l -0.036,0.0145 h -0.76018 -0.76019 l -0.0352,-0.0143 c -0.0408,-0.0165 -0.0825,-0.0501 -0.10357,-0.0835 -0.008,-0.0134 -0.1214,-0.36772 -0.26465,-0.83023 -0.13745,-0.44378 -0.25258,-0.81322 -0.25584,-0.82098 l -0.006,-0.0141 -0.98918,-0.002 -0.98918,-0.002 -0.042,-0.0207 c -0.0453,-0.0223 -0.0897,-0.0656 -0.10944,-0.10681 -0.007,-0.0154 -0.0123,-0.043 -0.0139,-0.0775 l -0.002,-0.0536 0.16167,-0.58039 c 0.0889,-0.31921 0.16813,-0.59458 0.17603,-0.61193 0.0176,-0.0386 0.0646,-0.086 0.1032,-0.10418 0.0158,-0.007 0.0446,-0.0161 0.064,-0.0193 0.0195,-0.003 0.28981,-0.006 0.60508,-0.006 0.5397,-7e-5 0.56959,-5.7e-4 0.56641,-0.0111 -0.002,-0.006 -0.18947,-0.65404 -0.41695,-1.43993 -0.22747,-0.78589 -0.41962,-1.44403 -0.42699,-1.46254 -0.0181,-0.0455 -0.0659,-0.0966 -0.10759,-0.11505 -0.051,-0.0226 -0.12786,-0.0215 -0.1767,0.002 -0.0457,0.0224 -0.0878,0.0643 -0.10767,0.10689 -0.0114,0.0244 -0.9754,3.28073 -1.29472,4.37333 -0.28373,0.97086 -0.52273,1.76749 -0.53709,1.79023 -0.0233,0.0369 -0.0531,0.0644 -0.092,0.0849 l -0.0331,0.0174 -1.42574,0.002 c -1.05248,0.001 -1.43685,7e-5 -1.46819,-0.005 -0.03,-0.005 -0.0531,-0.0142 -0.0788,-0.0308 -0.0434,-0.0281 -0.0551,-0.0416 -0.13015,-0.15038 -0.0317,-0.046 -0.4551,-0.65552 -0.94086,-1.3546 l -0.8832,-1.27105 -0.69867,-1.4e-4 -0.69868,-1.4e-4 v 1.30454 c 0,1.42237 0.002,1.34374 -0.0352,1.40259 -0.0248,0.0393 -0.051,0.062 -0.0968,0.0837 l -0.0415,0.0197 -0.70656,0.001 c -0.54098,8.8e-4 -0.71469,-6.8e-4 -0.74126,-0.007 z m 3.64005,-4.40322 c 0.29639,-0.034 0.47138,-0.10557 0.59545,-0.24354 0.0903,-0.10038 0.14295,-0.2262 0.17235,-0.4116 0.0103,-0.065 0.0113,-0.12615 0.0113,-0.69586 0,-0.61504 -2.8e-4,-0.6257 -0.0138,-0.70025 -0.0481,-0.26387 -0.15549,-0.41923 -0.35942,-0.51991 -0.0997,-0.0492 -0.21251,-0.081 -0.37464,-0.10563 -0.0658,-0.01 -0.16026,-0.0112 -1.05797,-0.0131 l -0.98572,-0.002 v 1.34919 c 0,0.74205 0.002,1.35129 0.005,1.35387 0.003,0.003 0.43479,0.004 0.96048,0.002 0.83894,-0.002 0.96698,-0.004 1.04727,-0.0131 z m -19.51127,4.39882 c -0.0867,-0.0171 -0.17269,-0.0978 -0.19095,-0.17941 -0.008,-0.0354 -0.002,-0.15302 0.0168,-0.32313 0.0808,-0.73948 0.35942,-1.49087 0.83673,-2.25636 0.101,-0.16197 0.13049,-0.20407 0.16178,-0.23091 0.0769,-0.0659 0.1768,-0.0785 0.26144,-0.0329 0.0208,0.0112 0.0718,0.0603 0.16455,0.15865 0.33774,0.35793 0.50811,0.54836 0.80469,0.89942 0.0947,0.11209 0.12674,0.18526 0.12657,0.28893 -1.4e-4,0.066 -0.0118,0.10105 -0.0747,0.22477 -0.1343,0.26397 -0.22518,0.50102 -0.28761,0.75018 -0.0376,0.15003 -0.0528,0.23972 -0.0792,0.46759 -0.0152,0.13065 -0.0893,0.21473 -0.20614,0.23387 -0.0459,0.008 -1.49552,0.007 -1.53388,-6.5e-4 z m 3.85656,-0.0103 c -0.0306,-0.007 -0.0808,-0.037 -0.1071,-0.0634 -0.0504,-0.0504 -0.064,-0.0885 -0.0792,-0.22244 -0.0332,-0.29228 -0.0896,-0.51785 -0.19876,-0.79488 -0.1922,-0.48791 -0.50097,-0.97607 -0.9833,-1.55455 -0.0552,-0.0662 -0.12046,-0.14308 -0.14503,-0.17084 -0.36501,-0.41235 -0.56087,-0.61915 -1.2815,-1.35308 -0.12458,-0.12689 -0.32983,-0.33713 -0.40668,-0.41658 -0.002,-0.002 -0.03,-0.0316 -0.0629,-0.0662 -0.0328,-0.0346 -0.0884,-0.0928 -0.12349,-0.12922 -0.0794,-0.0825 -0.30839,-0.33286 -0.43846,-0.47945 -1.06844,-1.2042 -1.60056,-2.21841 -1.72891,-3.29531 -0.0184,-0.15454 0.0202,-0.24809 0.12435,-0.30094 0.0405,-0.0206 0.0462,-0.0217 0.1062,-0.0214 l 0.0634,2.8e-4 0.14825,0.0554 c 0.39762,0.14872 0.89261,0.30099 1.27433,0.39203 0.19161,0.0457 0.20359,0.0505 0.26108,0.1038 0.0411,0.0382 0.0564,0.0637 0.0898,0.15004 0.21047,0.54456 0.58386,1.09308 1.22923,1.80578 0.33067,0.36516 0.951,1.00076 1.00564,1.0304 0.0614,0.0333 0.1489,0.0346 0.21176,0.003 0.0452,-0.0227 0.53289,-0.51814 0.8839,-0.89797 0.54034,-0.58471 0.89637,-1.05024 1.14328,-1.4949 0.0593,-0.10686 0.16001,-0.31799 0.20005,-0.41952 0.0198,-0.0503 0.0431,-0.10355 0.0518,-0.11832 0.0196,-0.0334 0.0803,-0.089 0.11747,-0.10756 0.0154,-0.008 0.12272,-0.0379 0.2385,-0.067 0.48396,-0.12197 0.8502,-0.23316 1.22304,-0.37131 0.15353,-0.0569 0.15497,-0.0573 0.2145,-0.0577 0.0532,-4.3e-4 0.0643,0.002 0.0993,0.0177 0.0465,0.0215 0.0867,0.0618 0.11075,0.11116 0.0286,0.0586 0.031,0.088 0.0168,0.20349 -0.0431,0.35026 -0.12839,0.69146 -0.25352,1.01406 -0.0763,0.19675 -0.11313,0.27854 -0.22575,0.50154 -0.16299,0.32274 -0.34401,0.61501 -0.58459,0.94387 -0.0884,0.12089 -0.24399,0.3251 -0.25412,0.33361 -0.002,0.002 -0.0348,0.0415 -0.0727,0.0883 -0.30418,0.37571 -0.78045,0.89072 -1.46436,1.58345 -0.10522,0.10659 -0.17029,0.17747 -0.17951,0.19557 -0.0111,0.0217 -0.0146,0.0394 -0.0149,0.0757 -5.7e-4,0.0602 0.009,0.0805 0.0854,0.17664 0.17737,0.2239 0.36813,0.48757 0.4975,0.68763 0.046,0.0711 0.0901,0.13927 0.0981,0.15141 0.008,0.0121 0.0456,0.0746 0.0836,0.13879 0.44031,0.74377 0.68616,1.43575 0.76447,2.15173 0.019,0.1741 0.0229,0.2925 0.0107,0.32603 -0.0215,0.0589 -0.0711,0.11409 -0.12936,0.14409 l -0.0355,0.0183 -0.78541,9e-4 c -0.43198,5e-4 -0.7911,-4.7e-4 -0.79804,-0.002 z m -1.20494,-6.51646 c -0.0487,-0.0128 -0.0822,-0.0386 -0.17703,-0.1363 -0.25804,-0.26576 -0.49385,-0.59581 -0.6682,-0.93521 -0.0705,-0.13725 -0.11419,-0.24349 -0.11973,-0.29119 -0.0122,-0.10551 0.0548,-0.20718 0.15797,-0.23972 0.0327,-0.0103 0.0454,-0.0102 0.25351,0.001 0.28281,0.0158 0.90617,0.0173 1.16226,0.003 0.0919,-0.005 0.20124,-0.009 0.24288,-0.009 0.0683,0 0.0791,0.002 0.1104,0.0163 0.064,0.0301 0.11289,0.0934 0.12618,0.16353 0.013,0.0687 -0.0162,0.15849 -0.11378,0.34969 -0.1777,0.34813 -0.41209,0.67545 -0.68342,0.95433 -0.10891,0.11195 -0.12954,0.12384 -0.21828,0.12583 -0.0331,7.2e-4 -0.0658,-1.4e-4 -0.0728,-0.002 z m -2.56127,-2.91753 c -0.17728,-0.0318 -0.30961,-0.0986 -0.42638,-0.21522 -0.14395,-0.14369 -0.22025,-0.33003 -0.22025,-0.53789 0,-0.16406 0.0457,-0.30924 0.13793,-0.43829 0.15856,-0.22181 0.42149,-0.34255 0.68796,-0.31591 0.18189,0.0182 0.33263,0.0884 0.46119,0.21478 0.0935,0.0919 0.15019,0.18251 0.19184,0.3065 0.0353,0.10502 0.0454,0.25123 0.0254,0.36613 -0.0637,0.36507 -0.3821,0.62986 -0.75315,0.62627 -0.0401,-4.3e-4 -0.0872,-0.003 -0.10451,-0.006 z m 5.02792,4.2e-4 c -0.22169,-0.0424 -0.37834,-0.13677 -0.50046,-0.30147 -0.12153,-0.16391 -0.17235,-0.38128 -0.13665,-0.58448 0.0678,-0.38605 0.43023,-0.66218 0.81583,-0.62162 0.29999,0.0315 0.54617,0.22316 0.64682,0.50344 0.0552,0.15369 0.0563,0.34072 0.003,0.4967 -0.087,0.25462 -0.29411,0.43875 -0.56041,0.49836 -0.0556,0.0124 -0.22117,0.018 -0.26811,0.009 z m -2.53969,-0.70332 c -0.23922,-0.0433 -0.44148,-0.19518 -0.54789,-0.41136 -0.12084,-0.24548 -0.101,-0.53588 0.0522,-0.76323 0.15359,-0.228 0.42264,-0.35518 0.69652,-0.32925 0.32448,0.0307 0.58542,0.2545 0.66837,0.57318 0.0195,0.0749 0.0265,0.2115 0.0149,0.29084 -0.0476,0.32545 -0.2989,0.58366 -0.62307,0.6402 -0.0662,0.0115 -0.19614,0.0114 -0.26098,-4.3e-4 z"
id="path1560"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.53958774;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 52.393597,91.116389 H 41.184857"
id="path984-6-4-0"
inkscape:connector-curvature="0" />
</g>
</svg>
<figcaption>Figure 1. An example of a room connected to GitHub and JIRA</figcaption>
</figure>
<p>Hookshot supports several connection types, which are defined under the Room Configuration
heading.</p>
<p>The availablilty of connection types depends on the configuration provided to hookshot.</p>
<h3 id="the-hookshot-command"><a class="header" href="#the-hookshot-command">The <code>!hookshot</code> command</a></h3>
<p>Rooms can be bridged by inviting the hookshot bot into a room, and then running the
<code>!hookshot</code> command. Running <code>!hookshot help</code> will give you some details, but you should
see the documentation provided for information on each connection type.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="github-repository"><a class="header" href="#github-repository">GitHub Repository</a></h1>
<p>This connection type connects a GitHub repository (e.g. https://github.com/Half-Shot/matrix-hookshot) to a room.</p>
<p>You can run commands to create and manipulate issues, and recieve notifications when something changes such as
a new release.</p>
<h2 id="setting-up"><a class="header" href="#setting-up">Setting up</a></h2>
<p>To set up a connection to a GitHub Repository in a new room:</p>
<p>(N.B you must have permission to bridge GitHub repositories before you can use this command, see <a href="usage/room_configuration/../auth.html#github">auth</a>)</p>
<ol>
<li>Invite the bridge bot (e..g <code>@hookshot:example.com</code>)</li>
<li>Give the bridge bot moderator permissions or higher (power level 50).</li>
<li>Send the command <code>!hookshot github repo https://github.com/my/project</code></li>
<li>If you have permission to bridge this repo, the bridge will respond with a confirmation message.</li>
<li>Note: The bridge will need to either:
<ul>
<li>Have a GitHub installation registered with the organisation</li>
<li>The requesting user must be authenticated with the bridge via OAuth and the repository must be part of their GitHub account.</li>
</ul>
</li>
</ol>
<h2 id="configuration-5"><a class="header" href="#configuration-5">Configuration</a></h2>
<p>This connection supports a few options which can be defined in the room state:</p>
<table><thead><tr><th>Option</th><th>Description</th><th>Allowed values</th><th>Default</th></tr></thead><tbody>
<tr><td>ignoreHooks</td><td>Choose to exclude notifications for some event types</td><td>Array of: <a href="usage/room_configuration/github_repo.html#supported-event-types">Supported event types</a></td><td><em>empty</em></td></tr>
<tr><td>commandPrefix</td><td>Choose the prefix to use when sending commands to the bot</td><td>A string, ideally starts with &quot;!&quot;</td><td><code>!gh</code></td></tr>
<tr><td>showIssueRoomLink</td><td>When new issues are created, provide a Matrix alias link to the issue room</td><td><code>true/false</code></td><td><code>false</code></td></tr>
<tr><td>prDiff</td><td>Show a diff in the room when a PR is created, subject to limits</td><td><code>{enabled: boolean, maxLines: number}</code></td><td><code>{enabled: false}</code></td></tr>
<tr><td>includingLabels</td><td>Only notify on issues matching these label names</td><td>Any string matching a label name</td><td><em>empty</em></td></tr>
<tr><td>excludingLabels</td><td>Never notify on issues matching these label names</td><td>Any string matching a label name</td><td><em>empty</em></td></tr>
</tbody></table>
<h3 id="supported-event-types"><a class="header" href="#supported-event-types">Supported event types</a></h3>
<p>This connection supports sending messages when the following actions happen on the repository.</p>
<ul>
<li>issue
<ul>
<li>issue.created</li>
<li>issue.changed</li>
<li>issue.edited</li>
</ul>
</li>
<li>pull_request
<ul>
<li>pull_request.closed</li>
<li>pull_request.merged</li>
<li>pull_request.opened</li>
<li>pull_request.ready_for_review</li>
<li>pull_request.reviewed</li>
</ul>
</li>
<li>release
<ul>
<li>release.created</li>
</ul>
</li>
</ul>
<div style="break-before: page; page-break-before: always;"></div><h1 id="prometheus-metrics"><a class="header" href="#prometheus-metrics">Prometheus Metrics</a></h1>
<p>You can configure metrics support by adding the following to your config:</p>
<pre><code class="language-yaml"> enabled: true
bindAddress: 127.0.0.1
port: 9002
</code></pre>
<p>Below is the generated list of Prometheus metrics for Hookshot.</p>
<h2 id="hookshot"><a class="header" href="#hookshot">hookshot</a></h2>
<table><thead><tr><th>Metric</th><th>Help</th><th>Labels</th></tr></thead><tbody>
<tr><td>hookshot_webhooks_http_request</td><td>Number of requests made to the hookshot webhooks handler</td><td>path, method</td></tr>
<tr><td>hookshot_provisioning_http_request</td><td>Number of requests made to the hookshot webhooks handler</td><td>path, method</td></tr>
<tr><td>hookshot_queue_event_pushes</td><td>Number of events pushed through the queue</td><td>event</td></tr>
<tr><td>hookshot_notifications_push</td><td>Number of notifications pushed</td><td>service</td></tr>
<tr><td>hookshot_notifications_service_up</td><td>Is the notification service up or down</td><td>service</td></tr>
<tr><td>hookshot_notifications_watchers</td><td>Number of notifications watchers running</td><td>service</td></tr>
</tbody></table>
<h2 id="matrix"><a class="header" href="#matrix">matrix</a></h2>
<table><thead><tr><th>Metric</th><th>Help</th><th>Labels</th></tr></thead><tbody>
<tr><td>matrix_api_calls</td><td>The number of Matrix client API calls made</td><td>method</td></tr>
<tr><td>matrix_api_calls_failed</td><td>The number of Matrix client API calls which failed</td><td>method</td></tr>
<tr><td>matrix_appservice_events</td><td>The number of events sent over the AS API</td><td></td></tr>
</tbody></table>
<h2 id="process"><a class="header" href="#process">process</a></h2>
<table><thead><tr><th>Metric</th><th>Help</th><th>Labels</th></tr></thead><tbody>
<tr><td>process_cpu_user_seconds_total</td><td>Total user CPU time spent in seconds.</td><td></td></tr>
<tr><td>process_cpu_system_seconds_total</td><td>Total system CPU time spent in seconds.</td><td></td></tr>
<tr><td>process_cpu_seconds_total</td><td>Total user and system CPU time spent in seconds.</td><td></td></tr>
<tr><td>process_start_time_seconds</td><td>Start time of the process since unix epoch in seconds.</td><td></td></tr>
<tr><td>process_resident_memory_bytes</td><td>Resident memory size in bytes.</td><td></td></tr>
<tr><td>process_virtual_memory_bytes</td><td>Virtual memory size in bytes.</td><td></td></tr>
<tr><td>process_heap_bytes</td><td>Process heap size in bytes.</td><td></td></tr>
<tr><td>process_open_fds</td><td>Number of open file descriptors.</td><td></td></tr>
<tr><td>process_max_fds</td><td>Maximum number of open file descriptors.</td><td></td></tr>
</tbody></table>
<h2 id="nodejs"><a class="header" href="#nodejs">nodejs</a></h2>
<table><thead><tr><th>Metric</th><th>Help</th><th>Labels</th></tr></thead><tbody>
<tr><td>nodejs_eventloop_lag_seconds</td><td>Lag of event loop in seconds.</td><td></td></tr>
<tr><td>nodejs_eventloop_lag_min_seconds</td><td>The minimum recorded event loop delay.</td><td></td></tr>
<tr><td>nodejs_eventloop_lag_max_seconds</td><td>The maximum recorded event loop delay.</td><td></td></tr>
<tr><td>nodejs_eventloop_lag_mean_seconds</td><td>The mean of the recorded event loop delays.</td><td></td></tr>
<tr><td>nodejs_eventloop_lag_stddev_seconds</td><td>The standard deviation of the recorded event loop delays.</td><td></td></tr>
<tr><td>nodejs_eventloop_lag_p50_seconds</td><td>The 50th percentile of the recorded event loop delays.</td><td></td></tr>
<tr><td>nodejs_eventloop_lag_p90_seconds</td><td>The 90th percentile of the recorded event loop delays.</td><td></td></tr>
<tr><td>nodejs_eventloop_lag_p99_seconds</td><td>The 99th percentile of the recorded event loop delays.</td><td></td></tr>
<tr><td>nodejs_active_handles</td><td>Number of active libuv handles grouped by handle type. Every handle type is C++ class name.</td><td>type</td></tr>
<tr><td>nodejs_active_handles_total</td><td>Total number of active handles.</td><td></td></tr>
<tr><td>nodejs_active_requests</td><td>Number of active libuv requests grouped by request type. Every request type is C++ class name.</td><td>type</td></tr>
<tr><td>nodejs_active_requests_total</td><td>Total number of active requests.</td><td></td></tr>
<tr><td>nodejs_heap_size_total_bytes</td><td>Process heap size from Node.js in bytes.</td><td></td></tr>
<tr><td>nodejs_heap_size_used_bytes</td><td>Process heap size used from Node.js in bytes.</td><td></td></tr>
<tr><td>nodejs_external_memory_bytes</td><td>Node.js external memory size in bytes.</td><td></td></tr>
<tr><td>nodejs_heap_space_size_total_bytes</td><td>Process heap space size total from Node.js in bytes.</td><td>space</td></tr>
<tr><td>nodejs_heap_space_size_used_bytes</td><td>Process heap space size used from Node.js in bytes.</td><td>space</td></tr>
<tr><td>nodejs_heap_space_size_available_bytes</td><td>Process heap space size available from Node.js in bytes.</td><td>space</td></tr>
<tr><td>nodejs_version_info</td><td>Node.js version info.</td><td>version, major, minor, patch</td></tr>
<tr><td>nodejs_gc_duration_seconds</td><td>Garbage collection duration by kind, one of major, minor, incremental or weakcb.</td><td>kind</td></tr>
</tbody></table>
<div style="break-before: page; page-break-before: always;"></div><h1 id="provisioning"><a class="header" href="#provisioning">Provisioning</a></h1>
<p>This section is not complete yet for end users. For developers, you can read the documentation for the API below:</p>
<h2 id="provisioning-api-for-matrix-hookshot"><a class="header" href="#provisioning-api-for-matrix-hookshot">Provisioning API for matrix-hookshot</a></h2>
<h1 id="overview"><a class="header" href="#overview">Overview</a></h1>
<p>This document describes how to integrate with <code>matrix-hookshot</code>'s provisoning API.</p>
<p>Requests made to the bridge must be against the API listener defined in the config under <code>provisioning</code>, not
the appservice or webhook listeners.</p>
<p>Requests should always be authenticated with the secret given in the config, inside the <code>Authorization</code> header.
Requests being made on behalf of users (most provisioning APIs) should include the userId as a query parameter.</p>
<pre><code>GET /v1/health?userId=%40Half-Shot%3Ahalf-shot.uk
Authorization: Bearer secret
</code></pre>
<p>APIs are versioned independently so two endpoints on the latest version may not always have the same version.</p>
<h1 id="apis"><a class="header" href="#apis">APIs</a></h1>
<h2 id="get-v1health"><a class="header" href="#get-v1health">GET /v1/health</a></h2>
<p>Request the status of the provisoning API.</p>
<h3 id="response"><a class="header" href="#response">Response</a></h3>
<pre><code>HTTP 200
{}
</code></pre>
<p>Any other response should be considered a failed request (e.g. 404, 502 etc).</p>
<h2 id="get-v1connectiontypes"><a class="header" href="#get-v1connectiontypes">GET /v1/connectiontypes</a></h2>
<p>Request the connection types enabled for this bridge.</p>
<h3 id="response-1"><a class="header" href="#response-1">Response</a></h3>
<pre><code class="language-json5">{
&quot;JiraProject&quot;: {
&quot;type&quot;: &quot;JiraProject&quot;, // The name of the connection
&quot;eventType&quot;: &quot;uk.half-shot.matrix-hookshot.jira.project&quot;, // Corresponds to the state type for the connection
&quot;service&quot;: &quot;jira&quot;, // or github, webhook. A human-readable service name to make things look pretty
&quot;botUserId&quot;: &quot;@hookshot:yourdomain.com&quot;, // The bot mxid for the service. Currently this is the sender_localpart, but may change in the future.
}
}
</code></pre>
<h2 id="get-v1roomidconnections"><a class="header" href="#get-v1roomidconnections">GET /v1/{roomId}/connections</a></h2>
<p>Request the connections for a given room. The <code>{roomId}</code> parameter is the target Matrix room.</p>
<h3 id="response-2"><a class="header" href="#response-2">Response</a></h3>
<pre><code class="language-json5">[{
&quot;type&quot;: &quot;JiraProject&quot;, // The name of the connection
&quot;eventType&quot;: &quot;uk.half-shot.matrix-hookshot.jira.project&quot;, // Corresponds to the state type in the connection
&quot;id&quot;: &quot;opaque-unique-id&quot;, // An opaque ID used to refer to this connection. Should **NOT** be assumed to be stable.
&quot;service&quot;: &quot;jira&quot;, // or github, webhook. A human-readable service name to make things look pretty
&quot;botUserId&quot;: &quot;@hookshot:yourdomain.com&quot;, // The bot mxid for the service. Currently this is the sender_localpart, but may change in the future.
&quot;config&quot;: {
// ... connection specific details, can be configured.
}
}]
</code></pre>
<h2 id="get-v1roomidconnectionsid"><a class="header" href="#get-v1roomidconnectionsid">GET /v1/{roomId}/connections/{id}</a></h2>
<p>Request details of a single connection. The <code>{roomId}</code> parameter is the target Matrix room.</p>
<h3 id="response-3"><a class="header" href="#response-3">Response</a></h3>
<pre><code class="language-json5">{
&quot;type&quot;: &quot;JiraProject&quot;, // The name of the connection
&quot;eventType&quot;: &quot;uk.half-shot.matrix-hookshot.jira.project&quot;, // Corresponds to the state type in the connection
&quot;id&quot;: &quot;opaque-unique-id&quot;, // An opaque ID used to refer to this connection. Should **NOT** be assumed to be stable.
&quot;service&quot;: &quot;jira&quot;, // or github, webhook. A human-readable service name to make things look pretty
&quot;botUserId&quot;: &quot;@hookshot:yourdomain.com&quot;, // The bot mxid for the service. Currently this is the sender_localpart, but may change in the future.
&quot;config&quot;: {
// ... connection specific details, can be configured.
}
}
</code></pre>
<h2 id="put-v1roomidconnectionstype"><a class="header" href="#put-v1roomidconnectionstype">PUT /v1/{roomId}/connections/{type}</a></h2>
<p>Create a new connection of a given type. The type refers to the <code>eventType</code> (<code>IConnection.CanonicalEventType</code>). The <code>{roomId}</code> parameter is the target Matrix room.</p>
<p>The body of the request is the configuration for the connection, which will be the &quot;ConnectionState&quot; interface for each connection.</p>
<h3 id="request-body"><a class="header" href="#request-body">Request body</a></h3>
<pre><code class="language-json5">{
// ... connection specific details, can be configured.
}
</code></pre>
<h3 id="response-4"><a class="header" href="#response-4">Response</a></h3>
<pre><code class="language-json5">{
&quot;type&quot;: &quot;JiraProject&quot;, // The name of the connection
&quot;eventType&quot;: &quot;uk.half-shot.matrix-hookshot.jira.project&quot;, // Corresponds to the state type in the connection
&quot;id&quot;: &quot;opaque-unique-id&quot;, // An opaque ID used to refer to this connection. Should **NOT** be assumed to be stable.
&quot;service&quot;: &quot;jira&quot;, // or github, webhook. A human-readable service name to make things look pretty
&quot;botUserId&quot;: &quot;@hookshot:yourdomain.com&quot;, // The bot mxid for the service. Currently this is the sender_localpart, but may change in the future.
&quot;config&quot;: {
// ... connection specific details, can be configured.
}
}
</code></pre>
<h2 id="patch-v1roomidconnectionsid"><a class="header" href="#patch-v1roomidconnectionsid">PATCH /v1/{roomId}/connections/{id}</a></h2>
<p>Update a connection's configuration. The <code>id</code> refers to the <code>id</code> returned in the GET response.</p>
<p>The body of the request is the configuration for the connection, which will be the &quot;ConnectionState&quot; interface for each connection.</p>
<h3 id="request-body-1"><a class="header" href="#request-body-1">Request body</a></h3>
<pre><code class="language-json5">{
// ... connection specific details, can be configured.
}
</code></pre>
<h3 id="response-5"><a class="header" href="#response-5">Response</a></h3>
<pre><code class="language-json5">{
&quot;type&quot;: &quot;JiraProject&quot;, // The name of the connection
&quot;eventType&quot;: &quot;uk.half-shot.matrix-hookshot.jira.project&quot;, // Corresponds to the state type in the connection
&quot;id&quot;: &quot;opaque-unique-id&quot;, // An opaque ID used to refer to this connection. Should **NOT** be assumed to be stable.
&quot;service&quot;: &quot;jira&quot;, // or github, webhook. A human-readable service name to make things look pretty
&quot;botUserId&quot;: &quot;@hookshot:yourdomain.com&quot;, // The bot mxid for the service. Currently this is the sender_localpart, but may change in the future.
&quot;config&quot;: {
// ... connection specific details, can be configured.
}
}
</code></pre>
<h2 id="delete-v1roomidconnectionsid"><a class="header" href="#delete-v1roomidconnectionsid">DELETE /v1/{roomId}/connections/{id}</a></h2>
<p>Delete a connection. The <code>id</code> refers to the <code>id</code> returned in the GET response.</p>
<h3 id="response-6"><a class="header" href="#response-6">Response</a></h3>
<pre><code class="language-json5">{
&quot;ok&quot;: true
}
</code></pre>
<h1 id="service-specific-apis"><a class="header" href="#service-specific-apis">Service specific APIs</a></h1>
<p>Some services have specific APIs for additional functionality, like OAuth.</p>
<h2 id="github-1"><a class="header" href="#github-1">GitHub</a></h2>
<h3 id="get-v1githuboauthuseriduserid"><a class="header" href="#get-v1githuboauthuseriduserid">GET /v1/github/oauth?userId={userId}</a></h3>
<p>Request an OAuth url for the given user. Once the user has completed the steps in the OAuth process,
the bridge will be granted access.</p>
<h3 id="response-7"><a class="header" href="#response-7">Response</a></h3>
<pre><code class="language-json5">[{
&quot;user_url&quot;: &quot;https://github.com/login/oauth/authorize?...&quot;,
&quot;org_url&quot;: &quot;https://github.com/apps/matrix-bridge/installations/new&quot;,
}]
</code></pre>
<h3 id="get-v1githubaccountuseriduserid"><a class="header" href="#get-v1githubaccountuseriduserid">GET /v1/github/account?userId={userId}</a></h3>
<p>Request the status of the users account. This will return a <code>loggedIn</code> value to determine if the
bridge has a GitHub identity stored for the user, and any organisations they have access to.</p>
<h3 id="response-8"><a class="header" href="#response-8">Response</a></h3>
<pre><code class="language-json5">{
&quot;loggedIn&quot;: true,
&quot;organisations&quot;:[{
&quot;name&quot;: &quot;half-shot&quot;,
&quot;avatarUrl&quot;: &quot;https://avatars.githubusercontent.com/u/8418310?v=4&quot;
}]
}
</code></pre>
<h3 id="get-v1githuborgsorgnamerepositoriesuseriduseridpagepageperpageperpage"><a class="header" href="#get-v1githuborgsorgnamerepositoriesuseriduseridpagepageperpageperpage">GET /v1/github/orgs/{orgName}/repositories?userId={userId}&amp;page={page}&amp;perPage={perPage}</a></h3>
<p>Request a list of all repositories a user is a member of in the given org. The <code>owner</code> and <code>name</code> value of a repository can be given to create a new GitHub connection.</p>
<p>This request is paginated, and <code>page</code> sets the page (defaults to <code>1</code>) while <code>perPage</code> (defaults to <code>10</code>) sets the number of entries per page.</p>
<p>This request can be retried until the number of entries is less than the value of <code>perPage</code>.</p>
<h3 id="response-9"><a class="header" href="#response-9">Response</a></h3>
<pre><code class="language-json5">{
&quot;loggedIn&quot;: true,
&quot;repositories&quot;:[{
&quot;name&quot;: &quot;matrix-hookshot&quot;,
&quot;owner&quot;: &quot;half-shot&quot;,
&quot;fullName&quot;: &quot;half-shot/matrix-hookshot&quot;,
&quot;avatarUrl&quot;: &quot;https://avatars.githubusercontent.com/u/8418310?v=4&quot;,
&quot;description&quot;: &quot;A bridge between Matrix and multiple project management services, such as GitHub, GitLab and JIRA. &quot;
}]
}
</code></pre>
<h3 id="get-v1githubrepositoriesuseriduseridpagepageperpageperpage"><a class="header" href="#get-v1githubrepositoriesuseriduseridpagepageperpageperpage">GET /v1/github/repositories?userId={userId}&amp;page={page}&amp;perPage={perPage}</a></h3>
<p>Request a list of all repositories a user is a member of (including those not belonging to an org). The <code>owner</code> and <code>name</code> value of a repository can be given to create a new GitHub connection.</p>
<p>If the user has only allowed a subset of repositories to be bridged, <code>changeSelectionUrl</code> will be defined and can be used to expand the search query.</p>
<p>This request is paginated, and <code>page</code> sets the page (defaults to <code>1</code>) while <code>perPage</code> (defaults to <code>10</code>) sets the number of entries per page.</p>
<p>This request can be retried until the number of entries is less than the value of <code>perPage</code>.</p>
<h3 id="response-10"><a class="header" href="#response-10">Response</a></h3>
<pre><code class="language-json5">{
&quot;loggedIn&quot;: true,
&quot;changeSelectionUrl&quot;: &quot;https://github.com/settings/installations/12345&quot;,
&quot;repositories&quot;:[{
&quot;name&quot;: &quot;matrix-hookshot&quot;,
&quot;owner&quot;: &quot;half-shot&quot;,
&quot;fullName&quot;: &quot;half-shot/matrix-hookshot&quot;,
&quot;avatarUrl&quot;: &quot;https://avatars.githubusercontent.com/u/8418310?v=4&quot;,
&quot;description&quot;: &quot;A bridge between Matrix and multiple project management services, such as GitHub, GitLab and JIRA. &quot;
}]
}
</code></pre>
<h2 id="jira-2"><a class="header" href="#jira-2">JIRA</a></h2>
<h3 id="get-v1jiraoauthuseriduserid"><a class="header" href="#get-v1jiraoauthuseriduserid">GET /v1/jira/oauth?userId={userId}</a></h3>
<p>Request an OAuth url for the given user. Once the user has completed the steps in the OAuth process,
the bridge will be granted access.</p>
<h3 id="response-11"><a class="header" href="#response-11">Response</a></h3>
<pre><code class="language-json5">{
&quot;url&quot;: &quot;https://auth.atlassian.com/authorize?...&quot;
}
</code></pre>
<h3 id="get-v1jiraaccountuseriduserid"><a class="header" href="#get-v1jiraaccountuseriduserid">GET /v1/jira/account?userId={userId}</a></h3>
<p>Request the status of the users account. This will return a <code>loggedIn</code> value to determine if the
bridge has a JIRA identity stored for the user, and any instances they have access to. Note that if a
user does not have access to an instance, they can authenticate again to gain access to it (if they are able
to consent).</p>
<h3 id="response-12"><a class="header" href="#response-12">Response</a></h3>
<pre><code class="language-json5">{
&quot;loggedIn&quot;: true,
&quot;instances&quot;:[{
&quot;name&quot;: &quot;acme&quot;,
&quot;url&quot;: &quot;https://acme.atlassian.net&quot;
}]
}
</code></pre>
<h3 id="get-v1jirainstancesinstancenameprojectsuseriduserid"><a class="header" href="#get-v1jirainstancesinstancenameprojectsuseriduserid">GET /v1/jira/instances/{instanceName}/projects?userId={userId}</a></h3>
<p>Request a list of all projects a user can see in a given instance. The <code>url</code> value of a project can be given to create
a new JIRA connection.</p>
<h3 id="response-13"><a class="header" href="#response-13">Response</a></h3>
<pre><code class="language-json5">[{
&quot;key&quot;: &quot;PLAY&quot;,
&quot;name&quot;: &quot;Jira Playground&quot;,
&quot;url&quot;: &quot;https://acme.atlassian.net/projects/PLAY&quot;
}]
</code></pre>
<div style="break-before: page; page-break-before: always;"></div><h1 id="provisioning-1"><a class="header" href="#provisioning-1">Provisioning</a></h1>
<p>This section is not complete yet for end users. For developers, you can read the documentation for the API below:</p>
<h2 id="provisioning-api-for-matrix-hookshot-1"><a class="header" href="#provisioning-api-for-matrix-hookshot-1">Provisioning API for matrix-hookshot</a></h2>
<h1 id="overview-1"><a class="header" href="#overview-1">Overview</a></h1>
<p>This document describes how to integrate with <code>matrix-hookshot</code>'s provisoning API.</p>
<p>Requests made to the bridge must be against the API listener defined in the config under <code>provisioning</code>, not
the appservice or webhook listeners.</p>
<p>Requests should always be authenticated with the secret given in the config, inside the <code>Authorization</code> header.
Requests being made on behalf of users (most provisioning APIs) should include the userId as a query parameter.</p>
<pre><code>GET /v1/health?userId=%40Half-Shot%3Ahalf-shot.uk
Authorization: Bearer secret
</code></pre>
<p>APIs are versioned independently so two endpoints on the latest version may not always have the same version.</p>
<h1 id="apis-1"><a class="header" href="#apis-1">APIs</a></h1>
<h2 id="get-v1health-1"><a class="header" href="#get-v1health-1">GET /v1/health</a></h2>
<p>Request the status of the provisoning API.</p>
<h3 id="response-14"><a class="header" href="#response-14">Response</a></h3>
<pre><code>HTTP 200
{}
</code></pre>
<p>Any other response should be considered a failed request (e.g. 404, 502 etc).</p>
<h2 id="get-v1connectiontypes-1"><a class="header" href="#get-v1connectiontypes-1">GET /v1/connectiontypes</a></h2>
<p>Request the connection types enabled for this bridge.</p>
<h3 id="response-15"><a class="header" href="#response-15">Response</a></h3>
<pre><code class="language-json5">{
&quot;JiraProject&quot;: {
&quot;type&quot;: &quot;JiraProject&quot;, // The name of the connection
&quot;eventType&quot;: &quot;uk.half-shot.matrix-hookshot.jira.project&quot;, // Corresponds to the state type for the connection
&quot;service&quot;: &quot;jira&quot;, // or github, webhook. A human-readable service name to make things look pretty
&quot;botUserId&quot;: &quot;@hookshot:yourdomain.com&quot;, // The bot mxid for the service. Currently this is the sender_localpart, but may change in the future.
}
}
</code></pre>
<h2 id="get-v1roomidconnections-1"><a class="header" href="#get-v1roomidconnections-1">GET /v1/{roomId}/connections</a></h2>
<p>Request the connections for a given room. The <code>{roomId}</code> parameter is the target Matrix room.</p>
<h3 id="response-16"><a class="header" href="#response-16">Response</a></h3>
<pre><code class="language-json5">[{
&quot;type&quot;: &quot;JiraProject&quot;, // The name of the connection
&quot;eventType&quot;: &quot;uk.half-shot.matrix-hookshot.jira.project&quot;, // Corresponds to the state type in the connection
&quot;id&quot;: &quot;opaque-unique-id&quot;, // An opaque ID used to refer to this connection. Should **NOT** be assumed to be stable.
&quot;service&quot;: &quot;jira&quot;, // or github, webhook. A human-readable service name to make things look pretty
&quot;botUserId&quot;: &quot;@hookshot:yourdomain.com&quot;, // The bot mxid for the service. Currently this is the sender_localpart, but may change in the future.
&quot;config&quot;: {
// ... connection specific details, can be configured.
}
}]
</code></pre>
<h2 id="get-v1roomidconnectionsid-1"><a class="header" href="#get-v1roomidconnectionsid-1">GET /v1/{roomId}/connections/{id}</a></h2>
<p>Request details of a single connection. The <code>{roomId}</code> parameter is the target Matrix room.</p>
<h3 id="response-17"><a class="header" href="#response-17">Response</a></h3>
<pre><code class="language-json5">{
&quot;type&quot;: &quot;JiraProject&quot;, // The name of the connection
&quot;eventType&quot;: &quot;uk.half-shot.matrix-hookshot.jira.project&quot;, // Corresponds to the state type in the connection
&quot;id&quot;: &quot;opaque-unique-id&quot;, // An opaque ID used to refer to this connection. Should **NOT** be assumed to be stable.
&quot;service&quot;: &quot;jira&quot;, // or github, webhook. A human-readable service name to make things look pretty
&quot;botUserId&quot;: &quot;@hookshot:yourdomain.com&quot;, // The bot mxid for the service. Currently this is the sender_localpart, but may change in the future.
&quot;config&quot;: {
// ... connection specific details, can be configured.
}
}
</code></pre>
<h2 id="put-v1roomidconnectionstype-1"><a class="header" href="#put-v1roomidconnectionstype-1">PUT /v1/{roomId}/connections/{type}</a></h2>
<p>Create a new connection of a given type. The type refers to the <code>eventType</code> (<code>IConnection.CanonicalEventType</code>). The <code>{roomId}</code> parameter is the target Matrix room.</p>
<p>The body of the request is the configuration for the connection, which will be the &quot;ConnectionState&quot; interface for each connection.</p>
<h3 id="request-body-2"><a class="header" href="#request-body-2">Request body</a></h3>
<pre><code class="language-json5">{
// ... connection specific details, can be configured.
}
</code></pre>
<h3 id="response-18"><a class="header" href="#response-18">Response</a></h3>
<pre><code class="language-json5">{
&quot;type&quot;: &quot;JiraProject&quot;, // The name of the connection
&quot;eventType&quot;: &quot;uk.half-shot.matrix-hookshot.jira.project&quot;, // Corresponds to the state type in the connection
&quot;id&quot;: &quot;opaque-unique-id&quot;, // An opaque ID used to refer to this connection. Should **NOT** be assumed to be stable.
&quot;service&quot;: &quot;jira&quot;, // or github, webhook. A human-readable service name to make things look pretty
&quot;botUserId&quot;: &quot;@hookshot:yourdomain.com&quot;, // The bot mxid for the service. Currently this is the sender_localpart, but may change in the future.
&quot;config&quot;: {
// ... connection specific details, can be configured.
}
}
</code></pre>
<h2 id="patch-v1roomidconnectionsid-1"><a class="header" href="#patch-v1roomidconnectionsid-1">PATCH /v1/{roomId}/connections/{id}</a></h2>
<p>Update a connection's configuration. The <code>id</code> refers to the <code>id</code> returned in the GET response.</p>
<p>The body of the request is the configuration for the connection, which will be the &quot;ConnectionState&quot; interface for each connection.</p>
<h3 id="request-body-3"><a class="header" href="#request-body-3">Request body</a></h3>
<pre><code class="language-json5">{
// ... connection specific details, can be configured.
}
</code></pre>
<h3 id="response-19"><a class="header" href="#response-19">Response</a></h3>
<pre><code class="language-json5">{
&quot;type&quot;: &quot;JiraProject&quot;, // The name of the connection
&quot;eventType&quot;: &quot;uk.half-shot.matrix-hookshot.jira.project&quot;, // Corresponds to the state type in the connection
&quot;id&quot;: &quot;opaque-unique-id&quot;, // An opaque ID used to refer to this connection. Should **NOT** be assumed to be stable.
&quot;service&quot;: &quot;jira&quot;, // or github, webhook. A human-readable service name to make things look pretty
&quot;botUserId&quot;: &quot;@hookshot:yourdomain.com&quot;, // The bot mxid for the service. Currently this is the sender_localpart, but may change in the future.
&quot;config&quot;: {
// ... connection specific details, can be configured.
}
}
</code></pre>
<h2 id="delete-v1roomidconnectionsid-1"><a class="header" href="#delete-v1roomidconnectionsid-1">DELETE /v1/{roomId}/connections/{id}</a></h2>
<p>Delete a connection. The <code>id</code> refers to the <code>id</code> returned in the GET response.</p>
<h3 id="response-20"><a class="header" href="#response-20">Response</a></h3>
<pre><code class="language-json5">{
&quot;ok&quot;: true
}
</code></pre>
<h1 id="service-specific-apis-1"><a class="header" href="#service-specific-apis-1">Service specific APIs</a></h1>
<p>Some services have specific APIs for additional functionality, like OAuth.</p>
<h2 id="github-2"><a class="header" href="#github-2">GitHub</a></h2>
<h3 id="get-v1githuboauthuseriduserid-1"><a class="header" href="#get-v1githuboauthuseriduserid-1">GET /v1/github/oauth?userId={userId}</a></h3>
<p>Request an OAuth url for the given user. Once the user has completed the steps in the OAuth process,
the bridge will be granted access.</p>
<h3 id="response-21"><a class="header" href="#response-21">Response</a></h3>
<pre><code class="language-json5">[{
&quot;user_url&quot;: &quot;https://github.com/login/oauth/authorize?...&quot;,
&quot;org_url&quot;: &quot;https://github.com/apps/matrix-bridge/installations/new&quot;,
}]
</code></pre>
<h3 id="get-v1githubaccountuseriduserid-1"><a class="header" href="#get-v1githubaccountuseriduserid-1">GET /v1/github/account?userId={userId}</a></h3>
<p>Request the status of the users account. This will return a <code>loggedIn</code> value to determine if the
bridge has a GitHub identity stored for the user, and any organisations they have access to.</p>
<h3 id="response-22"><a class="header" href="#response-22">Response</a></h3>
<pre><code class="language-json5">{
&quot;loggedIn&quot;: true,
&quot;organisations&quot;:[{
&quot;name&quot;: &quot;half-shot&quot;,
&quot;avatarUrl&quot;: &quot;https://avatars.githubusercontent.com/u/8418310?v=4&quot;
}]
}
</code></pre>
<h3 id="get-v1githuborgsorgnamerepositoriesuseriduseridpagepageperpageperpage-1"><a class="header" href="#get-v1githuborgsorgnamerepositoriesuseriduseridpagepageperpageperpage-1">GET /v1/github/orgs/{orgName}/repositories?userId={userId}&amp;page={page}&amp;perPage={perPage}</a></h3>
<p>Request a list of all repositories a user is a member of in the given org. The <code>owner</code> and <code>name</code> value of a repository can be given to create a new GitHub connection.</p>
<p>This request is paginated, and <code>page</code> sets the page (defaults to <code>1</code>) while <code>perPage</code> (defaults to <code>10</code>) sets the number of entries per page.</p>
<p>This request can be retried until the number of entries is less than the value of <code>perPage</code>.</p>
<h3 id="response-23"><a class="header" href="#response-23">Response</a></h3>
<pre><code class="language-json5">{
&quot;loggedIn&quot;: true,
&quot;repositories&quot;:[{
&quot;name&quot;: &quot;matrix-hookshot&quot;,
&quot;owner&quot;: &quot;half-shot&quot;,
&quot;fullName&quot;: &quot;half-shot/matrix-hookshot&quot;,
&quot;avatarUrl&quot;: &quot;https://avatars.githubusercontent.com/u/8418310?v=4&quot;,
&quot;description&quot;: &quot;A bridge between Matrix and multiple project management services, such as GitHub, GitLab and JIRA. &quot;
}]
}
</code></pre>
<h3 id="get-v1githubrepositoriesuseriduseridpagepageperpageperpage-1"><a class="header" href="#get-v1githubrepositoriesuseriduseridpagepageperpageperpage-1">GET /v1/github/repositories?userId={userId}&amp;page={page}&amp;perPage={perPage}</a></h3>
<p>Request a list of all repositories a user is a member of (including those not belonging to an org). The <code>owner</code> and <code>name</code> value of a repository can be given to create a new GitHub connection.</p>
<p>If the user has only allowed a subset of repositories to be bridged, <code>changeSelectionUrl</code> will be defined and can be used to expand the search query.</p>
<p>This request is paginated, and <code>page</code> sets the page (defaults to <code>1</code>) while <code>perPage</code> (defaults to <code>10</code>) sets the number of entries per page.</p>
<p>This request can be retried until the number of entries is less than the value of <code>perPage</code>.</p>
<h3 id="response-24"><a class="header" href="#response-24">Response</a></h3>
<pre><code class="language-json5">{
&quot;loggedIn&quot;: true,
&quot;changeSelectionUrl&quot;: &quot;https://github.com/settings/installations/12345&quot;,
&quot;repositories&quot;:[{
&quot;name&quot;: &quot;matrix-hookshot&quot;,
&quot;owner&quot;: &quot;half-shot&quot;,
&quot;fullName&quot;: &quot;half-shot/matrix-hookshot&quot;,
&quot;avatarUrl&quot;: &quot;https://avatars.githubusercontent.com/u/8418310?v=4&quot;,
&quot;description&quot;: &quot;A bridge between Matrix and multiple project management services, such as GitHub, GitLab and JIRA. &quot;
}]
}
</code></pre>
<h2 id="jira-3"><a class="header" href="#jira-3">JIRA</a></h2>
<h3 id="get-v1jiraoauthuseriduserid-1"><a class="header" href="#get-v1jiraoauthuseriduserid-1">GET /v1/jira/oauth?userId={userId}</a></h3>
<p>Request an OAuth url for the given user. Once the user has completed the steps in the OAuth process,
the bridge will be granted access.</p>
<h3 id="response-25"><a class="header" href="#response-25">Response</a></h3>
<pre><code class="language-json5">{
&quot;url&quot;: &quot;https://auth.atlassian.com/authorize?...&quot;
}
</code></pre>
<h3 id="get-v1jiraaccountuseriduserid-1"><a class="header" href="#get-v1jiraaccountuseriduserid-1">GET /v1/jira/account?userId={userId}</a></h3>
<p>Request the status of the users account. This will return a <code>loggedIn</code> value to determine if the
bridge has a JIRA identity stored for the user, and any instances they have access to. Note that if a
user does not have access to an instance, they can authenticate again to gain access to it (if they are able
to consent).</p>
<h3 id="response-26"><a class="header" href="#response-26">Response</a></h3>
<pre><code class="language-json5">{
&quot;loggedIn&quot;: true,
&quot;instances&quot;:[{
&quot;name&quot;: &quot;acme&quot;,
&quot;url&quot;: &quot;https://acme.atlassian.net&quot;
}]
}
</code></pre>
<h3 id="get-v1jirainstancesinstancenameprojectsuseriduserid-1"><a class="header" href="#get-v1jirainstancesinstancenameprojectsuseriduserid-1">GET /v1/jira/instances/{instanceName}/projects?userId={userId}</a></h3>
<p>Request a list of all projects a user can see in a given instance. The <code>url</code> value of a project can be given to create
a new JIRA connection.</p>
<h3 id="response-27"><a class="header" href="#response-27">Response</a></h3>
<pre><code class="language-json5">[{
&quot;key&quot;: &quot;PLAY&quot;,
&quot;name&quot;: &quot;Jira Playground&quot;,
&quot;url&quot;: &quot;https://acme.atlassian.net/projects/PLAY&quot;
}]
</code></pre>
<div style="break-before: page; page-break-before: always;"></div><h1 id="workers"><a class="header" href="#workers">Workers</a></h1>
<p>Hookshot supports running in a worker configuration, using Redis as the middleman process to handle traffic between processes.</p>
<section class="warning">
This feature is <b>experimental</b> and should only be used when you are reaching natural limits in the monolith process.
</section>
<h2 id="running-in-multi-process-mode"><a class="header" href="#running-in-multi-process-mode">Running in multi-process mode</a></h2>
<p>You must first have a working redis instance somewhere which can talk between processes. For example, in Docker you can run:</p>
<p><code>docker run --name github-bridge-redis -p 6379:6379 -d redis</code>.</p>
<p>The processes should all share the same config, which should contain the correct config enable redis:</p>
<pre><code class="language-yaml">queue:
monolithic: true
port: 6379
host: github-bridge-redis
</code></pre>
<p>Once that is done, you can simply start the processes by name using yarn:</p>
<pre><code>yarn start:webhooks
yarn start:matrixsender
yarn start:app
</code></pre>
<p>Be aware that you will need to start all worker types when running in worker mode, as the service does not allow a hybrid worker approach.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
<script type="text/javascript">
window.addEventListener('load', function() {
window.setTimeout(window.print, 100);
});
</script>
</body>
</html>