Giter Club home page Giter Club logo

matrix-appservice-node's Introduction

matrix-appservice-node

This is a Matrix Application Service framework written in Node.js.

This can be used to quickly setup performant application services for almost anything you can think of in a web framework agnostic way.

If you are looking for a more fully-featured SDK for creating bridges, you may want to check out matrix-appservice-bridge instead.

Example

To create an app service registration file:

const { AppServiceRegistration } = require("matrix-appservice");

// creating registration files
const reg = new AppServiceRegistration();
reg.setAppServiceUrl("http://localhost:8010");
reg.setHomeserverToken(AppServiceRegistration.generateToken());
reg.setAppServiceToken(AppServiceRegistration.generateToken());
reg.setSenderLocalpart("example-appservice");
reg.addRegexPattern("users", "@.*", true);
reg.setProtocols(["exampleservice"]); // For 3PID lookups
reg.setId("example-service");
reg.outputAsYaml("registration.yaml");

You only need to generate a registration once, provided the registration info does not change. Once you have generated a registration, you can run the app service like so:

import { AppService, AppserviceHttpError } from "matrix-appservice";
// listening
const as = new AppService({
  homeserverToken: "abcd653bac492087d3c87"
});
as.on("type:m.room.message", (event) => {
  // handle the incoming message
});
as.onUserQuery = function(userId, callback) {
  // handle the incoming user query then respond
  console.log("RECV %s", userId);

  /*
  // if this userId cannot be created, or if some error
  // conditions occur, throw AppserviceHttpError exception.
  // The underlying appservice code will send the HTTP status,
  // Matrix errorcode and error message back as a response.

  if (userCreationOrQueryFailed) {
    throw new AppserviceHttpError(
      {
        errcode: "M_FORBIDDEN",
        error: "User query or creation failed.",
      },
      403, // Forbidden, or an appropriate HTTP status
    )
  }
  */

  callback();
};
// can also do this as a promise
as.onAliasQuery = async function(alias) {
  console.log("RECV %s", alias);
};
as.listen(8010);

TLS Connections

If MATRIX_AS_TLS_KEY and MATRIX_AS_TLS_CERT environment variables are defined and point to valid tls key and cert files, the AS will listen using an HTTPS listener.

API Reference

A hosted API reference can be found on GitHub Pages.

matrix-appservice-node's People

Contributors

andrewferr avatar andrewjdr avatar dakrone avatar dependabot[bot] avatar half-shot avatar illicitonion avatar jaywink avatar kegsay avatar lukebarnard1 avatar madlittlemods avatar tadzik avatar tak-hntlabs avatar verglor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

matrix-appservice-node's Issues

Add healthcheck endpoint

Is your feature request related to a problem? Please describe.

Add healthcheck endpoint that you can hit and see if the appservice (AS) bridge is available.

Describe the solution you'd like

Add /healthcheck endpoint that returns 200 OK.

Relevant code: src/app-service.ts#L89-L94

Describe alternatives you've considered

You can check if the appservice is available by hitting any of the GET endpoints already available but they don't return 200 OK for something random.

For example if you hit http://localhost:9000/rooms/healthcheck, it will return 403 Forbidden but you know the bridge is working on port 9000.

Version bump?

Can we please have a version bump on matrix-appservice-node, and also have matrix-appservice-bridge's package.json point to that new version, then get a new version for matrix-appservice-bridge as well?

I'd like to be able to include HTTPS support (0ff5e88) in our bridges without resorting to forking matrix-appservice-bridge and pointing our bridge to a commit on a fork.

I had been waiting patiently for a version bump, but it's been 4 months now :)

Missing required field(s): id, hs_token, as_token, url, sender_localpart

When trying to create a registration file, node (8) outputs

/node_modules/matrix-appservice/lib/app-service-registration.js:174
        throw new Error(
        ^

Error: Missing required field(s): id, hs_token, as_token, url, sender_localpart
    at AppServiceRegistration.getOutput (/home/korny/Development/00_SANDBOX/matrix/myzel-oi-job/node_modules/matrix-appservice/lib/app-service-registration.js:174:15)
    at AppServiceRegistration.outputAsYaml (/home/korny/Development/00_SANDBOX/matrix/myzel-oi-job/node_modules/matrix-appservice/lib/app-service-registration.js:163:20)
    at OI.initRegistration (/home/korny/Development/00_SANDBOX/matrix/myzel-oi-job/app.js:16:9)
    at Object.<anonymous> (/home/korny/Development/00_SANDBOX/matrix/myzel-oi-job/app.js:21:4)
    at Module._compile (module.js:643:30)
    at Object.Module._extensions..js (module.js:654:10)
    at Module.load (module.js:556:32)
    at tryModuleLoad (module.js:499:12)
    at Function.Module._load (module.js:491:3)
    at Function.Module.runMain (module.js:684:10)

my implementation is:

var AppServiceRegistration = require("matrix-appservice").AppServiceRegistrati
on;

class OI {
  constructor () {
  this._status = null;
  }

  initRegistration () {
    var reg = new AppServiceRegistration();
    reg.setAppServiceUrl("http://localhost:8010");
    reg.setHomeserverToken(AppServiceRegistration.generateToken());
    reg.setAppServiceToken(AppServiceRegistration.generateToken());
    reg.setSenderLocalpart("example-appservice");
    reg.addRegexPattern("users", "@.*", true);
    reg.setProtocols(["exampleservice"]); // For 3PID lookups
    reg.outputAsYaml("registration.yaml");
  }
}

var oi = new OI();
oi.initRegistration();

On error in onUserQuery, send back specific HTTP status and errorcode

Describe the bug
I am building an appservice. The AppService.onGetUsers returns http status 200 in the response message when an exception has occurred this.onUserQuery. Specifically, the onGetUsers method catches the exception, but does this:

// AppService.ts line 232
} catch (e) { res.send({ ... }); }.

