Supporting-docs now in matrix.org repo.
parent
17af66105d
commit
e7772af5c3
@ -1,129 +0,0 @@
|
|||||||
Application Services
|
|
||||||
====================
|
|
||||||
|
|
||||||
This file contains examples of some application service
|
|
||||||
|
|
||||||
IRC Bridge
|
|
||||||
----------
|
|
||||||
Pre-conditions:
|
|
||||||
- Server admin stores the AS token "T_a" on the homeserver.
|
|
||||||
- Homeserver has a token "T_h".
|
|
||||||
- Homeserver has the domain "hsdomain.com"
|
|
||||||
|
|
||||||
1. Application service registration
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
AS -> HS: Registers itself with the homeserver
|
|
||||||
POST /register
|
|
||||||
{
|
|
||||||
url: "https://someapp.com/matrix",
|
|
||||||
as_token: "T_a",
|
|
||||||
namespaces: {
|
|
||||||
users: [
|
|
||||||
{
|
|
||||||
"exclusive": true,
|
|
||||||
"regex": "@irc\.freenode\.net/.*"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
aliases: [
|
|
||||||
{
|
|
||||||
"exclusive": true,
|
|
||||||
"regex": "#irc\.freenode\.net/.*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Returns 200 OK:
|
|
||||||
{
|
|
||||||
hs_token: "T_h"
|
|
||||||
}
|
|
||||||
|
|
||||||
2. IRC user "Bob" says "hello?" on "#matrix" at timestamp 1421416883133:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
- AS stores message as potential scrollback.
|
|
||||||
- Nothing happens as no Matrix users are in the room.
|
|
||||||
|
|
||||||
3. Matrix user "@alice:hsdomain.com" wants to join "#matrix":
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
User -> HS: Request to join "#irc.freenode.net/#matrix:hsdomain.com"
|
|
||||||
|
|
||||||
HS -> AS: Room Query "#irc.freenode.net/#matrix:hsdomain.com"
|
|
||||||
GET /rooms/%23irc.freenode.net%2F%23matrix%3Ahsdomain.com?access_token=T_h
|
|
||||||
[Starts blocking]
|
|
||||||
AS -> HS: Creates room. Gets room ID "!aasaasasa:hsdomain.com".
|
|
||||||
AS -> HS: Sets room name to "#matrix".
|
|
||||||
AS -> HS: Sends message as ""@irc.freenode.net/Bob:hsdomain.com"
|
|
||||||
PUT /rooms/%21aasaasasa%3Ahsdomain.com/send/m.room.message
|
|
||||||
?access_token=T_a
|
|
||||||
&user_id=%40irc.freenode.net%2FBob%3Ahsdomain.com
|
|
||||||
&ts=1421416883133
|
|
||||||
{
|
|
||||||
body: "hello?"
|
|
||||||
msgtype: "m.text"
|
|
||||||
}
|
|
||||||
HS -> AS: User Query "@irc.freenode.net/Bob:hsdomain.com"
|
|
||||||
GET /users/%40irc.freenode.net%2FBob%3Ahsdomain.com?access_token=T_h
|
|
||||||
[Starts blocking]
|
|
||||||
AS -> HS: Creates user using CS API extension.
|
|
||||||
POST /register?access_token=T_a
|
|
||||||
{
|
|
||||||
type: "m.login.application_service",
|
|
||||||
user: "irc.freenode.net/Bob"
|
|
||||||
}
|
|
||||||
AS -> HS: Set user display name to "Bob".
|
|
||||||
[Finishes blocking]
|
|
||||||
[Finished blocking]
|
|
||||||
|
|
||||||
- HS sends room information back to client.
|
|
||||||
|
|
||||||
4. @alice:hsdomain.com says "hi!" in this room:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
User -> HS: Send message "hi!" in room !aasaasasa:hsdomain.com
|
|
||||||
|
|
||||||
- HS sends message.
|
|
||||||
- HS sees the room ID is in the AS namespace and pushes it to the AS.
|
|
||||||
|
|
||||||
HS -> AS: Push event
|
|
||||||
PUT /transactions/1?access_token=T_h
|
|
||||||
{
|
|
||||||
events: [
|
|
||||||
{
|
|
||||||
content: {
|
|
||||||
body: "hi!",
|
|
||||||
msgtype: "m.text"
|
|
||||||
},
|
|
||||||
origin_server_ts: <generated by hs>,
|
|
||||||
user_id: "@alice:hsdomain.com",
|
|
||||||
room_id: "!aasaasasa:hsdomain.com",
|
|
||||||
type: "m.room.message"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
- AS passes this through to IRC.
|
|
||||||
|
|
||||||
|
|
||||||
5. IRC user "Bob" says "what's up?" on "#matrix" at timestamp 1421418084816:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
IRC -> AS: "what's up?"
|
|
||||||
AS -> HS: Send message via CS API extension
|
|
||||||
PUT /rooms/%21aasaasasa%3Ahsdomain.com/send/m.room.message
|
|
||||||
?access_token=T_a
|
|
||||||
&user_id=%40irc.freenode.net%2FBob%3Ahsdomain.com
|
|
||||||
&ts=1421418084816
|
|
||||||
{
|
|
||||||
body: "what's up?"
|
|
||||||
msgtype: "m.text"
|
|
||||||
}
|
|
||||||
|
|
||||||
- HS modifies the user_id and origin_server_ts on the event and sends it.
|
|
@ -1,141 +0,0 @@
|
|||||||
---
|
|
||||||
layout: post
|
|
||||||
title: Getting involved
|
|
||||||
categories: guides
|
|
||||||
---
|
|
||||||
|
|
||||||
# How can I get involved?
|
|
||||||
Matrix is an ecosystem consisting of several apps written by lots of people. We at Matrix.org have written one server and a few clients, and people in the community have also written several clients, servers, and Application Services. We are collecting [a list of all known Matrix-apps](https://matrix.org/blog/try-matrix-now/).
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
You have a few options when it comes to getting involved: if you just want to use Matrix, you can [register an account on a public server using a public webclient](#reg). If you have a virtual private server (VPS) or similar, you might want to [run a server and/or client yourself](#run). If you want to look under the hood, you can [checkout the code and modify it - or write your own client or server](#checkout). Or you can write an [Application Service](#as), for example a bridge to an existing ecosystem.
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
We very much welcome [contributions](https://github.com/matrix-org/synapse/blob/master/CONTRIBUTING.rst) to any of our projects, which you can find in our [github space](https://github.com/matrix-org/).
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
<a class="anchor" id="reg"></a>
|
|
||||||
|
|
||||||
## Access Matrix via a public webclient/server
|
|
||||||
|
|
||||||
The easiest thing to do if you want to just have a play, is to use the [Riot.im
|
|
||||||
webclient](https://riot.im). You can use it as a guest, or register for an
|
|
||||||
account. For details of other clients, see
|
|
||||||
[https://matrix.org/blog/try-matrix-now](https://matrix.org/blog/try-matrix-now).
|
|
||||||
|
|
||||||
<a class="anchor" id="run"></a>
|
|
||||||
|
|
||||||
## Run a server and/or client yourself
|
|
||||||
|
|
||||||
You can clone our open source projects and run clients and servers yourself. Here is how:
|
|
||||||
|
|
||||||
### Running your own client:
|
|
||||||
|
|
||||||
You can run your own Matrix client; there are [numerous clients
|
|
||||||
available](https://matrix.org/blog/try-matrix-now/). You can easily [run your
|
|
||||||
own copy](https://github.com/vector-im/vector-web#getting-started) of the
|
|
||||||
Riot.im web client.
|
|
||||||
|
|
||||||
### Running your own homeserver:
|
|
||||||
|
|
||||||
One of the core features of Matrix is that anyone can run a homeserver and join the federated network on equal terms (there is no hierarchy). If you want to set up your own homeserver, please see the relevant docs of the server you want to run. If you want to run Matrix.org's reference homeserver, please consult the [readme of the Synapse project](https://github.com/matrix-org/synapse/blob/master/README.rst).
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
Note that Synapse comes with a bundled Matrix.org webclient - but you can tell it to use your [development checkout snapshot instead](https://github.com/matrix-org/matrix-angular-sdk#matrix-angular-sdk) (or to not run a webclient at all via the "web_client: false" config option).
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
<a class="anchor" id="checkout"></a>
|
|
||||||
|
|
||||||
## Checkout our code - or write your own
|
|
||||||
|
|
||||||
As described above, you can clone our code and [run a server and/or client yourself](#run). Infact, all the code that we at Matrix.org write is available from [our github](http://github.com/matrix-org) - and other servers and clients may also be open sourced - see [our list of all known Matrix-apps](https://matrix.org/blog/try-matrix-now/).
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
You can also implement your own client or server - after all, Matrix is at its core "just" a specification of a protocol.
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
### Write your own client:
|
|
||||||
|
|
||||||
The [client-server API
|
|
||||||
spec](http://matrix.org/docs/spec/client_server/latest.html) describes what API
|
|
||||||
calls are available to clients, and there is a [HOWTO
|
|
||||||
guide](http://matrix.org/docs/guides/client-server.html) which provides an
|
|
||||||
introduction to using the API along with some common operations. A quick
|
|
||||||
step-by-step guide would include:
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
1. Get a user either by registering your user in an existing client or running the [new-user script](https://github.com/matrix-org/synapse/blob/master/scripts/register_new_matrix_user) if you are running your own Synapse homeserver.
|
|
||||||
|
|
||||||
2. Assuming the homeserver you are using allows logins by password, log in via the login API:
|
|
||||||
|
|
||||||
```
|
|
||||||
curl -XPOST -d '{"type":"m.login.password", "user":"example", "password":"wordpass"}' "http://localhost:8008/_matrix/client/api/v1/login"
|
|
||||||
```
|
|
||||||
|
|
||||||
3. If successful, this returns the following, including an `access_token`:
|
|
||||||
|
|
||||||
{
|
|
||||||
"access_token": "QGV4YW1wbGU6bG9jYWxob3N0.vRDLTgxefmKWQEtgGd",
|
|
||||||
"home_server": "localhost",
|
|
||||||
"user_id": "@example:localhost"
|
|
||||||
}
|
|
||||||
|
|
||||||
4. This ``access_token`` will be used for authentication for the rest of your API calls. Potentially the next step you want is to make a call to the sync API and get the last few events from each room your user is in:
|
|
||||||
|
|
||||||
```
|
|
||||||
curl -XGET "http://localhost:8008/_matrix/client/r0/sync?access_token=YOUR_ACCESS_TOKEN"
|
|
||||||
```
|
|
||||||
|
|
||||||
5. The above will return something like this:
|
|
||||||
|
|
||||||
{
|
|
||||||
"next_batch": "s72595_4483_1934",
|
|
||||||
"rooms": {
|
|
||||||
"join": {
|
|
||||||
"!726s6s6q:example.com": {
|
|
||||||
"state": {
|
|
||||||
"events": [
|
|
||||||
...
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"timeline": {
|
|
||||||
"events": [
|
|
||||||
...
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
You can then use the "next_batch" token to start listening for new events like so:
|
|
||||||
|
|
||||||
```
|
|
||||||
curl -XGET "http://localhost:8008/_matrix/client/r0/sync?access_token=YOUR_ACCESS_TOKEN&since=s72595_4483_1934"
|
|
||||||
```
|
|
||||||
|
|
||||||
6. This request will block waiting for an incoming event, timing out after several seconds if there is no event. This ensures that you only get new events. Now you have the initial room states, and a stream of events - a good client should be able to process all these events and present them to the user. And potentially you might want to add functionality to generate events as well (such as messages from the user, for example)!
|
|
||||||
|
|
||||||
### Write your own server:
|
|
||||||
|
|
||||||
We are still working on the server-server spec, so the best thing to do if you are interested in writing a server, is to come talk to us in [#matrix:matrix.org](https://matrix.to/#/#matrix:matrix.org).
|
|
||||||
|
|
||||||
If you are interested in how federation works, please see the [Server-Server API spec](http://matrix.org/docs/spec/server_server/unstable.html).
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
<a class="anchor" id="as"></a>
|
|
||||||
|
|
||||||
## Write an Application Service:
|
|
||||||
|
|
||||||
Information about Application services and how they can be used can be found in the [Application services](./application_services.html) document! (This is based on Kegan's excellent blog posts, but now lives here so it can be kept up-to-date!)
|
|
@ -1,18 +0,0 @@
|
|||||||
---
|
|
||||||
layout: default
|
|
||||||
categories: guides
|
|
||||||
---
|
|
||||||
<div class="home">
|
|
||||||
|
|
||||||
<h1>Guides</h1>
|
|
||||||
|
|
||||||
<p>Here is a collection of guides that might help you get involved with Matrix.</p>
|
|
||||||
<p>First, there is the <a href="./getting_involved.html" title="Getting Involved">Getting Involved</a> guide, which explains various ways of getting started with Matrix, and the <a href="./faq.html" title="FAQ">FAQ</a>, which tries to answer all your questions relating to Matrix.</p>
|
|
||||||
<p>The <a href="/docs/guides/client-server.html" title="Client-Server API">Client-Server API</a> guide explains in detail how to use the CS API, which is useful if you want to write a client (or modify an existing one) - or if you're just interested in how it works "under the hood".</p>
|
|
||||||
<p>If you were using the old v1 CS API, there is also the <a href="/docs/guides/client-server-migrating-from-v1.html">v1 migration guide</a> which justs lists the changes from v1 to r0.</p>
|
|
||||||
<p><a href="./lets-encrypt.html">Let's Encrypt Matrix</a> explains how to use Let's Encrypt's certificates with your Synapse installation. This guide was written by William A Stevens.</p>
|
|
||||||
<p>The <a href="./application_services.html" title="Application services">Application services</a> guide introduces and explains Application services, and what they can be used for.</p>
|
|
||||||
<p><a href="./types-of-bridging.html">Types of Bridging</a> should be read by all bridge developers to ensure everyone has the same mental map of terminology when implementing bridges.</p>
|
|
||||||
<p>The <a href="./e2e_implementation.html">End-to-end Encryption Implementation Guide</a> is intended for client developers who wish to add support for end-to-end encryption.</p>
|
|
||||||
|
|
||||||
</div>
|
|
@ -1,37 +0,0 @@
|
|||||||
---
|
|
||||||
layout: post
|
|
||||||
title: Let's Encrypt Matrix
|
|
||||||
categories: guides
|
|
||||||
---
|
|
||||||
|
|
||||||
====================
|
|
||||||
Let's Encrypt Matrix
|
|
||||||
====================
|
|
||||||
|
|
||||||
Let's Encrypt is a free Certificate Authority that makes it easy to secure your server's internet traffic. This makes it really easy to secure your Matrix homeserver, and this guide will explain exactly how you do this. Guide written by William A Stevens - thanks!
|
|
||||||
|
|
||||||
0: Prerequisites
|
|
||||||
================
|
|
||||||
* Install Synapse_.
|
|
||||||
* Install (or Download) certbot_
|
|
||||||
|
|
||||||
1: Get certificates
|
|
||||||
===================
|
|
||||||
When executing the Let's Encrypt client, it will ask for the domain name of your server, and your email address. The domain list can include multiple names and should include any domain you want to access the server from.
|
|
||||||
|
|
||||||
Also, the certificates will be in a folder under /etc/letsencrypt (see below) and owned by root.
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
# certbot certonly --standalone
|
|
||||||
|
|
||||||
A note about renewal
|
|
||||||
--------------------
|
|
||||||
These certificates will expire in 3 months. To renew certificates, run ```certbot renew```. It is recommended to create a cronjob, which attempts renewal twice a day. Depending on your distribution, that could be already configured.
|
|
||||||
|
|
||||||
2: Install Certificates
|
|
||||||
=======================
|
|
||||||
At the top of your homeserver.yaml there should be two keys, ```tls_certificate_path``` and ```tls_private_key_path```. These should be changed so that instead of pointing to the default keys, they now point to the Let's Encrypt keys. ```tls_certificate_path``` should point to ```/etc/letsencrypt/live/(your domain name)/fullchain.pem```. ```tls_private_key_path``` should point to ```/etc/letsencrypt/live/(your domain name)/privkey.pem```. ```tls_dh_params_path``` can stay the same as before.
|
|
||||||
|
|
||||||
.. _Synapse: https://github.com/matrix-org/synapse/blob/master/README.rst#synapse-installation
|
|
||||||
.. _certbot: https://certbot.eff.org/
|
|
@ -1,114 +0,0 @@
|
|||||||
---
|
|
||||||
layout: post
|
|
||||||
title: Migrating from Client Server API v1
|
|
||||||
categories: guides
|
|
||||||
---
|
|
||||||
|
|
||||||
Migrating from client-server API v1
|
|
||||||
===================================
|
|
||||||
|
|
||||||
This guide assists developers of API clients that target the ``v1`` version of
|
|
||||||
the API to migrate their code to the later ``r0``. It does not aim to introduce
|
|
||||||
new concepts that were added in ``r0`` except where these replace things that
|
|
||||||
were removed since ``v1``.
|
|
||||||
|
|
||||||
Updated Version In Path
|
|
||||||
=======================
|
|
||||||
|
|
||||||
The new version of the API is ``r0``; this should be used in paths where
|
|
||||||
``v1`` used to appear. Additionally, the ``/api`` path component has now been
|
|
||||||
removed. API endpoint paths are now::
|
|
||||||
|
|
||||||
POST /_matrix/client/r0/register
|
|
||||||
GET /_matrix/client/r0/login
|
|
||||||
etc...
|
|
||||||
|
|
||||||
New Registration and Login Endpoints
|
|
||||||
====================================
|
|
||||||
|
|
||||||
The ``r0`` version of the ``/register`` and ``/login`` endpoints is different
|
|
||||||
to the ``v1`` version. See the updated API documentation for details on how the
|
|
||||||
new API works. In brief, the changes are that the new version returns extra
|
|
||||||
information in the form of the ``params`` object, and that a sequence of
|
|
||||||
multiple calls may be statefully chained together by the ``session`` parameter.
|
|
||||||
|
|
||||||
Additionally, whereas in ``v1`` the client performed a ``GET`` request to
|
|
||||||
discover the list of supported flows for ``/register``, in ``r0`` this is done
|
|
||||||
by sending a ``POST`` request with an empty data body. The ``/login`` endpoint
|
|
||||||
continues to use the ``GET`` method as before.
|
|
||||||
|
|
||||||
Deprecated Endpoints
|
|
||||||
====================
|
|
||||||
|
|
||||||
The following endpoints are now deprecated and replaced by the ``/sync`` API::
|
|
||||||
|
|
||||||
/initialSync
|
|
||||||
/events
|
|
||||||
/rooms/:roomId/initialSync
|
|
||||||
|
|
||||||
The new ``/sync`` API takes an optional ``since`` parameter to distinguish the
|
|
||||||
initial sync from subsequent updates for more events.
|
|
||||||
|
|
||||||
The return value takes a different structure to that from the previous
|
|
||||||
``/initialSync`` API. For full details see the API documentation, but the
|
|
||||||
following summary may be useful to compare with ``v1``:
|
|
||||||
|
|
||||||
* ``/initialSync`` returned a ``state`` key containing the most recent state
|
|
||||||
in the room, whereas the new ``/sync`` API's ``state`` corresponds to the
|
|
||||||
room state at the start of the returned timeline. This makes it easier for
|
|
||||||
clients to represent state changes that occur within the region of returned
|
|
||||||
timeline.
|
|
||||||
|
|
||||||
* In ``/events``, if more events occurred since the ``since`` token than the
|
|
||||||
``limit`` parameter allowed, then events from the start of this range were
|
|
||||||
returned and the client had to perform another fetch to incrementally obtain
|
|
||||||
more of them. In the ``/sync`` API the result always contains the most
|
|
||||||
recent events, creating a gap if this would be more events than the
|
|
||||||
requested limit. If this occurs then the client can use the ``prev_batch``
|
|
||||||
token as a reference to obtaining more.
|
|
||||||
|
|
||||||
* The ``state`` contained in the response to a ``/sync`` request that has a
|
|
||||||
``since`` parameter will contain only keys that have changed since the
|
|
||||||
basis given in the ``since`` parameter, rather than containing a full set
|
|
||||||
values.
|
|
||||||
|
|
||||||
The ``/initialSync`` API allowed a parameter called ``limit`` to limit the
|
|
||||||
number of events returned. To apply this limit to the new ``/sync`` API, you
|
|
||||||
can supply an ad-hoc filter::
|
|
||||||
|
|
||||||
GET .../sync?filter={"room":{"timeline":{"limit:$limit}}}
|
|
||||||
|
|
||||||
There is no direct replacement for the per-room ``/rooms/:roomId/initialSync``
|
|
||||||
endpoint, but the behaviour can be recreated by applying an ad-hoc filter using
|
|
||||||
the ``filter`` parameter to ``/sync`` that selects only the required room ID::
|
|
||||||
|
|
||||||
GET .../sync?filter={"room":{"rooms":[$room_id]}}
|
|
||||||
|
|
||||||
However, the way that the new ``/sync`` API works should remove any need to do
|
|
||||||
this kind of query, in the situations where the ``v1`` API needed it.
|
|
||||||
Specifically, on joining a new room the initial information about that room is
|
|
||||||
sent in the next ``/sync`` batch, so it should not be necessary to query that
|
|
||||||
one room specially.
|
|
||||||
|
|
||||||
The following endpoint is deprecated and has no direct replacement::
|
|
||||||
|
|
||||||
/events/:eventId
|
|
||||||
|
|
||||||
However, if the client knows the room ID of the room that the event is in, it
|
|
||||||
can use the ``/rooms/:roomId/context/:eventId`` request to fetch the event
|
|
||||||
itself. By giving the ``limit`` parameter of ``0`` the client can save using
|
|
||||||
extra bandwidth by actually returning additional context events around the
|
|
||||||
requested one.
|
|
||||||
|
|
||||||
Removed POST Endpoint
|
|
||||||
=====================
|
|
||||||
|
|
||||||
The room message sending API endpoint in ``v1`` accepted both ``PUT`` and
|
|
||||||
``POST`` methods, where the client could specify a message ID in the ``PUT``
|
|
||||||
path for de-duplication purposes, or have the server allocate one during
|
|
||||||
``POST``. In ``r0`` this latter form no longer exists. Clients will now have
|
|
||||||
to generate these IDs locally.
|
|
||||||
|
|
||||||
The following URLs have therefore been removed::
|
|
||||||
|
|
||||||
POST .../rooms/:roomId/send/:messageType
|
|
@ -1,394 +0,0 @@
|
|||||||
---
|
|
||||||
layout: post
|
|
||||||
title: Client Server API
|
|
||||||
categories: guides
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
.. TODO kegan
|
|
||||||
Room config (specifically: message history,
|
|
||||||
public rooms).
|
|
||||||
|
|
||||||
How to use the client-server API
|
|
||||||
================================
|
|
||||||
|
|
||||||
.. NOTE::
|
|
||||||
The git version of this document is ``{% project_version %}``
|
|
||||||
|
|
||||||
This guide focuses on how the client-server APIs *provided by the reference
|
|
||||||
homeserver* can be used. Since this is specific to a homeserver
|
|
||||||
implementation, there may be variations in relation to registering/logging in
|
|
||||||
which are not covered in extensive detail in this guide.
|
|
||||||
|
|
||||||
If you haven't already, get a homeserver up and running on
|
|
||||||
``https://localhost:8448``.
|
|
||||||
|
|
||||||
|
|
||||||
Accounts
|
|
||||||
========
|
|
||||||
Before you can send and receive messages, you must **register** for an account.
|
|
||||||
If you already have an account, you must **login** into it.
|
|
||||||
|
|
||||||
.. NOTE::
|
|
||||||
`Try out the fiddle`__
|
|
||||||
|
|
||||||
.. __: http://jsfiddle.net/gh/get/jquery/1.8.3/matrix-org/matrix-doc/tree/master/supporting-docs/howtos/jsfiddles/register_login
|
|
||||||
|
|
||||||
Registration
|
|
||||||
------------
|
|
||||||
The aim of registration is to get a user ID and access token which you will need
|
|
||||||
when accessing other APIs::
|
|
||||||
|
|
||||||
curl -XPOST -d '{"username":"example", "password":"wordpass", "auth": {"type":"m.login.dummy"}}' "https://localhost:8448/_matrix/client/r0/register"
|
|
||||||
|
|
||||||
{
|
|
||||||
"access_token": "QGV4YW1wbGU6bG9jYWxob3N0.AqdSzFmFYrLrTmteXc",
|
|
||||||
"home_server": "localhost",
|
|
||||||
"user_id": "@example:localhost"
|
|
||||||
}
|
|
||||||
|
|
||||||
NB: If a ``user`` is not specified, one will be randomly generated for you.
|
|
||||||
If you do not specify a ``password``, you will be unable to login to the account
|
|
||||||
if you forget the ``access_token``.
|
|
||||||
|
|
||||||
Implementation note: The matrix specification does not enforce how users
|
|
||||||
register with a server. It just specifies the URL path and absolute minimum
|
|
||||||
keys. The reference homeserver uses a username/password to authenticate user,
|
|
||||||
but other homeservers may use different methods. This is why you need to
|
|
||||||
specify the ``type`` of method.
|
|
||||||
|
|
||||||
Login
|
|
||||||
-----
|
|
||||||
The aim when logging in is to get an access token for your existing user ID::
|
|
||||||
|
|
||||||
curl -XGET "https://localhost:8448/_matrix/client/r0/login"
|
|
||||||
|
|
||||||
{
|
|
||||||
"flows": [
|
|
||||||
{
|
|
||||||
"type": "m.login.password"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
curl -XPOST -d '{"type":"m.login.password", "user":"example", "password":"wordpass"}' "https://localhost:8448/_matrix/client/r0/login"
|
|
||||||
|
|
||||||
{
|
|
||||||
"access_token": "QGV4YW1wbGU6bG9jYWxob3N0.vRDLTgxefmKWQEtgGd",
|
|
||||||
"home_server": "localhost",
|
|
||||||
"user_id": "@example:localhost"
|
|
||||||
}
|
|
||||||
|
|
||||||
Implementation note: Different homeservers may implement different methods for
|
|
||||||
logging in to an existing account. In order to check that you know how to login
|
|
||||||
to this homeserver, you must perform a ``GET`` first and make sure you
|
|
||||||
recognise the login type. If you do not know how to login, you can
|
|
||||||
``GET /login/fallback`` which will return a basic webpage which you can use to
|
|
||||||
login. The reference homeserver implementation support username/password login,
|
|
||||||
but other homeservers may support different login methods (e.g. OAuth2).
|
|
||||||
|
|
||||||
|
|
||||||
Communicating
|
|
||||||
=============
|
|
||||||
|
|
||||||
In order to communicate with another user, you must **create a room** with that
|
|
||||||
user and **send a message** to that room.
|
|
||||||
|
|
||||||
.. NOTE::
|
|
||||||
`Try out the fiddle`__
|
|
||||||
|
|
||||||
.. __: http://jsfiddle.net/gh/get/jquery/1.8.3/matrix-org/matrix-doc/tree/master/supporting-docs/howtos/jsfiddles/create_room_send_msg
|
|
||||||
|
|
||||||
Creating a room
|
|
||||||
---------------
|
|
||||||
If you want to send a message to someone, you have to be in a room with them. To
|
|
||||||
create a room::
|
|
||||||
|
|
||||||
curl -XPOST -d '{"room_alias_name":"tutorial"}' "https://localhost:8448/_matrix/client/r0/createRoom?access_token=YOUR_ACCESS_TOKEN"
|
|
||||||
|
|
||||||
{
|
|
||||||
"room_alias": "#tutorial:localhost",
|
|
||||||
"room_id": "!asfLdzLnOdGRkdPZWu:localhost"
|
|
||||||
}
|
|
||||||
|
|
||||||
The "room alias" is a human-readable string which can be shared with other users
|
|
||||||
so they can join a room, rather than the room ID which is a randomly generated
|
|
||||||
string. You can have multiple room aliases per room.
|
|
||||||
|
|
||||||
.. TODO(kegan)
|
|
||||||
How to add/remove aliases from an existing room.
|
|
||||||
|
|
||||||
|
|
||||||
Sending messages
|
|
||||||
----------------
|
|
||||||
You can now send messages to this room::
|
|
||||||
|
|
||||||
curl -XPOST -d '{"msgtype":"m.text", "body":"hello"}' "https://localhost:8448/_matrix/client/r0/rooms/%21asfLdzLnOdGRkdPZWu:localhost/send/m.room.message?access_token=YOUR_ACCESS_TOKEN"
|
|
||||||
|
|
||||||
{
|
|
||||||
"event_id": "YUwRidLecu"
|
|
||||||
}
|
|
||||||
|
|
||||||
The event ID returned is a unique ID which identifies this message.
|
|
||||||
|
|
||||||
NB: There are no limitations to the types of messages which can be exchanged.
|
|
||||||
The only requirement is that ``"msgtype"`` is specified. The Matrix
|
|
||||||
specification outlines the following standard types: ``m.text``, ``m.image``,
|
|
||||||
``m.audio``, ``m.video``, ``m.location``, ``m.emote``. See the specification for
|
|
||||||
more information on these types.
|
|
||||||
|
|
||||||
Users and rooms
|
|
||||||
===============
|
|
||||||
|
|
||||||
Each room can be configured to allow or disallow certain rules. In particular,
|
|
||||||
these rules may specify if you require an **invitation** from someone already in
|
|
||||||
the room in order to **join the room**. In addition, you may also be able to
|
|
||||||
join a room **via a room alias** if one was set up.
|
|
||||||
|
|
||||||
.. NOTE::
|
|
||||||
`Try out the fiddle`__
|
|
||||||
|
|
||||||
.. __: http://jsfiddle.net/gh/get/jquery/1.8.3/matrix-org/matrix-doc/tree/master/supporting-docs/howtos/jsfiddles/room_memberships
|
|
||||||
|
|
||||||
Inviting a user to a room
|
|
||||||
-------------------------
|
|
||||||
You can directly invite a user to a room like so::
|
|
||||||
|
|
||||||
curl -XPOST -d '{"user_id":"@myfriend:localhost"}' "https://localhost:8448/_matrix/client/r0/rooms/%21asfLdzLnOdGRkdPZWu:localhost/invite?access_token=YOUR_ACCESS_TOKEN"
|
|
||||||
|
|
||||||
This informs ``@myfriend:localhost`` of the room ID
|
|
||||||
``!CvcvRuDYDzTOzfKKgh:localhost`` and allows them to join the room.
|
|
||||||
|
|
||||||
Joining a room via an invite
|
|
||||||
----------------------------
|
|
||||||
If you receive an invite, you can join the room::
|
|
||||||
|
|
||||||
curl -XPOST -d '{}' "https://localhost:8448/_matrix/client/r0/rooms/%21asfLdzLnOdGRkdPZWu:localhost/join?access_token=YOUR_ACCESS_TOKEN"
|
|
||||||
|
|
||||||
NB: Only the person invited (``@myfriend:localhost``) can change the membership
|
|
||||||
state to ``"join"``. Repeatedly joining a room does nothing.
|
|
||||||
|
|
||||||
Joining a room via an alias
|
|
||||||
---------------------------
|
|
||||||
Alternatively, if you know the room alias for this room and the room config
|
|
||||||
allows it, you can directly join a room via the alias::
|
|
||||||
|
|
||||||
curl -XPOST -d '{}' "https://localhost:8448/_matrix/client/r0/join/%21asfLdzLnOdGRkdPZWu:localhost?access_token=YOUR_ACCESS_TOKEN"
|
|
||||||
|
|
||||||
{
|
|
||||||
"room_id": "!CvcvRuDYDzTOzfKKgh:localhost"
|
|
||||||
}
|
|
||||||
|
|
||||||
You will need to use the room ID when sending messages, not the room alias.
|
|
||||||
|
|
||||||
NB: If the room is configured to be an invite-only room, you will still require
|
|
||||||
an invite in order to join the room even though you know the room alias. As a
|
|
||||||
result, it is more common to see a room alias in relation to a public room,
|
|
||||||
which do not require invitations.
|
|
||||||
|
|
||||||
Getting events
|
|
||||||
==============
|
|
||||||
An event is some interesting piece of data that a client may be interested in.
|
|
||||||
It can be a message in a room, a room invite, etc. There are many different ways
|
|
||||||
of getting events, depending on what the client already knows.
|
|
||||||
|
|
||||||
.. NOTE::
|
|
||||||
`Try out the fiddle`__
|
|
||||||
|
|
||||||
.. __: http://jsfiddle.net/gh/get/jquery/1.8.3/matrix-org/matrix-doc/tree/master/supporting-docs/howtos/jsfiddles/event_stream
|
|
||||||
|
|
||||||
Getting all state
|
|
||||||
-----------------
|
|
||||||
If the client doesn't know any information on the rooms the user is
|
|
||||||
invited/joined on, they can get all the user's state for all rooms::
|
|
||||||
|
|
||||||
curl -XGET "https://localhost:8448/_matrix/client/r0/sync?access_token=YOUR_ACCESS_TOKEN"
|
|
||||||
|
|
||||||
{
|
|
||||||
"account_data": {
|
|
||||||
"events": [
|
|
||||||
{
|
|
||||||
...
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"next_batch": "s9_3_0_1_1_1",
|
|
||||||
"presence": {
|
|
||||||
"events": [
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"currently_active": true,
|
|
||||||
"last_active_ago": 19,
|
|
||||||
"presence": "online"
|
|
||||||
},
|
|
||||||
"sender": "@example:localhost",
|
|
||||||
"type": "m.presence"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"rooms": {
|
|
||||||
"invite": {},
|
|
||||||
"join": {
|
|
||||||
"!asfLdzLnOdGRkdPZWu:localhost": {
|
|
||||||
"account_data": {
|
|
||||||
"events": []
|
|
||||||
},
|
|
||||||
"ephemeral": {
|
|
||||||
"events": []
|
|
||||||
},
|
|
||||||
"state": {
|
|
||||||
"events": []
|
|
||||||
},
|
|
||||||
"timeline": {
|
|
||||||
"events": [
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"creator": "@example:localhost"
|
|
||||||
},
|
|
||||||
"event_id": "$14606534990LhqHt:localhost",
|
|
||||||
"origin_server_ts": 1460653499699,
|
|
||||||
"sender": "@example:localhost",
|
|
||||||
"state_key": "",
|
|
||||||
"type": "m.room.create",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 239192
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"avatar_url": null,
|
|
||||||
"displayname": null,
|
|
||||||
"membership": "join"
|
|
||||||
},
|
|
||||||
"event_id": "$14606534991nsZKk:localhost",
|
|
||||||
"membership": "join",
|
|
||||||
"origin_server_ts": 1460653499727,
|
|
||||||
"sender": "@example:localhost",
|
|
||||||
"state_key": "@example:localhost",
|
|
||||||
"type": "m.room.member",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 239164
|
|
||||||
}
|
|
||||||
},
|
|
||||||
...
|
|
||||||
],
|
|
||||||
"limited": false,
|
|
||||||
"prev_batch": "s9_3_0_1_1_1"
|
|
||||||
},
|
|
||||||
"unread_notifications": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"leave": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
This returns all the room information the user is invited/joined on, as well as
|
|
||||||
all of the presences relevant for these rooms. This can be a LOT of data. You
|
|
||||||
may just want the most recent event for each room. This can be achieved by
|
|
||||||
applying a filter that asks for a limit of 1 timeline event per room::
|
|
||||||
|
|
||||||
curl --globoff -XGET 'https://localhost:8448/_matrix/client/r0/sync?filter={"room":{"timeline":{"limit":1}}}&access_token=YOUR_ACCESS_TOKEN'
|
|
||||||
|
|
||||||
{
|
|
||||||
...
|
|
||||||
"rooms": {
|
|
||||||
"invite": {},
|
|
||||||
"join": {
|
|
||||||
"!asfLdzLnOdGRkdPZWu:localhost": {
|
|
||||||
...
|
|
||||||
"timeline": {
|
|
||||||
"events": [
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"body": "hello",
|
|
||||||
"msgtype": "m.text"
|
|
||||||
},
|
|
||||||
"event_id": "$14606535757KCGXo:localhost",
|
|
||||||
"origin_server_ts": 1460653575105,
|
|
||||||
"sender": "@example:localhost",
|
|
||||||
"type": "m.room.message",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 800348
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"limited": true,
|
|
||||||
"prev_batch": "t8-8_7_0_1_1_1"
|
|
||||||
},
|
|
||||||
"unread_notifications": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"leave": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(additionally we have to ask ``curl`` not to try to interpret any ``{}``
|
|
||||||
characters in the URL, which is what the ``--globoff`` option is for)
|
|
||||||
|
|
||||||
Getting live state
|
|
||||||
------------------
|
|
||||||
In the response to this ``sync`` request the server includes a token that can
|
|
||||||
be used to obtain updates since this point under the object key ``next_batch``.
|
|
||||||
To use this token, specify its value as the ``since`` parameter to another
|
|
||||||
``/sync`` request.::
|
|
||||||
|
|
||||||
curl -XGET "https://localhost:8448/_matrix/client/r0/sync?since=s9_7_0_1_1_1&access_token=YOUR_ACCESS_TOKEN"
|
|
||||||
|
|
||||||
{
|
|
||||||
"account_data": {
|
|
||||||
"events": []
|
|
||||||
},
|
|
||||||
"next_batch": "s9_9_0_1_1_1",
|
|
||||||
"presence": {
|
|
||||||
"events": [
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"currently_active": true,
|
|
||||||
"last_active_ago": 12,
|
|
||||||
"presence": "online"
|
|
||||||
},
|
|
||||||
"sender": "@example:localhost",
|
|
||||||
"type": "m.presence"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"rooms": {
|
|
||||||
"invite": {},
|
|
||||||
"join": {},
|
|
||||||
"leave": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
By default this request will not wait in the server, always returning a value
|
|
||||||
even if nothing interesting happened. However, by applying the ``timeout``
|
|
||||||
query parameter, which gives a duration in miliseconds, we can ask the server
|
|
||||||
to wait for up to that amount of time before it returns. If no interesting
|
|
||||||
events have happened since then, the response will be relatively empty.::
|
|
||||||
|
|
||||||
curl -XGET "https://localhost:8448/_matrix/client/r0/sync?since=s9_13_0_1_1_1&access_token=YOUR_ACCESS_TOKEN"
|
|
||||||
{
|
|
||||||
"account_data": {
|
|
||||||
"events": []
|
|
||||||
},
|
|
||||||
"next_batch": "s9_13_0_1_1_1",
|
|
||||||
"presence": {
|
|
||||||
"events": []
|
|
||||||
},
|
|
||||||
"rooms": {
|
|
||||||
"invite": {},
|
|
||||||
"join": {},
|
|
||||||
"leave": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Example application
|
|
||||||
-------------------
|
|
||||||
The following example demonstrates registration and login, live event streaming,
|
|
||||||
creating and joining rooms, sending messages, getting member lists and getting
|
|
||||||
historical messages for a room. This covers most functionality of a messaging
|
|
||||||
application.
|
|
||||||
|
|
||||||
.. NOTE::
|
|
||||||
`Try out the fiddle`__
|
|
||||||
|
|
||||||
.. __: http://jsfiddle.net/gh/get/jquery/1.8.3/matrix-org/matrix-doc/tree/master/supporting-docs/howtos/jsfiddles/example_app
|
|
@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Try Matrix Now!
|
|
||||||
categories: howtos
|
|
||||||
---
|
|
||||||
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="refresh" content="0; url=../guides/client-server.html" />
|
|
||||||
</head>
|
|
||||||
</html>
|
|
@ -1,17 +0,0 @@
|
|||||||
.loggedin {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-family: monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
table
|
|
||||||
{
|
|
||||||
border-spacing:5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th,td
|
|
||||||
{
|
|
||||||
padding:5px;
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
<div>
|
|
||||||
<p>This room creation / message sending demo requires a homeserver to be running on http://localhost:8008</p>
|
|
||||||
</div>
|
|
||||||
<form class="loginForm">
|
|
||||||
<input type="text" id="userLogin" placeholder="Username"></input>
|
|
||||||
<input type="password" id="passwordLogin" placeholder="Password"></input>
|
|
||||||
<input type="button" class="login" value="Login"></input>
|
|
||||||
</form>
|
|
||||||
<div class="loggedin">
|
|
||||||
<form class="createRoomForm">
|
|
||||||
<input type="text" id="roomAlias" placeholder="Room alias (optional)"></input>
|
|
||||||
<input type="button" class="createRoom" value="Create Room"></input>
|
|
||||||
</form>
|
|
||||||
<form class="sendMessageForm">
|
|
||||||
<input type="text" id="roomId" placeholder="Room ID"></input>
|
|
||||||
<input type="text" id="messageBody" placeholder="Message body"></input>
|
|
||||||
<input type="button" class="sendMessage" value="Send Message"></input>
|
|
||||||
</form>
|
|
||||||
<table id="rooms">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th>Room ID</th>
|
|
||||||
<th>My state</th>
|
|
||||||
<th>Room Alias</th>
|
|
||||||
<th>Latest message</th>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,113 +0,0 @@
|
|||||||
var accountInfo = {};
|
|
||||||
|
|
||||||
var showLoggedIn = function(data) {
|
|
||||||
accountInfo = data;
|
|
||||||
getCurrentRoomList();
|
|
||||||
$(".loggedin").css({visibility: "visible"});
|
|
||||||
};
|
|
||||||
|
|
||||||
$('.login').live('click', function() {
|
|
||||||
var user = $("#userLogin").val();
|
|
||||||
var password = $("#passwordLogin").val();
|
|
||||||
$.ajax({
|
|
||||||
url: "http://localhost:8008/_matrix/client/api/v1/login",
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify({ user: user, password: password, type: "m.login.password" }),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data) {
|
|
||||||
showLoggedIn(data);
|
|
||||||
},
|
|
||||||
error: function(err) {
|
|
||||||
var errMsg = "To try this, you need a homeserver running!";
|
|
||||||
var errJson = $.parseJSON(err.responseText);
|
|
||||||
if (errJson) {
|
|
||||||
errMsg = JSON.stringify(errJson);
|
|
||||||
}
|
|
||||||
alert(errMsg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
var getCurrentRoomList = function() {
|
|
||||||
var url = "http://localhost:8008/_matrix/client/api/v1/initialSync?access_token=" + accountInfo.access_token + "&limit=1";
|
|
||||||
$.getJSON(url, function(data) {
|
|
||||||
var rooms = data.rooms;
|
|
||||||
for (var i=0; i<rooms.length; ++i) {
|
|
||||||
rooms[i].latest_message = rooms[i].messages.chunk[0].content.body;
|
|
||||||
addRoom(rooms[i]);
|
|
||||||
}
|
|
||||||
}).fail(function(err) {
|
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$('.createRoom').live('click', function() {
|
|
||||||
var roomAlias = $("#roomAlias").val();
|
|
||||||
var data = {};
|
|
||||||
if (roomAlias.length > 0) {
|
|
||||||
data.room_alias_name = roomAlias;
|
|
||||||
}
|
|
||||||
$.ajax({
|
|
||||||
url: "http://localhost:8008/_matrix/client/api/v1/createRoom?access_token="+accountInfo.access_token,
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify(data),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data) {
|
|
||||||
data.membership = "join"; // you are automatically joined into every room you make.
|
|
||||||
data.latest_message = "";
|
|
||||||
addRoom(data);
|
|
||||||
},
|
|
||||||
error: function(err) {
|
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
var addRoom = function(data) {
|
|
||||||
row = "<tr>" +
|
|
||||||
"<td>"+data.room_id+"</td>" +
|
|
||||||
"<td>"+data.membership+"</td>" +
|
|
||||||
"<td>"+data.room_alias+"</td>" +
|
|
||||||
"<td>"+data.latest_message+"</td>" +
|
|
||||||
"</tr>";
|
|
||||||
$("#rooms").append(row);
|
|
||||||
};
|
|
||||||
|
|
||||||
$('.sendMessage').live('click', function() {
|
|
||||||
var roomId = $("#roomId").val();
|
|
||||||
var body = $("#messageBody").val();
|
|
||||||
var msgId = $.now();
|
|
||||||
|
|
||||||
if (roomId.length === 0 || body.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var url = "http://localhost:8008/_matrix/client/api/v1/rooms/$roomid/send/m.room.message?access_token=$token";
|
|
||||||
url = url.replace("$token", accountInfo.access_token);
|
|
||||||
url = url.replace("$roomid", encodeURIComponent(roomId));
|
|
||||||
|
|
||||||
var data = {
|
|
||||||
msgtype: "m.text",
|
|
||||||
body: body
|
|
||||||
};
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify(data),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data) {
|
|
||||||
$("#messageBody").val("");
|
|
||||||
// wipe the table and reload it. Using the event stream would be the best
|
|
||||||
// solution but that is out of scope of this fiddle.
|
|
||||||
$("#rooms").find("tr:gt(0)").remove();
|
|
||||||
getCurrentRoomList();
|
|
||||||
},
|
|
||||||
error: function(err) {
|
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,17 +0,0 @@
|
|||||||
.loggedin {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-family: monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
table
|
|
||||||
{
|
|
||||||
border-spacing:5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th,td
|
|
||||||
{
|
|
||||||
padding:5px;
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
<div>
|
|
||||||
<p>This event stream demo requires a homeserver to be running on http://localhost:8008</p>
|
|
||||||
</div>
|
|
||||||
<form class="loginForm">
|
|
||||||
<input type="text" id="userLogin" placeholder="Username"></input>
|
|
||||||
<input type="password" id="passwordLogin" placeholder="Password"></input>
|
|
||||||
<input type="button" class="login" value="Login"></input>
|
|
||||||
</form>
|
|
||||||
<div class="loggedin">
|
|
||||||
<form class="sendMessageForm">
|
|
||||||
<input type="button" class="sendMessage" value="Send random message"></input>
|
|
||||||
</form>
|
|
||||||
<p id="streamErrorText"></p>
|
|
||||||
<table id="rooms">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th>Room ID</th>
|
|
||||||
<th>Latest message</th>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,145 +0,0 @@
|
|||||||
var accountInfo = {};
|
|
||||||
|
|
||||||
var eventStreamInfo = {
|
|
||||||
from: "END"
|
|
||||||
};
|
|
||||||
|
|
||||||
var roomInfo = [];
|
|
||||||
|
|
||||||
var longpollEventStream = function() {
|
|
||||||
var url = "http://localhost:8008/_matrix/client/api/v1/events?access_token=$token&from=$from";
|
|
||||||
url = url.replace("$token", accountInfo.access_token);
|
|
||||||
url = url.replace("$from", eventStreamInfo.from);
|
|
||||||
|
|
||||||
$.getJSON(url, function(data) {
|
|
||||||
eventStreamInfo.from = data.end;
|
|
||||||
|
|
||||||
var hasNewLatestMessage = false;
|
|
||||||
for (var i=0; i<data.chunk.length; ++i) {
|
|
||||||
if (data.chunk[i].type === "m.room.message") {
|
|
||||||
for (var j=0; j<roomInfo.length; ++j) {
|
|
||||||
if (roomInfo[j].room_id === data.chunk[i].room_id) {
|
|
||||||
roomInfo[j].latest_message = data.chunk[i].content.body;
|
|
||||||
hasNewLatestMessage = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasNewLatestMessage) {
|
|
||||||
setRooms(roomInfo);
|
|
||||||
}
|
|
||||||
$("#streamErrorText").text("");
|
|
||||||
longpollEventStream();
|
|
||||||
}).fail(function(err) {
|
|
||||||
$("#streamErrorText").text("Event stream error: "+JSON.stringify($.parseJSON(err.responseText)));
|
|
||||||
setTimeout(longpollEventStream, 5000);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var showLoggedIn = function(data) {
|
|
||||||
accountInfo = data;
|
|
||||||
longpollEventStream();
|
|
||||||
getCurrentRoomList();
|
|
||||||
$(".loggedin").css({visibility: "visible"});
|
|
||||||
};
|
|
||||||
|
|
||||||
$('.login').live('click', function() {
|
|
||||||
var user = $("#userLogin").val();
|
|
||||||
var password = $("#passwordLogin").val();
|
|
||||||
$.ajax({
|
|
||||||
url: "http://localhost:8008/_matrix/client/api/v1/login",
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify({ user: user, password: password, type: "m.login.password" }),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data) {
|
|
||||||
$("#rooms").find("tr:gt(0)").remove();
|
|
||||||
showLoggedIn(data);
|
|
||||||
},
|
|
||||||
error: function(err) {
|
|
||||||
var errMsg = "To try this, you need a homeserver running!";
|
|
||||||
var errJson = $.parseJSON(err.responseText);
|
|
||||||
if (errJson) {
|
|
||||||
errMsg = JSON.stringify(errJson);
|
|
||||||
}
|
|
||||||
alert(errMsg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
var getCurrentRoomList = function() {
|
|
||||||
$("#roomId").val("");
|
|
||||||
var url = "http://localhost:8008/_matrix/client/api/v1/initialSync?access_token=" + accountInfo.access_token + "&limit=1";
|
|
||||||
$.getJSON(url, function(data) {
|
|
||||||
var rooms = data.rooms;
|
|
||||||
for (var i=0; i<rooms.length; ++i) {
|
|
||||||
if ("messages" in rooms[i]) {
|
|
||||||
rooms[i].latest_message = rooms[i].messages.chunk[0].content.body;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
roomInfo = rooms;
|
|
||||||
setRooms(roomInfo);
|
|
||||||
}).fail(function(err) {
|
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$('.sendMessage').live('click', function() {
|
|
||||||
if (roomInfo.length === 0) {
|
|
||||||
alert("There is no room to send a message to!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var index = Math.floor(Math.random() * roomInfo.length);
|
|
||||||
|
|
||||||
sendMessage(roomInfo[index].room_id);
|
|
||||||
});
|
|
||||||
|
|
||||||
var sendMessage = function(roomId) {
|
|
||||||
var body = "jsfiddle message @" + $.now();
|
|
||||||
|
|
||||||
if (roomId.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var url = "http://localhost:8008/_matrix/client/api/v1/rooms/$roomid/send/m.room.message?access_token=$token";
|
|
||||||
url = url.replace("$token", accountInfo.access_token);
|
|
||||||
url = url.replace("$roomid", encodeURIComponent(roomId));
|
|
||||||
|
|
||||||
var data = {
|
|
||||||
msgtype: "m.text",
|
|
||||||
body: body
|
|
||||||
};
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify(data),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data) {
|
|
||||||
$("#messageBody").val("");
|
|
||||||
},
|
|
||||||
error: function(err) {
|
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var setRooms = function(roomList) {
|
|
||||||
// wipe existing entries
|
|
||||||
$("#rooms").find("tr:gt(0)").remove();
|
|
||||||
|
|
||||||
var rows = "";
|
|
||||||
for (var i=0; i<roomList.length; ++i) {
|
|
||||||
row = "<tr>" +
|
|
||||||
"<td>"+roomList[i].room_id+"</td>" +
|
|
||||||
"<td>"+roomList[i].latest_message+"</td>" +
|
|
||||||
"</tr>";
|
|
||||||
rows += row;
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#rooms").append(rows);
|
|
||||||
};
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
|||||||
.roomListDashboard, .roomContents, .sendMessageForm {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.roomList {
|
|
||||||
background-color: #909090;
|
|
||||||
}
|
|
||||||
|
|
||||||
.messageWrapper {
|
|
||||||
background-color: #EEEEEE;
|
|
||||||
height: 400px;
|
|
||||||
overflow: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
.membersWrapper {
|
|
||||||
background-color: #EEEEEE;
|
|
||||||
height: 200px;
|
|
||||||
width: 50%;
|
|
||||||
overflow: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
.textEntry {
|
|
||||||
width: 100%
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-family: monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
table
|
|
||||||
{
|
|
||||||
border-spacing:5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th,td
|
|
||||||
{
|
|
||||||
padding:5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.roomList tr:not(:first-child):hover {
|
|
||||||
background-color: orange;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
name: Example Matrix Client
|
|
||||||
description: Includes login, live event streaming, creating rooms, sending messages and viewing member lists.
|
|
||||||
authors:
|
|
||||||
- matrix.org
|
|
||||||
resources:
|
|
||||||
- http://matrix.org
|
|
||||||
normalize_css: no
|
|
@ -1,56 +0,0 @@
|
|||||||
<div class="signUp">
|
|
||||||
<p>Matrix example application: Requires a local homeserver running at http://localhost:8008</p>
|
|
||||||
<form class="registrationForm">
|
|
||||||
<p>No account? Register:</p>
|
|
||||||
<input type="text" id="userReg" placeholder="Username"></input>
|
|
||||||
<input type="password" id="passwordReg" placeholder="Password"></input>
|
|
||||||
<input type="button" class="register" value="Register"></input>
|
|
||||||
</form>
|
|
||||||
<form class="loginForm">
|
|
||||||
<p>Got an account? Login:</p>
|
|
||||||
<input type="text" id="userLogin" placeholder="Username"></input>
|
|
||||||
<input type="password" id="passwordLogin" placeholder="Password"></input>
|
|
||||||
<input type="button" class="login" value="Login"></input>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="roomListDashboard">
|
|
||||||
<form class="createRoomForm">
|
|
||||||
<input type="text" id="roomAlias" placeholder="Room alias"></input>
|
|
||||||
<input type="button" class="createRoom" value="Create Room"></input>
|
|
||||||
</form>
|
|
||||||
<table id="rooms" class="roomList">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th>Room</th>
|
|
||||||
<th>My state</th>
|
|
||||||
<th>Latest message</th>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="roomContents">
|
|
||||||
<p id="roomName">Select a room</p>
|
|
||||||
<div class="messageWrapper">
|
|
||||||
<table id="messages">
|
|
||||||
<tbody>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<form class="sendMessageForm">
|
|
||||||
<input type="text" class="textEntry" id="body" placeholder="Enter text here..." onkeydown="javascript:if (event.keyCode == 13) document.getElementById('sendMsg').focus()"></input>
|
|
||||||
<input type="button" class="sendMessage" id="sendMsg" value="Send"></input>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<p>Member list:</p>
|
|
||||||
<div class="membersWrapper">
|
|
||||||
<table id="members">
|
|
||||||
<tbody>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,327 +0,0 @@
|
|||||||
var accountInfo = {};
|
|
||||||
|
|
||||||
var eventStreamInfo = {
|
|
||||||
from: "END"
|
|
||||||
};
|
|
||||||
|
|
||||||
var roomInfo = [];
|
|
||||||
var memberInfo = [];
|
|
||||||
var viewingRoomId;
|
|
||||||
|
|
||||||
// ************** Event Streaming **************
|
|
||||||
var longpollEventStream = function() {
|
|
||||||
var url = "http://localhost:8008/_matrix/client/api/v1/events?access_token=$token&from=$from";
|
|
||||||
url = url.replace("$token", accountInfo.access_token);
|
|
||||||
url = url.replace("$from", eventStreamInfo.from);
|
|
||||||
|
|
||||||
$.getJSON(url, function(data) {
|
|
||||||
eventStreamInfo.from = data.end;
|
|
||||||
|
|
||||||
var hasNewLatestMessage = false;
|
|
||||||
var updatedMemberList = false;
|
|
||||||
var i=0;
|
|
||||||
var j=0;
|
|
||||||
for (i=0; i<data.chunk.length; ++i) {
|
|
||||||
if (data.chunk[i].type === "m.room.message") {
|
|
||||||
console.log("Got new message: " + JSON.stringify(data.chunk[i]));
|
|
||||||
if (viewingRoomId === data.chunk[i].room_id) {
|
|
||||||
addMessage(data.chunk[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j=0; j<roomInfo.length; ++j) {
|
|
||||||
if (roomInfo[j].room_id === data.chunk[i].room_id) {
|
|
||||||
roomInfo[j].latest_message = data.chunk[i].content.body;
|
|
||||||
hasNewLatestMessage = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (data.chunk[i].type === "m.room.member") {
|
|
||||||
if (viewingRoomId === data.chunk[i].room_id) {
|
|
||||||
console.log("Got new member: " + JSON.stringify(data.chunk[i]));
|
|
||||||
addMessage(data.chunk[i]);
|
|
||||||
for (j=0; j<memberInfo.length; ++j) {
|
|
||||||
if (memberInfo[j].state_key === data.chunk[i].state_key) {
|
|
||||||
memberInfo[j] = data.chunk[i];
|
|
||||||
updatedMemberList = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!updatedMemberList) {
|
|
||||||
memberInfo.push(data.chunk[i]);
|
|
||||||
updatedMemberList = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data.chunk[i].state_key === accountInfo.user_id) {
|
|
||||||
getCurrentRoomList(); // update our join/invite list
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log("Discarding: " + JSON.stringify(data.chunk[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasNewLatestMessage) {
|
|
||||||
setRooms(roomInfo);
|
|
||||||
}
|
|
||||||
if (updatedMemberList) {
|
|
||||||
$("#members").empty();
|
|
||||||
for (i=0; i<memberInfo.length; ++i) {
|
|
||||||
addMember(memberInfo[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
longpollEventStream();
|
|
||||||
}).fail(function(err) {
|
|
||||||
setTimeout(longpollEventStream, 5000);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// ************** Registration and Login **************
|
|
||||||
var onLoggedIn = function(data) {
|
|
||||||
accountInfo = data;
|
|
||||||
longpollEventStream();
|
|
||||||
getCurrentRoomList();
|
|
||||||
$(".roomListDashboard").css({visibility: "visible"});
|
|
||||||
$(".roomContents").css({visibility: "visible"});
|
|
||||||
$(".signUp").css({display: "none"});
|
|
||||||
};
|
|
||||||
|
|
||||||
$('.login').live('click', function() {
|
|
||||||
var user = $("#userLogin").val();
|
|
||||||
var password = $("#passwordLogin").val();
|
|
||||||
$.ajax({
|
|
||||||
url: "http://localhost:8008/_matrix/client/api/v1/login",
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify({ user: user, password: password, type: "m.login.password" }),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data) {
|
|
||||||
onLoggedIn(data);
|
|
||||||
},
|
|
||||||
error: function(err) {
|
|
||||||
alert("Unable to login: is the homeserver running?");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.register').live('click', function() {
|
|
||||||
var user = $("#userReg").val();
|
|
||||||
var password = $("#passwordReg").val();
|
|
||||||
$.ajax({
|
|
||||||
url: "http://localhost:8008/_matrix/client/api/v1/register",
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify({ user: user, password: password, type: "m.login.password" }),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data) {
|
|
||||||
onLoggedIn(data);
|
|
||||||
},
|
|
||||||
error: function(err) {
|
|
||||||
var msg = "Is the homeserver running?";
|
|
||||||
var errJson = $.parseJSON(err.responseText);
|
|
||||||
if (errJson !== null) {
|
|
||||||
msg = errJson.error;
|
|
||||||
}
|
|
||||||
alert("Unable to register: "+msg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// ************** Creating a room ******************
|
|
||||||
$('.createRoom').live('click', function() {
|
|
||||||
var roomAlias = $("#roomAlias").val();
|
|
||||||
var data = {};
|
|
||||||
if (roomAlias.length > 0) {
|
|
||||||
data.room_alias_name = roomAlias;
|
|
||||||
}
|
|
||||||
$.ajax({
|
|
||||||
url: "http://localhost:8008/_matrix/client/api/v1/createRoom?access_token="+accountInfo.access_token,
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify(data),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(response) {
|
|
||||||
$("#roomAlias").val("");
|
|
||||||
response.membership = "join"; // you are automatically joined into every room you make.
|
|
||||||
response.latest_message = "";
|
|
||||||
|
|
||||||
roomInfo.push(response);
|
|
||||||
setRooms(roomInfo);
|
|
||||||
},
|
|
||||||
error: function(err) {
|
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// ************** Getting current state **************
|
|
||||||
var getCurrentRoomList = function() {
|
|
||||||
var url = "http://localhost:8008/_matrix/client/api/v1/initialSync?access_token=" + accountInfo.access_token + "&limit=1";
|
|
||||||
$.getJSON(url, function(data) {
|
|
||||||
var rooms = data.rooms;
|
|
||||||
for (var i=0; i<rooms.length; ++i) {
|
|
||||||
if ("messages" in rooms[i]) {
|
|
||||||
rooms[i].latest_message = rooms[i].messages.chunk[0].content.body;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
roomInfo = rooms;
|
|
||||||
setRooms(roomInfo);
|
|
||||||
}).fail(function(err) {
|
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var loadRoomContent = function(roomId) {
|
|
||||||
console.log("loadRoomContent " + roomId);
|
|
||||||
viewingRoomId = roomId;
|
|
||||||
$("#roomName").text("Room: "+roomId);
|
|
||||||
$(".sendMessageForm").css({visibility: "visible"});
|
|
||||||
getMessages(roomId);
|
|
||||||
getMemberList(roomId);
|
|
||||||
};
|
|
||||||
|
|
||||||
var getMessages = function(roomId) {
|
|
||||||
$("#messages").empty();
|
|
||||||
var url = "http://localhost:8008/_matrix/client/api/v1/rooms/" +
|
|
||||||
encodeURIComponent(roomId) + "/messages?access_token=" + accountInfo.access_token + "&from=END&dir=b&limit=10";
|
|
||||||
$.getJSON(url, function(data) {
|
|
||||||
for (var i=data.chunk.length-1; i>=0; --i) {
|
|
||||||
addMessage(data.chunk[i]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var getMemberList = function(roomId) {
|
|
||||||
$("#members").empty();
|
|
||||||
memberInfo = [];
|
|
||||||
var url = "http://localhost:8008/_matrix/client/api/v1/rooms/" +
|
|
||||||
encodeURIComponent(roomId) + "/members?access_token=" + accountInfo.access_token;
|
|
||||||
$.getJSON(url, function(data) {
|
|
||||||
for (var i=0; i<data.chunk.length; ++i) {
|
|
||||||
memberInfo.push(data.chunk[i]);
|
|
||||||
addMember(data.chunk[i]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// ************** Sending messages **************
|
|
||||||
$('.sendMessage').live('click', function() {
|
|
||||||
if (viewingRoomId === undefined) {
|
|
||||||
alert("There is no room to send a message to!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var body = $("#body").val();
|
|
||||||
sendMessage(viewingRoomId, body);
|
|
||||||
});
|
|
||||||
|
|
||||||
var sendMessage = function(roomId, body) {
|
|
||||||
var msgId = $.now();
|
|
||||||
|
|
||||||
var url = "http://localhost:8008/_matrix/client/api/v1/rooms/$roomid/send/m.room.message?access_token=$token";
|
|
||||||
url = url.replace("$token", accountInfo.access_token);
|
|
||||||
url = url.replace("$roomid", encodeURIComponent(roomId));
|
|
||||||
|
|
||||||
var data = {
|
|
||||||
msgtype: "m.text",
|
|
||||||
body: body
|
|
||||||
};
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify(data),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data) {
|
|
||||||
$("#body").val("");
|
|
||||||
},
|
|
||||||
error: function(err) {
|
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// ************** Navigation and DOM manipulation **************
|
|
||||||
var setRooms = function(roomList) {
|
|
||||||
// wipe existing entries
|
|
||||||
$("#rooms").find("tr:gt(0)").remove();
|
|
||||||
|
|
||||||
var rows = "";
|
|
||||||
for (var i=0; i<roomList.length; ++i) {
|
|
||||||
row = "<tr>" +
|
|
||||||
"<td>"+roomList[i].room_id+"</td>" +
|
|
||||||
"<td>"+roomList[i].membership+"</td>" +
|
|
||||||
"<td>"+roomList[i].latest_message+"</td>" +
|
|
||||||
"</tr>";
|
|
||||||
rows += row;
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#rooms").append(rows);
|
|
||||||
|
|
||||||
$('#rooms').find("tr").click(function(){
|
|
||||||
var roomId = $(this).find('td:eq(0)').text();
|
|
||||||
var membership = $(this).find('td:eq(1)').text();
|
|
||||||
if (membership !== "join") {
|
|
||||||
console.log("Joining room " + roomId);
|
|
||||||
var url = "http://localhost:8008/_matrix/client/api/v1/rooms/$roomid/join?access_token=$token";
|
|
||||||
url = url.replace("$token", accountInfo.access_token);
|
|
||||||
url = url.replace("$roomid", encodeURIComponent(roomId));
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify({membership: "join"}),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data) {
|
|
||||||
loadRoomContent(roomId);
|
|
||||||
getCurrentRoomList();
|
|
||||||
},
|
|
||||||
error: function(err) {
|
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
loadRoomContent(roomId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var addMessage = function(data) {
|
|
||||||
|
|
||||||
var msg = data.content.body;
|
|
||||||
if (data.type === "m.room.member") {
|
|
||||||
if (data.content.membership === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (data.content.membership === "invite") {
|
|
||||||
msg = "<em>invited " + data.state_key + " to the room</em>";
|
|
||||||
}
|
|
||||||
else if (data.content.membership === "join") {
|
|
||||||
msg = "<em>joined the room</em>";
|
|
||||||
}
|
|
||||||
else if (data.content.membership === "leave") {
|
|
||||||
msg = "<em>left the room</em>";
|
|
||||||
}
|
|
||||||
else if (data.content.membership === "ban") {
|
|
||||||
msg = "<em>was banned from the room</em>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (msg === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var row = "<tr>" +
|
|
||||||
"<td>"+data.user_id+"</td>" +
|
|
||||||
"<td>"+msg+"</td>" +
|
|
||||||
"</tr>";
|
|
||||||
$("#messages").append(row);
|
|
||||||
};
|
|
||||||
|
|
||||||
var addMember = function(data) {
|
|
||||||
var row = "<tr>" +
|
|
||||||
"<td>"+data.state_key+"</td>" +
|
|
||||||
"<td>"+data.content.membership+"</td>" +
|
|
||||||
"</tr>";
|
|
||||||
$("#members").append(row);
|
|
||||||
};
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
.loggedin {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-family: monospace;
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
<div>
|
|
||||||
<p>This registration/login demo requires a homeserver to be running on http://localhost:8008</p>
|
|
||||||
</div>
|
|
||||||
<form class="registrationForm">
|
|
||||||
<input type="text" id="user" placeholder="Username"></input>
|
|
||||||
<input type="password" id="password" placeholder="Password"></input>
|
|
||||||
<input type="button" class="register" value="Register"></input>
|
|
||||||
</form>
|
|
||||||
<form class="loginForm">
|
|
||||||
<input type="text" id="userLogin" placeholder="Username"></input>
|
|
||||||
<input type="password" id="passwordLogin" placeholder="Password"></input>
|
|
||||||
<input type="button" class="login" value="Login"></input>
|
|
||||||
</form>
|
|
||||||
<div class="loggedin">
|
|
||||||
<p id="welcomeText"></p>
|
|
||||||
<input type="button" class="testToken" value="Test token"></input>
|
|
||||||
<input type="button" class="logout" value="Logout"></input>
|
|
||||||
<p id="imSyncText"></p>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
|||||||
var accountInfo = {};
|
|
||||||
|
|
||||||
var showLoggedIn = function(data) {
|
|
||||||
accountInfo = data;
|
|
||||||
$(".loggedin").css({visibility: "visible"});
|
|
||||||
$("#welcomeText").text("Welcome " + accountInfo.user_id+". Your access token is: " +
|
|
||||||
accountInfo.access_token);
|
|
||||||
};
|
|
||||||
|
|
||||||
$('.register').live('click', function() {
|
|
||||||
var user = $("#user").val();
|
|
||||||
var password = $("#password").val();
|
|
||||||
$.ajax({
|
|
||||||
url: "http://localhost:8008/_matrix/client/api/v1/register",
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify({ user: user, password: password, type: "m.login.password" }),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data) {
|
|
||||||
showLoggedIn(data);
|
|
||||||
},
|
|
||||||
error: function(err) {
|
|
||||||
var errMsg = "To try this, you need a homeserver running!";
|
|
||||||
var errJson = $.parseJSON(err.responseText);
|
|
||||||
if (errJson) {
|
|
||||||
errMsg = JSON.stringify(errJson);
|
|
||||||
}
|
|
||||||
alert(errMsg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
var login = function(user, password) {
|
|
||||||
$.ajax({
|
|
||||||
url: "http://localhost:8008/_matrix/client/api/v1/login",
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify({ user: user, password: password, type: "m.login.password" }),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data) {
|
|
||||||
showLoggedIn(data);
|
|
||||||
},
|
|
||||||
error: function(err) {
|
|
||||||
var errMsg = "To try this, you need a homeserver running!";
|
|
||||||
var errJson = $.parseJSON(err.responseText);
|
|
||||||
if (errJson) {
|
|
||||||
errMsg = JSON.stringify(errJson);
|
|
||||||
}
|
|
||||||
alert(errMsg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$('.login').live('click', function() {
|
|
||||||
var user = $("#userLogin").val();
|
|
||||||
var password = $("#passwordLogin").val();
|
|
||||||
$.getJSON("http://localhost:8008/_matrix/client/api/v1/login", function(data) {
|
|
||||||
if (data.flows[0].type !== "m.login.password") {
|
|
||||||
alert("I don't know how to login with this type: " + data.type);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
login(user, password);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.logout').live('click', function() {
|
|
||||||
accountInfo = {};
|
|
||||||
$("#imSyncText").text("");
|
|
||||||
$(".loggedin").css({visibility: "hidden"});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.testToken').live('click', function() {
|
|
||||||
var url = "http://localhost:8008/_matrix/client/api/v1/initialSync?access_token=" + accountInfo.access_token + "&limit=1";
|
|
||||||
$.getJSON(url, function(data) {
|
|
||||||
$("#imSyncText").text(JSON.stringify(data, undefined, 2));
|
|
||||||
}).fail(function(err) {
|
|
||||||
$("#imSyncText").text(JSON.stringify($.parseJSON(err.responseText)));
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,17 +0,0 @@
|
|||||||
.loggedin {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-family: monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
table
|
|
||||||
{
|
|
||||||
border-spacing:5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th,td
|
|
||||||
{
|
|
||||||
padding:5px;
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
<div>
|
|
||||||
<p>This room membership demo requires a homeserver to be running on http://localhost:8008</p>
|
|
||||||
</div>
|
|
||||||
<form class="loginForm">
|
|
||||||
<input type="text" id="userLogin" placeholder="Username"></input>
|
|
||||||
<input type="password" id="passwordLogin" placeholder="Password"></input>
|
|
||||||
<input type="button" class="login" value="Login"></input>
|
|
||||||
</form>
|
|
||||||
<div class="loggedin">
|
|
||||||
<form class="createRoomForm">
|
|
||||||
<input type="button" class="createRoom" value="Create Room"></input>
|
|
||||||
</form>
|
|
||||||
<form class="changeMembershipForm">
|
|
||||||
<input type="text" id="roomId" placeholder="Room ID"></input>
|
|
||||||
<input type="text" id="targetUser" placeholder="Target User ID"></input>
|
|
||||||
<select id="membership">
|
|
||||||
<option value="invite">invite</option>
|
|
||||||
<option value="join">join</option>
|
|
||||||
<option value="leave">leave</option>
|
|
||||||
</select>
|
|
||||||
<input type="button" class="changeMembership" value="Change Membership"></input>
|
|
||||||
</form>
|
|
||||||
<form class="joinAliasForm">
|
|
||||||
<input type="text" id="roomAlias" placeholder="Room Alias (#name:domain)"></input>
|
|
||||||
<input type="button" class="joinAlias" value="Join via Alias"></input>
|
|
||||||
</form>
|
|
||||||
<table id="rooms">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th>Room ID</th>
|
|
||||||
<th>My state</th>
|
|
||||||
<th>Room Alias</th>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,141 +0,0 @@
|
|||||||
var accountInfo = {};
|
|
||||||
|
|
||||||
var showLoggedIn = function(data) {
|
|
||||||
accountInfo = data;
|
|
||||||
getCurrentRoomList();
|
|
||||||
$(".loggedin").css({visibility: "visible"});
|
|
||||||
$("#membership").change(function() {
|
|
||||||
if ($("#membership").val() === "invite") {
|
|
||||||
$("#targetUser").css({visibility: "visible"});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$("#targetUser").css({visibility: "hidden"});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$('.login').live('click', function() {
|
|
||||||
var user = $("#userLogin").val();
|
|
||||||
var password = $("#passwordLogin").val();
|
|
||||||
$.ajax({
|
|
||||||
url: "http://localhost:8008/_matrix/client/api/v1/login",
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify({ user: user, password: password, type: "m.login.password" }),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data) {
|
|
||||||
$("#rooms").find("tr:gt(0)").remove();
|
|
||||||
showLoggedIn(data);
|
|
||||||
},
|
|
||||||
error: function(err) {
|
|
||||||
var errMsg = "To try this, you need a homeserver running!";
|
|
||||||
var errJson = $.parseJSON(err.responseText);
|
|
||||||
if (errJson) {
|
|
||||||
errMsg = JSON.stringify(errJson);
|
|
||||||
}
|
|
||||||
alert(errMsg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
var getCurrentRoomList = function() {
|
|
||||||
$("#roomId").val("");
|
|
||||||
// wipe the table and reload it. Using the event stream would be the best
|
|
||||||
// solution but that is out of scope of this fiddle.
|
|
||||||
$("#rooms").find("tr:gt(0)").remove();
|
|
||||||
|
|
||||||
var url = "http://localhost:8008/_matrix/client/api/v1/initialSync?access_token=" + accountInfo.access_token + "&limit=1";
|
|
||||||
$.getJSON(url, function(data) {
|
|
||||||
var rooms = data.rooms;
|
|
||||||
for (var i=0; i<rooms.length; ++i) {
|
|
||||||
addRoom(rooms[i]);
|
|
||||||
}
|
|
||||||
}).fail(function(err) {
|
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$('.createRoom').live('click', function() {
|
|
||||||
var data = {};
|
|
||||||
$.ajax({
|
|
||||||
url: "http://localhost:8008/_matrix/client/api/v1/createRoom?access_token="+accountInfo.access_token,
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify(data),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data) {
|
|
||||||
data.membership = "join"; // you are automatically joined into every room you make.
|
|
||||||
data.latest_message = "";
|
|
||||||
addRoom(data);
|
|
||||||
},
|
|
||||||
error: function(err) {
|
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
var addRoom = function(data) {
|
|
||||||
row = "<tr>" +
|
|
||||||
"<td>"+data.room_id+"</td>" +
|
|
||||||
"<td>"+data.membership+"</td>" +
|
|
||||||
"<td>"+data.room_alias+"</td>" +
|
|
||||||
"</tr>";
|
|
||||||
$("#rooms").append(row);
|
|
||||||
};
|
|
||||||
|
|
||||||
$('.changeMembership').live('click', function() {
|
|
||||||
var roomId = $("#roomId").val();
|
|
||||||
var member = $("#targetUser").val();
|
|
||||||
var membership = $("#membership").val();
|
|
||||||
|
|
||||||
if (roomId.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var url = "http://localhost:8008/_matrix/client/api/v1/rooms/$roomid/$membership?access_token=$token";
|
|
||||||
url = url.replace("$token", accountInfo.access_token);
|
|
||||||
url = url.replace("$roomid", encodeURIComponent(roomId));
|
|
||||||
url = url.replace("$membership", membership);
|
|
||||||
|
|
||||||
var data = {};
|
|
||||||
|
|
||||||
if (membership === "invite") {
|
|
||||||
data = {
|
|
||||||
user_id: member
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify(data),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data) {
|
|
||||||
getCurrentRoomList();
|
|
||||||
},
|
|
||||||
error: function(err) {
|
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.joinAlias').live('click', function() {
|
|
||||||
var roomAlias = $("#roomAlias").val();
|
|
||||||
var url = "http://localhost:8008/_matrix/client/api/v1/join/$roomalias?access_token=$token";
|
|
||||||
url = url.replace("$token", accountInfo.access_token);
|
|
||||||
url = url.replace("$roomalias", encodeURIComponent(roomAlias));
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify({}),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data) {
|
|
||||||
getCurrentRoomList();
|
|
||||||
},
|
|
||||||
error: function(err) {
|
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,20 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Riot
|
|
||||||
categories: projects client
|
|
||||||
thumbnail: /docs/projects/images/riot-web-small.png
|
|
||||||
author: Riot.im
|
|
||||||
description: Riot is a glossy web client with an emphasis on performance and usability
|
|
||||||
maturity: Released
|
|
||||||
---
|
|
||||||
|
|
||||||
![screenshot](/docs/projects/images/riot-web-large.png "{{ page.title }}")
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
[Riot](https://riot.im) is a glossy Matrix client built on top of [matrix-react-sdk](http://matrix.org/docs/projects/sdk/matrix.org-react-sdk.html) with an emphasis on performance and usability.
|
|
||||||
|
|
||||||
You can use it at [https://riot.im/app](https://riot.im/app), read more at [https://riot.im](https://riot.im) and get the source from [github](https://github.com/vector-im/vector-web)!
|
|
||||||
|
|
||||||
There is also a desktop version, which is available at [riot.im](https://riot.im/desktop.html). Taw has created RPM package builds for Fedora, CentOS, and Red Hat Enterprise Linux which are available via [GitHub](https://github.com/taw00/riot-rpm/) and [FedoraCorp](https://copr.fedorainfracloud.org/coprs/taw/Riot/).
|
|
||||||
|
|
||||||
Josué Tille has contributed a [Yunohost app](https://github.com/Josue-T/riot_ynh).
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Try Matrix Now!
|
|
||||||
---
|
|
||||||
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="refresh" content="0; url=./riot.html" />
|
|
||||||
</head>
|
|
||||||
</html>
|
|
@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: NEB (N. E. Bot)
|
|
||||||
categories: projects other
|
|
||||||
description: Our dear Matrix Bot
|
|
||||||
author: Kegsay
|
|
||||||
maturity: Late beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Kegsay's general-purpose Python Matrix Bot framework ([github](https://github.com/Kegsay/Matrix-NEB))
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Matrix.org Android SDK
|
|
||||||
categories: projects sdk
|
|
||||||
author: Matrix.org team
|
|
||||||
maturity: Late beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Matrix.org's Android SDK ([github](https://github.com/matrix-org/matrix-android-sdk))
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Matrix.org iOS SDK
|
|
||||||
categories: projects sdk
|
|
||||||
author: Matrix.org team
|
|
||||||
maturity: Late beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Matrix.org's iOS SDK ([github](https://github.com/matrix-org/matrix-ios-sdk))
|
|
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Matrix.org AngularJS SDK
|
|
||||||
categories: projects sdk
|
|
||||||
author: Matrix.org team
|
|
||||||
maturity: DEPRECATED
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
AngularJS services from Matrix.org for building communication apps in Angular based on Matrix: [https://github.com/matrix-org/matrix-angular-sdk](https://github.com/matrix-org/matrix-angular-sdk)
|
|
||||||
|
|
||||||
These are no longer being actively maintained.
|
|
@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Perl Matrix-IRC Bridge
|
|
||||||
categories: projects other
|
|
||||||
description: The first Matrix/IRC bridge
|
|
||||||
author: Tom Molesworth / Paul Evans
|
|
||||||
maturity: Beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
The first Matrix/IRC bridge, originally written by Tom Molesworth using Paul Evans' Net::Async::Matrix Perl client SDK and then later maintained by Paul Evans. Nowadays superceded by the [matrix-appservice-irc Node IRC bridge AS](../as/irc-bridge.html).
|
|
@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: ivar2 Matrix/IRC Bot
|
|
||||||
categories: projects other
|
|
||||||
description: IRC bot with native Matrix support
|
|
||||||
author: haste / Tor
|
|
||||||
maturity: Beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
ivar2 is a very comprehensive IRC bot written in Lua which has native support for Matrix! [https://github.com/torhve/ivar2](https://github.com/torhve/ivar2)
|
|
@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Try Matrix Now!
|
|
||||||
categories: projects
|
|
||||||
---
|
|
||||||
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="refresh" content="0; url=./try-matrix-now.html" />
|
|
||||||
</head>
|
|
||||||
</html>
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Matrix.org Python SDK
|
|
||||||
categories: projects sdk
|
|
||||||
author: Matrix.org team
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Matrix.org's Python SDK ([github](https://github.com/matrix-org/matrix-python-sdk))
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Matrix.org AS Node SDK
|
|
||||||
categories: projects as
|
|
||||||
author: Matrix.org team
|
|
||||||
maturity: Early beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
A framework from Matrix.org for building Application Services in Node.js/Express: [https://github.com/matrix-org/matrix-appservice-node](https://github.com/matrix-org/matrix-appservice-node)
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Matrix.org JS SDK
|
|
||||||
categories: projects sdk
|
|
||||||
author: Matrix.org team
|
|
||||||
maturity: Early beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Matrix.org's JS SDK ([github](https://github.com/matrix-org/matrix-js-sdk))
|
|
@ -1,14 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Matrix.org IRC Bridge
|
|
||||||
categories: projects as
|
|
||||||
description:
|
|
||||||
author: Matrix.org team
|
|
||||||
maturity: Early beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
An application service gateway from Matrix.org for bridging between IRC networks and Matrix, written using [matrix-appservice-node](http://matrix.org/blog/project/matrix-appservice-node/). You can get the [code on github](https://github.com/matrix-org/matrix-appservice-irc).
|
|
||||||
|
|
||||||
Supports dynamically bridging IRC channels on demand; synchronised user-lists, and other goodness.
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: redpill IRC bridge
|
|
||||||
categories: projects as
|
|
||||||
author: Tjgillies
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Kodo's IRC<->matrix GW written in Ruby ([github](https://github.com/tjgillies/redpill))
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: gomatrix IRC bridge
|
|
||||||
categories: projects as
|
|
||||||
author: Tor
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Tor's IRC<->Matrix bridge written in the Go language ([github](https://github.com/torhve/gomirc))
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Matrix.org MatrixKit (iOS)
|
|
||||||
categories: projects sdk
|
|
||||||
author: Matrix.org team
|
|
||||||
maturity: Late beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Matrix.org's reusable UI interfaces for iOS ([github](https://github.com/matrix-org/matrix-ios-kit))
|
|
@ -1,16 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Riot iOS
|
|
||||||
categories: projects client
|
|
||||||
thumbnail: /docs/projects/images/vector-iOS-small.png
|
|
||||||
description: Riot is a glossy client with an emphasis on performance and usability
|
|
||||||
author: Riot.im
|
|
||||||
maturity: Released
|
|
||||||
---
|
|
||||||
|
|
||||||
![screenshot](/docs/projects/images/vector-iOS-large.png "{{ page.title }}")
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
The iOS version of the [Riot](https://matrix.org/docs/projects/client/riot.html) web client. Riot is a glossy client with focus on performance and usability.
|
|
||||||
|
|
||||||
The code is available from [github](https://github.com/vector-im/vector-ios), and the app is available from the Apple [app store](https://itunes.apple.com/gb/app/vector.im/id1083446067?mt=8).
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Try Matrix Now!
|
|
||||||
---
|
|
||||||
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="refresh" content="0; url=./riot-ios.html" />
|
|
||||||
</head>
|
|
||||||
</html>
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: newlisp-matrix-client
|
|
||||||
categories: projects sdk
|
|
||||||
author: Ingo Hohmann
|
|
||||||
maturity: Early beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Client SDK for newlisp available at [https://github.com/IngoHohmann/newlisp-matrix-client](https://github.com/IngoHohmann/newlisp-matrix-client)
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: matrix-erlang-sdk
|
|
||||||
categories: projects sdk
|
|
||||||
author: Andreas Hallberg
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Andreas Hallberg's client SDK for Erlang [https://github.com/anhallbe/matrix-erlang-sdk](https://github.com/anhallbe/matrix-erlang-sdk)
|
|
@ -1,18 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Riot Android
|
|
||||||
categories: projects client
|
|
||||||
thumbnail: /docs/projects/images/vector-android-small.png
|
|
||||||
description: Riot is a glossy client with an emphasis on performance and usability
|
|
||||||
author: Riot.im
|
|
||||||
maturity: Released
|
|
||||||
---
|
|
||||||
|
|
||||||
![screenshot](/docs/projects/images/vector-android-large.png "{{ page.title }}")
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
The Android version of the [Riot](https://matrix.org/docs/projects/client/riot.html) web client. Riot is a glossy client with focus on performance and usability.
|
|
||||||
|
|
||||||
The code is available from [github](https://github.com/vector-im/vector-android), and the app is available from the [Google Play store](https://play.google.com/store/apps/details?id=im.vector.alpha) and [F-Droid](https://f-droid.org/repository/browse/?fdfilter=vector&fdid=im.vector.alpha).
|
|
||||||
|
|
||||||
If you want to help test the app, you can download development versions from [Jenkins](https://matrix.org/jenkins/job/VectorAndroidDevelop/).
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Try Matrix Now!
|
|
||||||
---
|
|
||||||
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="refresh" content="0; url=./riot-android.html" />
|
|
||||||
</head>
|
|
||||||
</html>
|
|
@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Matrix.org React SDK
|
|
||||||
categories: projects sdk
|
|
||||||
author: Matrix.org team
|
|
||||||
maturity: Early beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
[matrix-react-sdk](https://github.com/matrix-org/matrix-react-sdk) is our next-generation Web SDK for Matrix, providing both a large hierarchy of reusable UI components and a simple neutral reference application. It's suitable both for building standalone applications and embedding Matrix clients into existing web apps, irrespective of the host app's framework.
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Tensor
|
|
||||||
categories: projects client
|
|
||||||
thumbnail: https://matrix.org/blog/wp-content/uploads/2015/11/tensor1-400x284.png
|
|
||||||
description: QML-based Matrix client
|
|
||||||
author: David A Roberts
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
![screenshot](https://matrix.org/blog/wp-content/uploads/2015/11/tensor1.png "{{ page.title }}")
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Tensor is a cross-platform native Matrix client, based on QtQuick/QML and libqmatrixclient (formerly matrix-js-sdk). It has been tested on Desktop GNU/Linux, OS X, Windows, Android, SailfishOS and Ubuntu Touch. Get it from [github](https://github.com/davidar/tensor).
|
|
@ -1,14 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Quaternion
|
|
||||||
categories: projects client
|
|
||||||
thumbnail: https://raw.githubusercontent.com/QMatrixClient/Quaternion/master/quaternion.png
|
|
||||||
author: Felix Rohrbach, Kitsune Ral
|
|
||||||
description: Quaternion is an IM client for the Matrix protocol
|
|
||||||
maturity: Late alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
![screenshot](https://raw.githubusercontent.com/QMatrixClient/Quaternion/master/quaternion.png "{{ page.title }}")
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Quaternion is a Qt/QML-based IM client for the Matrix protocol in development. ([github](https://github.com/QMatrixClient/Quaternion))
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: xmpptrix
|
|
||||||
categories: projects as
|
|
||||||
author: SkaveRat
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
XMPP<->Matrix gateway application service written in Node JS: [https://github.com/SkaveRat/xmpptrix](https://github.com/SkaveRat/xmpptrix).
|
|
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: matrix-appservice-bridge
|
|
||||||
categories: projects as
|
|
||||||
author: Kegsay
|
|
||||||
maturity: Early beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
This library sits on top of the [core application service library](https://github.com/matrix-org/matrix-appservice-node) and provides an API for setting up bridges quickly.
|
|
||||||
|
|
||||||
Get it from [github](https://github.com/matrix-org/matrix-appservice-bridge) and have a look at the [HOW-TO](https://github.com/matrix-org/matrix-appservice-bridge/blob/master/HOWTO.md) for a step-by-step tutorial on setting up a new bridge!
|
|
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: matrix-appservice-respoke
|
|
||||||
categories: projects as
|
|
||||||
author: Matrix.org team
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
An incredibly hacky Matrix --> Asterisk bridge via chan_respoke.
|
|
||||||
|
|
||||||
Get it from [github](https://github.com/matrix-org/matrix-appservice-respoke)!
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Vertobridge
|
|
||||||
categories: projects as
|
|
||||||
author: Matthew / Kegan
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
A Matrix <--> Verto bridge, designed for conferencing via Freeswitch. [https://github.com/matrix-org/matrix-appservice-verto](https://github.com/matrix-org/matrix-appservice-verto)
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: bullettime
|
|
||||||
categories: projects server
|
|
||||||
author: Patrik Oldsberg
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
An experimental golang Matrix homeserver ([github](https://github.com/matrix-org/bullettime))
|
|
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: matrix-appservice-slack
|
|
||||||
categories: projects as
|
|
||||||
author: illicitonion
|
|
||||||
maturity: Early beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
This project bridges [Slack](https://slack.com) to Matrix, all in a 100 lines of code! It's currently quite barebones, but at the same time it shows how quickly a bridge can be written.
|
|
||||||
|
|
||||||
Get it from [github](https://github.com/matrix-org/matrix-appservice-slack)!
|
|
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Matrix-XMPP Bridge
|
|
||||||
categories: projects as
|
|
||||||
author: jfrederickson
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
This project creates a bridge between a Matrix room and an XMPP MUC: [https://github.com/jfrederickson/matrix-xmpp-bridge](https://github.com/jfrederickson/matrix-xmpp-bridge)
|
|
||||||
|
|
||||||
Update: there is also a forked and refactored version at [pztrn's GitHub space](https://github.com/pztrn/matrix-xmpp-bridge)
|
|
@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: node-purple
|
|
||||||
categories: projects as
|
|
||||||
author: Matrix.org team / tjfontaine
|
|
||||||
maturity: Early beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
[node-purple](https://github.com/tjfontaine/node-purple) provides basic FFI bindings for libpurple. In our fork, [appservice](https://github.com/matrix-org/node-purple/tree/master/appservice) connects node-purple to the AS API, so you can talk from Matrix to libpurple's connections.
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: slackbridge
|
|
||||||
categories: projects as
|
|
||||||
author: illicitonion
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
illicitonion's early Slack bridge, written in Go.
|
|
||||||
|
|
||||||
Check it out on [github](https://github.com/illicitonion/slackbridge)
|
|
@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: purple-matrix
|
|
||||||
categories: projects client
|
|
||||||
description: A plugin for libpurple
|
|
||||||
author: Matrix.org team
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
This project is a plugin for [libpurple](https://developer.pidgin.im/wiki/WhatIsLibpurple) which adds the ability to communicate with matrix.org homeservers to any libpurple-based clients (such as [Pidgin](http://www.pidgin.im/)).
|
|
||||||
|
|
||||||
Get it at [github](https://github.com/matrix-org/purple-matrix/).
|
|
@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Bender
|
|
||||||
categories: projects other
|
|
||||||
description: A simple/flexible bot framework
|
|
||||||
author: Dylan Griffith
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Bender is a Matrix bot framework written in Elixir: [https://github.com/DylanGriffith/bender](https://github.com/DylanGriffith/bender)
|
|
@ -1,15 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Mero
|
|
||||||
categories: projects as
|
|
||||||
description: NodeJS based XMPP facade bridge for matrix.org
|
|
||||||
author: SkaveRat
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
NodeJS based XMPP facade bridge for matrix.org
|
|
||||||
|
|
||||||
This Matrix Application Server will pretend to be a XMPP (jabber) server and mirror all actions to and from Matrix.
|
|
||||||
|
|
||||||
Check it out on [github](https://github.com/SkaveRat/mero)
|
|
@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: MatrixTool
|
|
||||||
categories: projects other
|
|
||||||
description: Commands to interact with a Matrix homeserver
|
|
||||||
author: LeoNerd
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
# {{ page.title }}
|
|
||||||
|
|
||||||
The tool provides a wrapper around a number of sub-commands that provide useful interactions with a Matrix homeserver.
|
|
||||||
|
|
||||||
You can grab it from [CPAN](http://search.cpan.org/~pevans/App-MatrixTool/).
|
|
@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Ruma
|
|
||||||
categories: projects server
|
|
||||||
author: Jimmy Cuadra
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Ruma is a server written in Rust ([github](https://github.com/ruma/ruma))
|
|
@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Hubot-Matrix
|
|
||||||
categories: projects other
|
|
||||||
description: A Matrix-adapter for Hubot
|
|
||||||
author: David A Roberts
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
A Matrix-adapter for Hubot: [https://github.com/davidar/hubot-matrix/](https://github.com/davidar/hubot-matrix/)
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Matrix Client SDK for GLib
|
|
||||||
categories: projects sdk
|
|
||||||
author: Gergely Polonkai
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
A Matrix.org client-server SDK for GLib >= 2.40. It contains both raw API calls and a signal based asynchronous client. Get it from [github](https://github.com/gergelypolonkai/matrix-glib-sdk)!
|
|
@ -1,15 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Perpetually Talking Online (PTO)
|
|
||||||
categories: projects client
|
|
||||||
description: PTO is an IRC frontend to the federated Matrix network.
|
|
||||||
author: tdfischer
|
|
||||||
maturity: Abandoned
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Perpetually Talking Online (PTO) is an IRC frontend to the federated Matrix network. It aims to enable as many people as possible to use an existing Matrix homeserver with their existing IRC clients, and provides a radically expanded feature set for existing IRC communities looking to migrate to Matrix.
|
|
||||||
|
|
||||||
See [pto.im](http://pto.im) for more info - or grab the code from [GitHub](https://github.com/tdfischer/pto).
|
|
||||||
|
|
||||||
Unfortunately, it appears that this project is no longer being worked on. Check out [matrix-ircd](./matrix-ircd.html) instead!
|
|
@ -1,20 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Matrix Console iOS
|
|
||||||
categories: projects client
|
|
||||||
thumbnail: /docs/projects/images/matrix-console-ios-2016-02-16-cropped.png
|
|
||||||
description: A neutral iOS client showcasing Matrix capabilities and implementation.
|
|
||||||
author: Matrix.org team
|
|
||||||
maturity: No longer maintained
|
|
||||||
---
|
|
||||||
|
|
||||||
![screenshot](/docs/projects/images/matrix-console-ios-2016-02-16-large.png "{{ page.title }}")
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Matrix.org's reference iOS client.
|
|
||||||
|
|
||||||
This client is meant to be a showcase of Matrix capabilities, a reference implementation of the Matrix standard and an easy entry to the Matrix ecosystem from iOS devices for less techy users, with a relatively neutral branding. This client is built using [MatrixKit](http://matrix.org/blog/project/matrix-ios-matrixkit/).
|
|
||||||
|
|
||||||
The code can be retrieved from [github](https://github.com/matrix-org/matrix-ios-console).
|
|
||||||
|
|
||||||
Also available from the Apple [app store](https://itunes.apple.com/gb/app/matrix-console/id970074271?mt=8).
|
|
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Dendron
|
|
||||||
categories: projects server
|
|
||||||
author: Matrix.org team
|
|
||||||
maturity: Obsolete
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Dendron was the start of an experimental Matrix homeserver written in Go, built as a 'strangler pattern' implementation on top of Synapse. It was discontinued in favour of Dendrite.
|
|
||||||
|
|
||||||
The code lives on at [github](https://github.com/matrix-org/dendron)!
|
|
@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Rocket Chat Federation
|
|
||||||
categories: projects as
|
|
||||||
thumbnail: https://raw.githubusercontent.com/Sing-Li/bbug/master/images/rcsnynapse.png
|
|
||||||
author: Rocket.Chat
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
![screenshot](https://raw.githubusercontent.com/Sing-Li/bbug/master/images/rcsnynapse.png "{{ page.title }}")
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Rocket.Chat have written a bot called Freddie that pairs a Synapse server with a Rocket.Chat server ([github](https://github.com/RocketChat/Rocket.Chat.Federation/tree/develop/matrix.org/hubot-freddie))
|
|
@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: feedbot
|
|
||||||
categories: projects other
|
|
||||||
description: Connects to RSS and Twitter feeds
|
|
||||||
author: Ryan Rix
|
|
||||||
maturity: Early beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Connect to RSS and Twitter feeds via Ryan Rix's feedbot!
|
|
||||||
|
|
||||||
Check it out from [Ryan's git repo](https://fort.kickass.systems/git/rrix/matrix-feedbot)
|
|
@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Lightrix
|
|
||||||
categories: projects other
|
|
||||||
description: Drive Adafruit Neopixels over Matrix
|
|
||||||
author: Ryan Rix
|
|
||||||
maturity: Early beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Control Adafruit Neopixels via Matrix!
|
|
||||||
|
|
||||||
Check it out from [Ryan's git repo](https://fort.kickass.systems/git/rrix/lightrix) or watch it in action on [YouTube](https://www.youtube.com/watch?v=4YG9Fk5aP24)
|
|
@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: mcat
|
|
||||||
categories: projects other
|
|
||||||
description: Pipe to/from a Matrix room via the Python SDK
|
|
||||||
author: Ryan Rix
|
|
||||||
maturity: Early beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Pipe in to and out of a Matrix room using the [Matrix Python SDK](https://github.com/matrix-org/matrix-python-sdk).
|
|
||||||
|
|
||||||
Check it out from [Ryan's git repo](https://fort.kickass.systems/git/rrix/matrix-cat)
|
|
@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Polynomial
|
|
||||||
description: A Decentralized Webring
|
|
||||||
categories: projects other
|
|
||||||
author: Ryan Rix
|
|
||||||
maturity: Early beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Webring software built on top of Matrix.org which means it doesn't have a central point of failure.
|
|
||||||
|
|
||||||
Check it out at [Ryan's blog](http://whatthefuck.computer/blog/2015/12/06/polynomial-a-decentralized-webring/) and grab the code from [Ryan's git repo](https://fort.kickass.systems/git/rrix/polynomial)
|
|
@ -1,14 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Headjack
|
|
||||||
categories: projects client
|
|
||||||
thumbnail: https://matrix.org/blog/wp-content/uploads/2015/05/headjack-400x284.png
|
|
||||||
description: Experimental Chrome App client
|
|
||||||
author: SkaveRat
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
![screenshot](https://matrix.org/blog/wp-content/uploads/2015/05/headjack.png "{{ page.title }}")
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Experimental Chrome App desktop client for Matrix, using [matrix-angular-sdk](https://github.com/matrix-org/matrix-angular-sdk). Available from [github](https://github.com/SkaveRat/headjack).
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Net::Async::Matrix (Perl)
|
|
||||||
categories: projects sdk
|
|
||||||
author: LeoNerd
|
|
||||||
maturity: Late beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
LeoNerd's Net::Async::Matrix client SDK library for Perl: [https://metacpan.org/release/Net-Async-Matrix](https://metacpan.org/release/Net-Async-Matrix)
|
|
@ -1,216 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Try Matrix Now!
|
|
||||||
categories: projects
|
|
||||||
---
|
|
||||||
|
|
||||||
<div class='font18'>
|
|
||||||
Matrix is a whole ecosystem of matrix-enabled clients, servers, gateways, application services, bots, etc.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
<div class='font18 bold'>
|
|
||||||
The easiest way to get started is to pick a client that appeals and join #matrix:matrix.org:
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p> </p>
|
|
||||||
|
|
||||||
<table class='bigtable'>
|
|
||||||
<tr>
|
|
||||||
<td class='bigproject'>
|
|
||||||
<a href='./client/weechat.html' class='font18 bold'>
|
|
||||||
Weechat/Matrix
|
|
||||||
</a><br />
|
|
||||||
If you like command line clients, try the Weechat plugin.<br /><br />
|
|
||||||
<a href='./client/weechat.html'>
|
|
||||||
<img src='https://matrix.org/blog/wp-content/uploads/2015/04/Screen-Shot-2015-08-07-at-13.31.29-300x209.png' class='featured_screenshot'>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td class='bigproject'>
|
|
||||||
<a href='./client/riot.html' class='font18 bold'>
|
|
||||||
Riot
|
|
||||||
</a><br />
|
|
||||||
If you like glossy and feature-rich web clients, try Riot.<br /><br />
|
|
||||||
<a href='./client/riot.html'>
|
|
||||||
<img src='/docs/projects/images/riot-web-featured.png' class='featured_screenshot'>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td class='bigproject'>
|
|
||||||
<a href='./client/riot-ios.html' class='font18 bold'>
|
|
||||||
Riot iOS
|
|
||||||
</a><br />
|
|
||||||
You can also access Matrix on your iOS phone via Riot iOS.<br /><br />
|
|
||||||
<a href='./client/riot-ios.html'>
|
|
||||||
<img src='/docs/projects/images/vector-iOS-featured.png' class='featured_screenshot'>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td class='bigproject'>
|
|
||||||
<a href='./client/riot-android.html' class='font18 bold'>
|
|
||||||
Riot Android
|
|
||||||
</a><br />
|
|
||||||
Riot is also available on Android devices!<br /><br />
|
|
||||||
<a href='./client/riot-android.html'>
|
|
||||||
<img src='/docs/projects/images/vector-android-featured.png' class='featured_screenshot'>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
This page aims to collect all known Matrix projects - if you want to add a new one (or update an existing one), you can submit a PR to the [matrix-doc](https://github.com/matrix-org/matrix-doc) project on github - the existing projects can be found [here](https://github.com/matrix-org/matrix-doc/tree/master/supporting-docs/projects) - or just let us know in the #matrix:matrix.org room.
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
<div class='font18'>
|
|
||||||
Projects using Matrix:
|
|
||||||
</div>
|
|
||||||
|
|
||||||
* TOC
|
|
||||||
{:toc .toc}
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
Clients
|
|
||||||
=======
|
|
||||||
|
|
||||||
<table>
|
|
||||||
{% assign post_nr = '0' %}
|
|
||||||
{% for post in site.categories.client reversed limit:100 %}
|
|
||||||
{% assign add_new_row_test = post_nr | modulo:6 %}
|
|
||||||
{% if add_new_row_test == 0 %}<tr>{% endif %}
|
|
||||||
<td class='project'>
|
|
||||||
<a href='/docs{{ BASE_PATH }}{{ post.url }}'>
|
|
||||||
<img class='thumbnail' src='{{ post.thumbnail }}'>
|
|
||||||
</a>
|
|
||||||
<br />
|
|
||||||
<a href='/docs{{ BASE_PATH }}{{ post.url }}'>
|
|
||||||
{{ post.title }}
|
|
||||||
</a><br />
|
|
||||||
<div style='margin-bottom: 8px;'>
|
|
||||||
{{ post.description }}
|
|
||||||
</div>
|
|
||||||
Author: {{ post.author }}<br />
|
|
||||||
Maturity: {{ post.maturity }}
|
|
||||||
</td>
|
|
||||||
{% assign post_nr = post_nr | plus: '1' %}
|
|
||||||
{% assign add_new_row_test = post_nr | modulo:6 %}
|
|
||||||
{% if add_new_row_test == 0 %}</tr>{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
Servers
|
|
||||||
=======
|
|
||||||
|
|
||||||
<table>
|
|
||||||
{% assign post_nr = '0' %}
|
|
||||||
{% for post in site.categories.server reversed limit:100 %}
|
|
||||||
{% assign add_new_row_test = post_nr | modulo:6 %}
|
|
||||||
{% if add_new_row_test == 0 %}<tr>{% endif %}
|
|
||||||
<td class='project'>
|
|
||||||
<a href='/docs{{ BASE_PATH }}{{ post.url }}'>
|
|
||||||
{{ post.title }}
|
|
||||||
</a><br />
|
|
||||||
<div style='margin-bottom: 8px;'>
|
|
||||||
{{ post.description }}
|
|
||||||
</div>
|
|
||||||
Author: {{ post.author }}<br />
|
|
||||||
Maturity: {{ post.maturity }}
|
|
||||||
</td>
|
|
||||||
{% assign post_nr = post_nr | plus: '1' %}
|
|
||||||
{% assign add_new_row_test = post_nr | modulo:6 %}
|
|
||||||
{% if add_new_row_test == 0 %}</tr>{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
Application Services
|
|
||||||
====================
|
|
||||||
|
|
||||||
<table>
|
|
||||||
{% assign post_nr = '0' %}
|
|
||||||
{% for post in site.categories.as reversed limit:100 %}
|
|
||||||
{% assign add_new_row_test = post_nr | modulo:6 %}
|
|
||||||
{% if add_new_row_test == 0 %}<tr>{% endif %}
|
|
||||||
<td class='project'>
|
|
||||||
<a href='/docs{{ BASE_PATH }}{{ post.url }}'>
|
|
||||||
{{ post.title }}
|
|
||||||
</a><br />
|
|
||||||
<div style='margin-bottom: 8px;'>
|
|
||||||
{{ post.description }}
|
|
||||||
</div>
|
|
||||||
Author: {{ post.author }}<br />
|
|
||||||
Maturity: {{ post.maturity }}
|
|
||||||
</td>
|
|
||||||
{% assign post_nr = post_nr | plus: '1' %}
|
|
||||||
{% assign add_new_row_test = post_nr | modulo:6 %}
|
|
||||||
{% if add_new_row_test == 0 %}</tr>{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
Client SDKs
|
|
||||||
===========
|
|
||||||
|
|
||||||
<table>
|
|
||||||
{% assign post_nr = '0' %}
|
|
||||||
{% for post in site.categories.sdk reversed limit:100 %}
|
|
||||||
{% assign add_new_row_test = post_nr | modulo:6 %}
|
|
||||||
{% if add_new_row_test == 0 %}<tr>{% endif %}
|
|
||||||
<td class='project'>
|
|
||||||
<a href='/docs{{ BASE_PATH }}{{ post.url }}'>
|
|
||||||
{{ post.title }}
|
|
||||||
</a><br />
|
|
||||||
<div style='margin-bottom: 8px;'>
|
|
||||||
{{ post.description }}
|
|
||||||
</div>
|
|
||||||
Author: {{ post.author }}<br />
|
|
||||||
Maturity: {{ post.maturity }}
|
|
||||||
</td>
|
|
||||||
{% assign post_nr = post_nr | plus: '1' %}
|
|
||||||
{% assign add_new_row_test = post_nr | modulo:6 %}
|
|
||||||
{% if add_new_row_test == 0 %}</tr>{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
Other
|
|
||||||
=====
|
|
||||||
|
|
||||||
<table>
|
|
||||||
{% assign post_nr = '0' %}
|
|
||||||
{% for post in site.categories.other reversed limit:100 %}
|
|
||||||
{% assign add_new_row_test = post_nr | modulo:6 %}
|
|
||||||
{% if add_new_row_test == 0 %}<tr>{% endif %}
|
|
||||||
<td class='project'>
|
|
||||||
<a href='/docs{{ BASE_PATH }}{{ post.url }}'>
|
|
||||||
{{ post.title }}
|
|
||||||
</a><br />
|
|
||||||
<div style='margin-bottom: 8px;'>
|
|
||||||
{{ post.description }}
|
|
||||||
</div>
|
|
||||||
Author: {{ post.author }}<br />
|
|
||||||
Maturity: {{ post.maturity }}
|
|
||||||
</td>
|
|
||||||
{% assign post_nr = post_nr | plus: '1' %}
|
|
||||||
{% assign add_new_row_test = post_nr | modulo:6 %}
|
|
||||||
{% if add_new_row_test == 0 %}</tr>{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Vector Desktop
|
|
||||||
description: Desktop version of Vector
|
|
||||||
author: Steven Hammerton
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Desktop version of the [Vector](./vector.html) web client. Basically it's Vector wrapped in an [Electron](https://github.com/atom/electron) app. Source here: [https://github.com/stevenhammerton/vector-desktop](https://github.com/stevenhammerton/vector-desktop)
|
|
@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Matrix Blog
|
|
||||||
categories: projects client
|
|
||||||
description: Read-only blog-style Matrix interface
|
|
||||||
author: simeng
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
An example read-only blog-style interface to a Matrix room ([github](https://github.com/simeng/matrix-blog)).
|
|
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: matrix-appservice-gitter
|
|
||||||
categories: projects as
|
|
||||||
author: LeoNerd
|
|
||||||
maturity: Early beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
This project bridges [Gitter](https://gitter.im) to Matrix, via the AS API on the Matrix side, and a Gitter user on the Gitter side.
|
|
||||||
|
|
||||||
Get it from [github](https://github.com/matrix-org/matrix-appservice-gitter).
|
|
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Matrix .NET SDK
|
|
||||||
categories: projects sdk
|
|
||||||
author: Half-Shot
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
# {{ page.title }}
|
|
||||||
|
|
||||||
The .NET SDK provides an object oriented library to interact with Matrix. It is currently mature enough to be used for simple clients and bots.
|
|
||||||
|
|
||||||
[Github](https://github.com/Half-Shot/matrix-dotnet-sdk)
|
|
@ -1,17 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: MPD DJ
|
|
||||||
categories: projects other
|
|
||||||
description: A bot for controlling MPD over matrix.
|
|
||||||
author: Half-Shot
|
|
||||||
maturity: Alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
|
|
||||||
Ever wanted to control a MPD instance over matrix? Now you can!
|
|
||||||
|
|
||||||
Supports a selection (with more coming soon) of mpd commands with the ability to play Youtube links.
|
|
||||||
|
|
||||||
Development is steadily ongoing at [Github](https://github.com/Half-Shot/matrix-mpd-dj)
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: libqmatrixclient
|
|
||||||
categories: projects sdk
|
|
||||||
author: Kitsune Ral, Felix Rohrbach
|
|
||||||
maturity: Late alpha
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
libqmatrixclient is a Qt-based library to make IM clients for the Matrix protocol. It is used by [Quaternion](https://matrix.org/docs/projects/client/quaternion.html) and is a part of the QMatrixClient project. Recent builds of [Tensor](https://matrix.org/docs/projects/client/tensor.html) are also made on top of libqmatrixclient.
|
|
||||||
|
|
||||||
The project lives in QMatrixClient [github space](https://github.com/QMatrixClient/libqmatrixclient).
|
|
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
layout: project
|
|
||||||
title: Concourse/Matrix notification resource
|
|
||||||
categories: projects other
|
|
||||||
thumbnail: /docs/projects/images/concourse-ci-logo.png
|
|
||||||
description: Post notifications from Concourse CI jobs
|
|
||||||
author: freelock
|
|
||||||
maturity: beta
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ page.title }}
|
|
||||||
Create a Concourse custom resource type using [freelock/matrix-notification-resource](https://hub.docker.com/r/freelock/matrix-notification-resource/) from Docker Hub, or fork/contribute on [github](https://github.com/freelock/matrix-notification-resource)
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue