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.