This call sends back http status 200. The 200 status is surprising. I had expected 4xx for any exceptions or error because the request is not successful. Consequently, on the dendrite server, the rest of the logic mistakenly assumes the user query succeeded and eventually runs into other issues.

To Reproduce
Dev repro:

  1. Set up Dendrite server + appservice.
  2. Throw an exception in the implementation of onUserQuery.

Expected behavior
The catch block should return a 4xx status.

Pull request

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

Bug

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

Update readme.md

I hit an error with the registration script, that said "missing field: id"

I resolved it by adding the following line:

reg.setId("example-service");

I put it before reg.outputAsYaml("registration.yaml");

and then it all worked.

Suggest updating the readme example code with that in

AppServiceRegistration.fromObject({ ... }) -> registration.outputAsYaml fails to serialize undefined value

Using AppServiceRegistration.fromObject({ ... }) followed by registration.outputAsYaml() results in yaml serializing error about pushEphemeral being undefined. See below for full cause.

Cause

Normally pushEphemeral is set to false.

But if you use AppServiceRegistration.fromObject({ ... }), it will look for obj["de.sorunome.msc2409.push_ephemeral"] in the object you pass in. For most people, the de.sorunome.msc2409.push_ephemeral key will be undefined.

Then when you try to save the registration to a YAML file via registrationConfig.outputAsYaml(), it will fail to serialize the undefined value.

Reproduction test case

AppServiceRegistration.fromObject({
  id: bridgeId,
  hs_token: hsToken,
  as_token: asToken,
  namespaces: {
    users: [
      {
        exclusive: true,
        regex: '@gitter_.*'
      }
    ],
    aliases: [],
    rooms: []
  },
  url: bridgeUrl,
  sender_localpart: senderLocalpart,
  rate_limited: true,
  protocols: null
});

console.log('registrationConfig', registrationConfig);
/*
registrationConfig AppServiceRegistration {
  url: 'http://host.docker.internal:9000',
  id:
   'xxx',
  hsToken:
   'xxx',
  asToken:
   'xxx',
  senderLocalpart: 'gitter-badger',
  rateLimited: true,
  pushEphemeral: undefined,
  namespaces: { users: [ [Object] ], aliases: [], rooms: [] },
  protocols: null,
  cachedRegex: {} }
*/

// This throws the `Uncaught exceptionYAMLException: unacceptable kind of an object to dump [object Undefined]` error
registrationConfig.outputAsYaml('output/gitter-matrix-as-registration.yaml');

Error:

Uncaught exceptionYAMLException: unacceptable kind of an object to dump [object Undefined]
    at writeNode (C:\Users\MLM\Documents\GitHub\matrix-appservice-bridge\node_modules\js-yaml\lib\js-yaml\dumper.js:779:13)
    at writeBlockMapping (C:\Users\MLM\Documents\GitHub\matrix-appservice-bridge\node_modules\js-yaml\lib\js-yaml\dumper.js:657:10)
    at writeNode (C:\Users\MLM\Documents\GitHub\matrix-appservice-bridge\node_modules\js-yaml\lib\js-yaml\dumper.js:750:9)
    at dump (C:\Users\MLM\Documents\GitHub\matrix-appservice-bridge\node_modules\js-yaml\lib\js-yaml\dumper.js:840:7)
    at Object.safeDump (C:\Users\MLM\Documents\GitHub\matrix-appservice-bridge\node_modules\js-yaml\lib\js-yaml\dumper.js:846:10)
    at AppServiceRegistration.outputAsYaml (C:\Users\MLM\Documents\GitHub\matrix-appservice-bridge\node_modules\matrix-appservice\lib\app-service-registration.js:186:64)
    at Object.<anonymous> (C:\Users\MLM\Documents\GitLab\webapp\modules\matrix-bridge\lib\bridge.js:44:22)

Relevant code


Found while working on https://gitlab.com/gitlab-org/gitter/webapp/-/merge_requests/2040

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.