mirror of
https://github.com/turt2live/matrix-dimension.git
synced 2024-10-01 01:05:53 -04:00
Restructure backend integrations to better support the various types
This commit is contained in:
parent
9ebd87bd88
commit
574c24bcd6
3
app.js
3
app.js
@ -7,8 +7,7 @@ var config = require("config");
|
||||
log.info("app", "Bootstrapping Dimension...");
|
||||
var db = new DimensionStore();
|
||||
db.prepare().then(() => {
|
||||
var app = new Dimension(db);
|
||||
app.start();
|
||||
Dimension.start(db);
|
||||
|
||||
if (config.get("demobot.enabled")) {
|
||||
log.info("app", "Demo bot enabled - starting up");
|
||||
|
142
src/Dimension.js
142
src/Dimension.js
@ -4,29 +4,27 @@ var log = require("./util/LogService");
|
||||
var DimensionStore = require("./storage/DimensionStore");
|
||||
var bodyParser = require('body-parser');
|
||||
var path = require("path");
|
||||
var MatrixLiteClient = require("./matrix/MatrixLiteClient");
|
||||
var randomString = require("random-string");
|
||||
var ScalarClient = require("./scalar/ScalarClient.js");
|
||||
var VectorScalarClient = require("./scalar/VectorScalarClient");
|
||||
var integrations = require("./integration");
|
||||
var _ = require("lodash");
|
||||
var UpstreamIntegration = require("./integration/UpstreamIntegration");
|
||||
var HostedIntegration = require("./integration/HostedIntegration");
|
||||
var IntegrationImpl = require("./integration/impl");
|
||||
var DimensionApi = require("./DimensionApi");
|
||||
var ScalarApi = require("./ScalarApi");
|
||||
|
||||
// TODO: Convert backend to typescript? Would avoid stubbing classes all over the place
|
||||
|
||||
/**
|
||||
* Primary entry point for Dimension
|
||||
*/
|
||||
class Dimension {
|
||||
|
||||
// TODO: Spread the app out into other classes
|
||||
// eg: ScalarApi, DimensionApi, etc
|
||||
|
||||
/**
|
||||
* Creates a new Dimension
|
||||
* @param {DimensionStore} db the storage
|
||||
*/
|
||||
constructor(db) {
|
||||
constructor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Dimension service
|
||||
* @param {DimensionStore} db the store to use
|
||||
*/
|
||||
start(db) {
|
||||
this._db = db;
|
||||
this._app = express();
|
||||
this._app.use(express.static('web-dist'));
|
||||
@ -50,122 +48,12 @@ class Dimension {
|
||||
next();
|
||||
});
|
||||
|
||||
this._app.post("/api/v1/scalar/register", this._scalarRegister.bind(this));
|
||||
this._app.get("/api/v1/scalar/checkToken", this._checkScalarToken.bind(this));
|
||||
DimensionApi.bootstrap(this._app, this._db);
|
||||
ScalarApi.bootstrap(this._app, this._db);
|
||||
|
||||
this._app.get("/api/v1/dimension/integrations/:roomId", this._getIntegrations.bind(this));
|
||||
this._app.post("/api/v1/dimension/removeIntegration", this._removeIntegration.bind(this));
|
||||
}
|
||||
|
||||
start() {
|
||||
this._app.listen(config.get('web.port'), config.get('web.address'));
|
||||
log.info("Dimension", "API and UI listening on " + config.get("web.address") + ":" + config.get("web.port"));
|
||||
}
|
||||
|
||||
_removeIntegration(req, res) {
|
||||
var roomId = req.body.roomId;
|
||||
var userId = req.body.userId;
|
||||
var scalarToken = req.body.scalarToken;
|
||||
|
||||
if (!roomId || !userId || !scalarToken) {
|
||||
res.status(400).send({error: "Missing room, user, or token"});
|
||||
return;
|
||||
}
|
||||
|
||||
var integrationConfig = integrations.byUserId[userId];
|
||||
if (!integrationConfig) {
|
||||
res.status(400).send({error: "Unknown integration"});
|
||||
return;
|
||||
}
|
||||
|
||||
this._db.checkToken(scalarToken).then(() => {
|
||||
if (integrationConfig.upstream) {
|
||||
return this._db.getUpstreamToken(scalarToken).then(upstreamToken => new UpstreamIntegration(integrationConfig, upstreamToken));
|
||||
} else return new HostedIntegration(integrationConfig);
|
||||
}).then(integration => integration.leaveRoom(roomId)).then(() => {
|
||||
res.status(200).send({success: true});
|
||||
}).catch(err => res.status(500).send({error: err.message}));
|
||||
}
|
||||
|
||||
_getIntegrations(req, res) {
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
|
||||
var scalarToken = req.query.scalar_token;
|
||||
this._db.checkToken(scalarToken).then(() => {
|
||||
var roomId = req.params.roomId;
|
||||
if (!roomId) {
|
||||
res.status(400).send({error: 'Missing room ID'});
|
||||
return;
|
||||
}
|
||||
|
||||
var results = _.map(integrations.all, i => JSON.parse(JSON.stringify(i)));
|
||||
|
||||
var promises = [];
|
||||
_.forEach(results, i => {
|
||||
if (IntegrationImpl[i.type]) {
|
||||
var confs = IntegrationImpl[i.type];
|
||||
if (confs[i.integrationType]) {
|
||||
log.info("Dimension", "Using special configuration for " + i.type + " (" + i.integrationType + ")");
|
||||
|
||||
promises.push(confs[i.integrationType](this._db, i, roomId, scalarToken).then(integration => {
|
||||
return integration.getUserId().then(userId=> {
|
||||
i.userId = userId;
|
||||
return integration.getState();
|
||||
}).then(state=> {
|
||||
for (var key in state) {
|
||||
i[key] = state[key];
|
||||
}
|
||||
});
|
||||
}))
|
||||
} else log.verbose("Dimension", "No special configuration needs for " + i.type + " (" + i.integrationType + ")");
|
||||
} else log.verbose("Dimension", "No special implementation type for " + i.type);
|
||||
});
|
||||
|
||||
Promise.all(promises).then(() => res.send(_.map(results, integration => {
|
||||
integration.upstream = undefined;
|
||||
integration.hosted = undefined;
|
||||
return integration;
|
||||
})));
|
||||
}).catch(err => {
|
||||
log.error("Dimension", err);
|
||||
res.status(500).send({error: err});
|
||||
});
|
||||
}
|
||||
|
||||
_checkScalarToken(req, res) {
|
||||
var token = req.query.scalar_token;
|
||||
if (!token) res.sendStatus(400);
|
||||
else this._db.checkToken(token).then(() => {
|
||||
res.sendStatus(200);
|
||||
}).catch(() => res.sendStatus(401));
|
||||
}
|
||||
|
||||
_scalarRegister(req, res) {
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
|
||||
var tokenInfo = req.body;
|
||||
if (!tokenInfo || !tokenInfo['access_token'] || !tokenInfo['token_type'] || !tokenInfo['matrix_server_name'] || !tokenInfo['expires_in']) {
|
||||
res.status(400).send({error: 'Missing OpenID'});
|
||||
return;
|
||||
}
|
||||
|
||||
var client = new MatrixLiteClient(tokenInfo);
|
||||
var scalarToken = randomString({length: 25});
|
||||
var userId;
|
||||
client.getSelfMxid().then(mxid => {
|
||||
userId = mxid;
|
||||
if (!mxid) throw new Error("Token does not resolve to a matrix user");
|
||||
return ScalarClient.register(tokenInfo);
|
||||
}).then(upstreamToken => {
|
||||
return this._db.createToken(userId, tokenInfo, scalarToken, upstreamToken);
|
||||
}).then(() => {
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
res.send({scalar_token: scalarToken});
|
||||
}).catch(err => {
|
||||
log.error("Dimension", err);
|
||||
res.status(500).send({error: err.message});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Dimension;
|
||||
module.exports = new Dimension();
|
107
src/DimensionApi.js
Normal file
107
src/DimensionApi.js
Normal file
@ -0,0 +1,107 @@
|
||||
var IntegrationImpl = require("./integration/impl/index");
|
||||
var Integrations = require("./integration/index");
|
||||
var _ = require("lodash");
|
||||
var log = require("./util/LogService");
|
||||
|
||||
/**
|
||||
* API handler for the Dimension API
|
||||
*/
|
||||
class DimensionApi {
|
||||
|
||||
/**
|
||||
* Creates a new Dimension API
|
||||
*/
|
||||
constructor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstraps the Dimension API
|
||||
* @param {*} app the Express application
|
||||
* @param {DimensionStore} db the store to use
|
||||
*/
|
||||
bootstrap(app, db) {
|
||||
this._db = db;
|
||||
|
||||
app.get("/api/v1/dimension/integrations/:roomId", this._getIntegrations.bind(this));
|
||||
app.post("/api/v1/dimension/removeIntegration", this._removeIntegration.bind(this));
|
||||
}
|
||||
|
||||
_getIntegration(integrationConfig, roomId, scalarToken) {
|
||||
var factory = IntegrationImpl.getFactory(integrationConfig);
|
||||
if (!factory) throw new Error("Missing config factory for " + integrationConfig.name);
|
||||
|
||||
return factory(this._db, integrationConfig, roomId, scalarToken);
|
||||
}
|
||||
|
||||
_getIntegrations(req, res) {
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
|
||||
var roomId = req.params.roomId;
|
||||
if (!roomId) {
|
||||
res.status(400).send({error: 'Missing room ID'});
|
||||
return;
|
||||
}
|
||||
|
||||
var scalarToken = req.query.scalar_token;
|
||||
this._db.checkToken(scalarToken).then(() => {
|
||||
var integrations = _.map(Integrations.all, i => JSON.parse(JSON.stringify(i))); // clone
|
||||
|
||||
var promises = [];
|
||||
_.forEach(integrations, integration => {
|
||||
promises.push(this._getIntegration(integration, roomId, scalarToken).then(builtIntegration => {
|
||||
return builtIntegration.getUserId().then(userId => {
|
||||
integration.userId = userId;
|
||||
return builtIntegration.getState();
|
||||
}).then(state => {
|
||||
var keys = _.keys(state);
|
||||
for (var key of keys) {
|
||||
integration[key] = state[key];
|
||||
}
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
Promise.all(promises).then(() => res.send(_.map(integrations, integration => {
|
||||
// Remove sensitive material
|
||||
integration.upstream = undefined;
|
||||
integration.hosted = undefined;
|
||||
return integration;
|
||||
})));
|
||||
}).catch(err => {
|
||||
log.error("DimensionApi", err);
|
||||
console.error(err);
|
||||
res.status(500).send({error: err});
|
||||
});
|
||||
}
|
||||
|
||||
_removeIntegration(req, res) {
|
||||
var roomId = req.body.roomId;
|
||||
var userId = req.body.userId;
|
||||
var scalarToken = req.body.scalarToken;
|
||||
|
||||
if (!roomId || !userId || !scalarToken) {
|
||||
res.status(400).send({error: "Missing room, user, or token"});
|
||||
return;
|
||||
}
|
||||
|
||||
var integrationConfig = Integrations.byUserId[userId];
|
||||
if (!integrationConfig) {
|
||||
res.status(400).send({error: "Unknown integration"});
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("DimensionApi", "Remove requested for " + userId + " in room " + roomId);
|
||||
|
||||
this._db.checkToken(scalarToken).then(() => {
|
||||
return this._getIntegration(integrationConfig, roomId, scalarToken);
|
||||
}).then(integration => integration.removeFromRoom(roomId)).then(() => {
|
||||
res.status(200).send({success: true});
|
||||
}).catch(err => {
|
||||
log.error("DimensionApi", err);
|
||||
console.error(err);
|
||||
res.status(500).send({error: err.message});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new DimensionApi();
|
66
src/ScalarApi.js
Normal file
66
src/ScalarApi.js
Normal file
@ -0,0 +1,66 @@
|
||||
var MatrixLiteClient = require("./matrix/MatrixLiteClient");
|
||||
var randomString = require("random-string");
|
||||
var ScalarClient = require("./scalar/ScalarClient.js");
|
||||
var _ = require("lodash");
|
||||
var log = require("./util/LogService");
|
||||
|
||||
/**
|
||||
* API handler for the Scalar API, as required by Riot
|
||||
*/
|
||||
class ScalarApi {
|
||||
|
||||
/**
|
||||
* Creates a new Scalar API
|
||||
*/
|
||||
constructor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstraps the Scalar API
|
||||
* @param {*} app the Express application
|
||||
* @param {DimensionStore} db the store to use
|
||||
*/
|
||||
bootstrap(app, db) {
|
||||
this._db = db;
|
||||
|
||||
app.post("/api/v1/scalar/register", this._scalarRegister.bind(this));
|
||||
app.get("/api/v1/scalar/checkToken", this._checkScalarToken.bind(this));
|
||||
}
|
||||
|
||||
_checkScalarToken(req, res) {
|
||||
var token = req.query.scalar_token;
|
||||
if (!token) res.sendStatus(400);
|
||||
else this._db.checkToken(token).then(() => {
|
||||
res.sendStatus(200);
|
||||
}).catch(() => res.sendStatus(401));
|
||||
}
|
||||
|
||||
_scalarRegister(req, res) {
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
|
||||
var tokenInfo = req.body;
|
||||
if (!tokenInfo || !tokenInfo['access_token'] || !tokenInfo['token_type'] || !tokenInfo['matrix_server_name'] || !tokenInfo['expires_in']) {
|
||||
res.status(400).send({error: 'Missing OpenID'});
|
||||
return;
|
||||
}
|
||||
|
||||
var client = new MatrixLiteClient(tokenInfo);
|
||||
var scalarToken = randomString({length: 25});
|
||||
var userId;
|
||||
client.getSelfMxid().then(mxid => {
|
||||
userId = mxid;
|
||||
if (!mxid) throw new Error("Token does not resolve to a matrix user");
|
||||
return ScalarClient.register(tokenInfo);
|
||||
}).then(upstreamToken => {
|
||||
return this._db.createToken(userId, tokenInfo, scalarToken, upstreamToken);
|
||||
}).then(() => {
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
res.send({scalar_token: scalarToken});
|
||||
}).catch(err => {
|
||||
log.error("ScalarApi", err);
|
||||
res.status(500).send({error: err.message});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new ScalarApi();
|
@ -1,35 +0,0 @@
|
||||
var sdk = require("matrix-js-sdk");
|
||||
var log = require("../util/LogService");
|
||||
var StubbedIntegration = require("./StubbedIntegration");
|
||||
|
||||
/**
|
||||
* Represents an integration hosted on a known homeserver
|
||||
*/
|
||||
class HostedIntegration extends StubbedIntegration {
|
||||
|
||||
/**
|
||||
* Creates a new hosted integration
|
||||
* @param integrationSettings the integration settings
|
||||
*/
|
||||
constructor(integrationSettings) {
|
||||
super();
|
||||
this._settings = integrationSettings;
|
||||
this._client = sdk.createClient({
|
||||
baseUrl: this._settings.hosted.homeserverUrl,
|
||||
accessToken: this._settings.hosted.accessToken,
|
||||
userId: this._settings.userId,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaves a given Matrix room
|
||||
* @param {string} roomId the room to leave
|
||||
* @returns {Promise<>} resolves when completed
|
||||
*/
|
||||
leaveRoom(roomId) {
|
||||
log.info("HostedIntegration", "Removing " + this._settings.userId + " from " + roomId);
|
||||
return this._client.leave(roomId);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = HostedIntegration;
|
@ -1,7 +0,0 @@
|
||||
class StubbedIntegration {
|
||||
leaveRoom(roomId) {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = StubbedIntegration;
|
@ -1,33 +0,0 @@
|
||||
var VectorScalarClient = require("../scalar/VectorScalarClient");
|
||||
var log = require("../util/LogService");
|
||||
var StubbedIntegration = require("./StubbedIntegration");
|
||||
|
||||
/**
|
||||
* An integration that is handled by an upstream Scalar instance
|
||||
*/
|
||||
class UpstreamIntegration extends StubbedIntegration {
|
||||
|
||||
/**
|
||||
* Creates a new hosted integration
|
||||
* @param integrationSettings the integration settings
|
||||
* @param {string} upstreamToken the upstream scalar token
|
||||
*/
|
||||
constructor(integrationSettings, upstreamToken) {
|
||||
super();
|
||||
this._settings = integrationSettings;
|
||||
this._upstreamToken = upstreamToken;
|
||||
if (this._settings.upstream.type !== "vector") throw new Error("Unknown upstream type: " + this._settings.upstream.type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaves a given Matrix room
|
||||
* @param {string} roomId the room to leave
|
||||
* @returns {Promise<>} resolves when completed
|
||||
*/
|
||||
leaveRoom(roomId) {
|
||||
log.info("UpstreamIntegration", "Removing " + this._settings.userId + " from " + roomId);
|
||||
return VectorScalarClient.removeIntegration(this._settings.upstream.id, roomId, this._upstreamToken);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UpstreamIntegration;
|
@ -1,3 +1,5 @@
|
||||
var IntegrationStub = require("../type/IntegrationStub");
|
||||
|
||||
/**
|
||||
* Creates an integration using the given
|
||||
* @param {DimensionStore} db the database
|
||||
@ -7,5 +9,5 @@
|
||||
* @returns {Promise<*>} resolves to the configured integration
|
||||
*/
|
||||
module.exports = (db, integrationConfig, roomId, scalarToken) => {
|
||||
throw new Error("Not implemented");
|
||||
return Promise.resolve(new IntegrationStub(integrationConfig));
|
||||
};
|
@ -1,7 +1,35 @@
|
||||
var log = require("../../util/LogService");
|
||||
var StubbedFactory = require("./StubbedFactory");
|
||||
var SimpleBotFactory = require("./simple_bot/SimpleBotFactory");
|
||||
var RSSFactory = require("./rss/RSSFactory");
|
||||
|
||||
module.exports = {
|
||||
var mapping = {
|
||||
"complex-bot": {
|
||||
"rss": RSSFactory
|
||||
}
|
||||
};
|
||||
|
||||
var defaultFactories = {
|
||||
"complex-bot": null,
|
||||
"bot": SimpleBotFactory
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getFactory: (integrationConfig) => {
|
||||
var opts = mapping[integrationConfig.type];
|
||||
|
||||
if (!opts) {
|
||||
log.verbose("IntegrationImpl", "No option set available for " + integrationConfig.type + " - will attempt defaults");
|
||||
}
|
||||
|
||||
var factory = null;
|
||||
if (!opts) factory = defaultFactories[integrationConfig.type];
|
||||
else factory = opts[integrationConfig.integrationType];
|
||||
if (!factory) {
|
||||
log.verbose("IntegrationImpl", "No factory available for " + integrationConfig.type + " (" + integrationConfig.integrationType + ") - using stub");
|
||||
factory = StubbedFactory;
|
||||
}
|
||||
|
||||
return factory;
|
||||
}
|
||||
};
|
@ -20,15 +20,16 @@ class RSSBot extends ComplexBot {
|
||||
return this._backbone.getUserId();
|
||||
}
|
||||
|
||||
getFeeds() {
|
||||
return this._backbone.getFeeds();
|
||||
/*override*/
|
||||
getState() {
|
||||
return this._backbone.getFeeds().then(feeds => {
|
||||
return {feeds: feeds};
|
||||
});
|
||||
}
|
||||
|
||||
/*override*/
|
||||
getState() {
|
||||
return this.getFeeds().then(feeds => {
|
||||
return {feeds: feeds};
|
||||
});
|
||||
removeFromRoom(roomId) {
|
||||
return this._backbone.removeFromRoom(roomId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,15 @@ class StubbedRssBackbone {
|
||||
getFeeds() {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the bot from the given room
|
||||
* @param {string} roomId the room ID to remove the bot from
|
||||
* @returns {Promise<>} resolves when completed
|
||||
*/
|
||||
removeFromRoom(roomId) {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = StubbedRssBackbone;
|
@ -1,6 +1,7 @@
|
||||
var StubbedRssBackbone = require("./StubbedRssBackbone");
|
||||
var VectorScalarClient = require("../../../scalar/VectorScalarClient");
|
||||
var _ = require("lodash");
|
||||
var log = require("../../../util/LogService");
|
||||
|
||||
/**
|
||||
* Backbone for RSS bots running on vector.im through scalar
|
||||
@ -40,6 +41,10 @@ class VectorRssBackbone extends StubbedRssBackbone {
|
||||
});
|
||||
}
|
||||
|
||||
/*override*/
|
||||
removeFromRoom(roomId) {
|
||||
return VectorScalarClient.removeIntegration(this._config.upstream.id, roomId, this._upstreamToken);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = VectorRssBackbone;
|
36
src/integration/impl/simple_bot/HostedSimpleBackbone.js
Normal file
36
src/integration/impl/simple_bot/HostedSimpleBackbone.js
Normal file
@ -0,0 +1,36 @@
|
||||
var sdk = require("matrix-js-sdk");
|
||||
var log = require("../../../util/LogService");
|
||||
var IntegrationStub = require("../../type/IntegrationStub");
|
||||
|
||||
/**
|
||||
* Standalone (matrix) backbone for simple bots
|
||||
*/
|
||||
class HostedSimpleBackbone extends IntegrationStub {
|
||||
|
||||
/**
|
||||
* Creates a new standalone bot backbone
|
||||
* @param {*} botConfig the configuration for the bot
|
||||
*/
|
||||
constructor(botConfig) {
|
||||
super(botConfig);
|
||||
this._config = botConfig;
|
||||
this._client = sdk.createClient({
|
||||
baseUrl: this._config.hosted.homeserverUrl,
|
||||
accessToken: this._config.hosted.accessToken,
|
||||
userId: this._config.userId,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaves a given Matrix room
|
||||
* @param {string} roomId the room to leave
|
||||
* @returns {Promise<>} resolves when completed
|
||||
*/
|
||||
/*override*/
|
||||
removeFromRoom(roomId) {
|
||||
log.info("HostedSimpleBackbone", "Removing " + this._settings.userId + " from " + roomId);
|
||||
return this._client.leave(roomId);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = HostedSimpleBackbone;
|
35
src/integration/impl/simple_bot/SimpleBot.js
Normal file
35
src/integration/impl/simple_bot/SimpleBot.js
Normal file
@ -0,0 +1,35 @@
|
||||
var ComplexBot = require("../../type/ComplexBot");
|
||||
|
||||
/**
|
||||
* Represents an RSS bot
|
||||
*/
|
||||
class RSSBot extends ComplexBot {
|
||||
|
||||
/**
|
||||
* Creates a new RSS bot
|
||||
* @param botConfig the bot configuration
|
||||
* @param backbone the backbone powering this bot
|
||||
*/
|
||||
constructor(botConfig, backbone) {
|
||||
super(botConfig);
|
||||
this._backbone = backbone;
|
||||
}
|
||||
|
||||
/*override*/
|
||||
getUserId() {
|
||||
return this._backbone.getUserId();
|
||||
}
|
||||
|
||||
getFeeds() {
|
||||
return this._backbone.getFeeds();
|
||||
}
|
||||
|
||||
/*override*/
|
||||
getState() {
|
||||
return this.getFeeds().then(feeds => {
|
||||
return {feeds: feeds};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RSSBot;
|
12
src/integration/impl/simple_bot/SimpleBotFactory.js
Normal file
12
src/integration/impl/simple_bot/SimpleBotFactory.js
Normal file
@ -0,0 +1,12 @@
|
||||
var RSSBot = require("./RSSBot");
|
||||
var VectorRssBackbone = require("./VectorRssBackbone");
|
||||
|
||||
module.exports = (db, integrationConfig, roomId, scalarToken) => {
|
||||
if (integrationConfig.upstream) {
|
||||
if (integrationConfig.upstream.type !== "vector") throw new Error("Unsupported upstream");
|
||||
return db.getUpstreamToken(scalarToken).then(upstreamToken => {
|
||||
var backbone = new VectorRssBackbone(roomId, upstreamToken);
|
||||
return new RSSBot(integrationConfig, backbone);
|
||||
});
|
||||
} else throw new Error("Unsupported config");
|
||||
};
|
3
src/integration/impl/simple_bot/StubbedSimpleBackbone.js
Normal file
3
src/integration/impl/simple_bot/StubbedSimpleBackbone.js
Normal file
@ -0,0 +1,3 @@
|
||||
/**
|
||||
* Created by Travis on 5/28/2017.
|
||||
*/
|
22
src/integration/impl/simple_bot/VectorSimpleBackbone.js
Normal file
22
src/integration/impl/simple_bot/VectorSimpleBackbone.js
Normal file
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Stubbed/placeholder simple bot backbone
|
||||
*/
|
||||
class StubbedSimpleBackbone {
|
||||
|
||||
/**
|
||||
* Creates a new stubbed RSS backbone
|
||||
*/
|
||||
constructor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaves a given Matrix room
|
||||
* @param {string} roomId the room to leave
|
||||
* @returns {Promise<>} resolves when completed
|
||||
*/
|
||||
leaveRoom(roomId) {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = StubbedRssBackbone;
|
@ -21,6 +21,15 @@ class IntegrationStub {
|
||||
getState() {
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the integration from the given room
|
||||
* @param {string} roomId the room ID to remove the integration from
|
||||
* @returns {Promise<>} resolves when completed
|
||||
*/
|
||||
removeFromRoom(roomId) {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IntegrationStub;
|
||||
|
Loading…
Reference in New Issue
Block a user