matrix-appservice
Advanced tools
Comparing version 0.0.4 to 0.0.5
/* Application Service API | ||
* This file contains the raw HTTP calls for the AS API. This includes inbound | ||
* and outbound calls. The general structure for outbound calls involves calling | ||
* a function which will return a Q promise, which will be resolved when the | ||
* HTTP call finishes. The general structure for inbound calls is more complex. | ||
* This file contains the raw HTTP calls for the AS API. | ||
* This module will invoke an AsapiRequestHandler to handle the incoming | ||
@@ -10,11 +7,6 @@ * request. This request handler is expected to return a promise, which will be | ||
*/ | ||
"use strict"; | ||
var request = require("request"); | ||
var url = require("url"); | ||
var q = require("q"); | ||
var PREFIX = "/_matrix/appservice/v1"; | ||
function AsapiRequestHandler() { | ||
@@ -100,61 +92,2 @@ | ||
}); | ||
}; | ||
/* | ||
* Register with the specified home server. | ||
* @param {String} hsUrl The home server to register with. | ||
* @param {String} asUrl The application service URL to hit for incoming requests. | ||
* @param {String} asToken The application service token. | ||
* @param {Object} namespaces The namespaces Object | ||
* @returns {Promise} A promise which will be resolved if the request was | ||
* successful, or rejected if the call was not successful. | ||
*/ | ||
module.exports.register = function(hsUrl, asUrl, asToken, namespaces) { | ||
// POST /register | ||
// { url: "string", as_token: "string", "namespaces": Object } | ||
var endpoint = url.resolve(hsUrl, PREFIX + "/register"); | ||
var body = { | ||
url: asUrl, | ||
as_token: asToken, | ||
namespaces: namespaces | ||
}; | ||
console.log("/register => %s", JSON.stringify(body)); | ||
var defer = q.defer(); | ||
request.post(endpoint, {json: body}, function(error, response, body) { | ||
if (!error && response.statusCode == 200) { | ||
defer.resolve(body.hs_token); | ||
} | ||
else { | ||
defer.reject(body ? body : error); | ||
} | ||
}); | ||
return defer.promise; | ||
}; | ||
/* | ||
* Unregister with the specified home server. | ||
* @param {String} hsUrl The home server to unregister from. | ||
* @param {String} asToken The application service token. | ||
* @returns {Promise} A promise which will be resolved if the request was | ||
* successful, or rejected if the call was not successful. | ||
*/ | ||
module.exports.unregister = function(hsUrl, asToken) { | ||
// POST /unregister | ||
// { as_token: "string"} | ||
var endpoint = url.resolve(hsUrl, PREFIX + "/unregister"); | ||
var body = { | ||
as_token: asToken | ||
}; | ||
console.log("/unregister => %s", JSON.stringify(body)); | ||
var defer = q.defer(); | ||
request.post(endpoint, {json: body}, function(error, response, body) { | ||
if (!error && response.statusCode == 200) { | ||
defer.resolve(response); | ||
} | ||
else { | ||
defer.reject(body ? body : error); | ||
} | ||
}); | ||
return defer.promise; | ||
}; | ||
}; |
@@ -117,4 +117,4 @@ "use strict"; | ||
} | ||
if (["users", "aliases"].indexOf(type) == -1) { | ||
console.error("'type' must be 'users' or 'aliases'"); | ||
if (["users", "aliases", "rooms"].indexOf(type) == -1) { | ||
console.error("'type' must be 'users', 'rooms' or 'aliases'"); | ||
return; | ||
@@ -131,25 +131,2 @@ } | ||
AsapiController.prototype.register = function register(hsUrl, asUrl, asToken) { | ||
var defer = q.defer(); | ||
var that = this; | ||
if (this.hsToken) { | ||
return q(this.hsToken); | ||
} | ||
this.asapi.register(hsUrl, asUrl, asToken, this.namespaces).then(function(hsToken) { | ||
that.hsToken = hsToken; | ||
that.emit("registered", { | ||
hsToken: hsToken, | ||
namespaces: that.namespaces | ||
}); | ||
defer.resolve(hsToken); | ||
}, function(err) { | ||
defer.reject(err); | ||
}); | ||
return defer.promise; | ||
}; | ||
AsapiController.prototype.setHomeserverToken = function(hsToken) { | ||
this.hsToken = hsToken; | ||
}; | ||
AsapiController.prototype.getRegexNamespaces = function() { | ||
@@ -156,0 +133,0 @@ return this.namespaces; |
@@ -1,3 +0,4 @@ | ||
var appservice = require("matrix-appservice"); | ||
var logging = require("matrix-appservice-logging"); | ||
var appservice = require("../.."); | ||
var logging = require("../logging/logging.js"); | ||
var yaml = require("js-yaml"); | ||
@@ -12,7 +13,22 @@ logging.configure({ | ||
hs: "http://localhost:8008", | ||
hsToken: "d2b52424827ab3c28476e3f", | ||
token: "1234567890", | ||
as: "http://localhost:3500", | ||
port: 3500 | ||
as: "http://localhost:3522", | ||
port: 3522 | ||
} | ||
]); | ||
// return the config files which need to be put in the homeserver | ||
appservice.getRegistrations().done(function(entries) { | ||
entries.forEach(function(c) { | ||
console.log("===== BEGIN REGISTRATION YAML ====="); | ||
console.log(yaml.safeDump(c)); | ||
console.log("===== END REGISTRATION YAML ====="); | ||
console.log( | ||
"The above YAML file should be added to the destination HS config YAML" | ||
); | ||
}); | ||
}); | ||
// actually listen on the port | ||
appservice.runForever(); |
@@ -10,3 +10,6 @@ { | ||
"author": "", | ||
"license": "Apache 2.0" | ||
"license": "Apache 2.0", | ||
"dependencies": { | ||
"js-yaml": "^3.2.7" | ||
} | ||
} |
64
index.js
"use strict"; | ||
// external libs | ||
var crypto = require("crypto"); | ||
var express = require("express"); | ||
@@ -22,2 +23,7 @@ var bodyParser = require('body-parser'); | ||
if (!srvConfig.hsToken) { | ||
console.error("Missing home server token 'hsToken'!"); | ||
process.exit(1); | ||
} | ||
// app setup | ||
@@ -34,3 +40,3 @@ var app = express(); | ||
asapi.setRoutes(app, controller.requestHandler); | ||
controller.hsToken = srvConfig.hsToken; | ||
var defer = srvConfig.service.register(controller, srvConfig); | ||
@@ -46,2 +52,25 @@ srvConfig._internal = { | ||
module.exports.getRegistrations = function() { | ||
var defer = q.defer(); | ||
var registrations = []; | ||
var outstandingPromises = []; | ||
configs.forEach(function(config, index) { | ||
if (config._internal.defer) { | ||
console.log("matrix-appservice: Waiting on %s register() to finish", | ||
config.service.serviceName); | ||
outstandingPromises.push(config._internal.defer); | ||
config._internal.defer.done(function() { | ||
registrations.push(getServiceRegistration(config)); | ||
}); | ||
} | ||
else { | ||
registrations.push(getServiceRegistration(config)); | ||
} | ||
}); | ||
q.all(outstandingPromises).done(function() { | ||
defer.resolve(registrations); | ||
}); | ||
return defer.promise; | ||
}; | ||
module.exports.runForever = function() { | ||
@@ -62,18 +91,21 @@ configs.forEach(function(config, index) { | ||
var getServiceRegistration = function(config) { | ||
var hsToken = config._internal.controller.hsToken; | ||
var localpart = config.localpart || config.service.serviceName; | ||
return { | ||
url: config.as, | ||
as_token: config.token, | ||
hs_token: hsToken, | ||
sender_localpart: localpart, | ||
namespaces: config._internal.controller.namespaces | ||
} | ||
}; | ||
var runService = function(config) { | ||
config._internal.controller.register( | ||
config.hs, config.as, config.token).then(function(hsToken) { | ||
config._internal.server = config._internal.app.listen( | ||
config.port || (3000+index), function() { | ||
var host = config._internal.server.address().address; | ||
var port = config._internal.server.address().port; | ||
console.log("matrix-appservice: %s listening at %s on port %s", | ||
config.service.serviceName, host, port); | ||
}); | ||
}, | ||
function(err) { | ||
console.error( | ||
"matrix-appservice: %s was unable to register for token: %s", | ||
config.service.serviceName, JSON.stringify(err) | ||
); | ||
config._internal.server = config._internal.app.listen( | ||
config.port || (3000+index), function() { | ||
var host = config._internal.server.address().address; | ||
var port = config._internal.server.address().port; | ||
console.log("matrix-appservice: %s listening at %s on port %s", | ||
config.service.serviceName, host, port); | ||
}); | ||
@@ -80,0 +112,0 @@ }; |
{ | ||
"name": "matrix-appservice", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"description": "Matrix Application Service Framework", | ||
@@ -5,0 +5,0 @@ "main": "./index", |
@@ -56,2 +56,3 @@ This is a Matrix Application Service framework written in Node.js with Express. | ||
hs: "http://localhost:8008", | ||
hsToken: "a62b3cde826f274a310900a7bc373dd27", | ||
token: "1234567890", | ||
@@ -66,3 +67,12 @@ as: "http://localhost:3500", | ||
This will run the logging service, listening on port 3500. Multiple services can | ||
be registered. | ||
be registered. To generate the application registration files: | ||
``` javascript | ||
// return the config files which need to be put in the homeserver | ||
var yaml = require("js-yaml"); | ||
appservice.getRegistrations().done(function(entries) { | ||
entries.forEach(function(entry) { | ||
console.log(yaml.safeDump(entry)); | ||
}); | ||
}); | ||
``` | ||
@@ -78,2 +88,3 @@ Framework | ||
- ``hs`` => ``String``: The base home server URL to hit to register with. | ||
- ``hsToken`` => ``String``: The home server token which will be added on requests from the HS. | ||
- ``token`` => ``String``: The application service token. | ||
@@ -92,2 +103,5 @@ - ``as`` => ``String``: The base application service URL that the home server | ||
* ``serviceConfigs`` (Array<Object>): An array of service configs. | ||
- ``getRegistrations()``: Get the registration YAML files for each registered service. | ||
Returns a Promise, which resolves to an array of Objects which represent the desired | ||
YAML. This object can be safely dumped by a YAML library. | ||
- ``runForever()``: For each registered service, listen on the specified port. | ||
@@ -127,11 +141,2 @@ | ||
- ``register(hsUrl, asUrl, asToken)``: [PRIVATE] Register with the home server. | ||
Services should not need to invoke this manually, as it is called for you in | ||
``matrix-appservice.runForever()``. | ||
- ``setHomeserverToken(hsToken)``: Set the home server token to use when | ||
checking incoming requests. This will prevent registration if it is called | ||
before the ``register`` method. | ||
* ``hsToken`` (String): The home server token. | ||
- ``on(nodeEventType, fn)``: Listens for the specified event type, and invoke | ||
@@ -148,7 +153,2 @@ the specified function. | ||
type e.g. ``type:m.room.message`` | ||
- ``registered`` (emits Object): Emitted when the AS successfully registers | ||
with the HS. Contains an object with a key ``hsToken`` for the home server | ||
token. To prevent re-registration on startup, call | ||
``controller.setHomeserverToken(hsToken)`` in your service's | ||
``register(controller, config)`` function. | ||
@@ -161,3 +161,4 @@ Service API | ||
- ``serviceName`` (String): The name of the service. Typically the package name | ||
e.g. ``matrix-appservice-foo``. | ||
e.g. ``matrix-appservice-foo``. This name is the default user ID localpart specified | ||
in the application service registration, so shouldn't contain special characters. | ||
@@ -164,0 +165,0 @@ - ``configure(opts)``: The service specific configuration. |
@@ -7,3 +7,4 @@ /* Provides the interface required to implement a service. | ||
// an informative name for this service | ||
// an informative name for this service - this will be used as a default user ID | ||
// localpart | ||
module.exports.serviceName = "template"; | ||
@@ -28,2 +29,3 @@ | ||
* - "port" {Number} : the port being listened on | ||
* - "localpart" {String} : (Optional) the desired AS user ID localpart | ||
*/ | ||
@@ -30,0 +32,0 @@ module.exports.register = function(controller, serviceConfig) { |
168
35524
388