Coder Social home page Coder Social logo

ssube / isolex Goto Github PK

View Code? Open in Web Editor NEW
17.0 4.0 7.0 7.49 MB

Chat bot able to speak natural language and markup, prompt to complete commands, and offer localized help. Configured with schema-validated YAML, features JWT authentication with granular RBAC, and SQL persistence.

License: MIT License

Makefile 1.37% JavaScript 0.95% TypeScript 96.67% Shell 1.01%
typescript chatbot aws-lex slack-bot discord-bot kubernetes chatops bot github-bot gitlab-bot

isolex's People

Contributors

dependabot[bot] avatar greenkeeper[bot] avatar isolex[bot] avatar kamilczak020 avatar renovate-bot avatar renovate[bot] avatar snyk-bot avatar ssube avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar

isolex's Issues

add labels to metadata

Summary

Services should keep a Dict<string> of labels in their metadata and use them to filter transforms, select parsers, and do other clever things.

Scope

  • add labels to:
    • Service and/or BaseService
    • Command
    • Message
  • write a label matching class (#31)
    • exact string
    • includes
    • regex
  • update Controllers

make dates an injected dependency

Summary

Dates are terrible and timezones will be worse. In a feeble effort to head that off, make sure everything date-related is injected via DI, and don't use Date.now.

Scope

  • inject Date or something

Use Case

Tokens need to the current date to sign and verify.

reset counters on sigint

Summary

Controllers, filters, the bot, and numerous other services have ephemeral state: counters, bans, filter state, etc. Providing a signal to reset these.

Scope

  • listen to sigint
  • add reset method to service
  • implement reset

Use Case

Reset counters and filters for testing.

move graph impl to its own module

The graph implementation is currently part of the express listener. This bloats the listener and overly couples them, along with making the graph (de)serialization methods difficult to test.

  • move the graph code into its own src/graph path
  • create graph types for all entities
    • input
      • channel
      • context
      • command
      • message
    • output
      • role
      • user
      • channel
      • context
      • fragment
      • command
      • message
      • service
  • add a graph entrypoint for use with express-graphql
  • update the express listener to instantiate that
  • check nullable/non types

update lex parser

Summary

Lex's NLP is a very important part of the bot. Make sure the parser is working, intents become nouns and verbs, slots are mapped correctly, and completion handled.

Scope

v1:

  • message parsing
  • pass uid
  • intent split into noun/verb
  • slots mapped to cmd data
  • completion from lex
  • document lex model
    • intent requirements
    • slots and completion

v2:

  • user session data (context data? cmd/msg data?)

confusing parser errors on custom types

Summary

The YAML parser does not report very helpful errors when an env var or file is missing.

Steps to Reproduce

Parse a config file with an !env and no corresponding variable or !include and a missing/invalid path.

Actual Behavior

> make run-terminal                                                                                             
node /home/ssube/code/isolex//out/main-bundle.js    
(node:609) ExperimentalWarning: The fs.promises API is experimental
uncaught error during main: { YAMLException: cannot resolve a node with !<!include> explicit tag at line 18, column 80:
     ... troller/kubernees-controller.yml
                                         ^
    at generateError (/home/ssube/code/isolex/node_modules/js-yaml/lib/js-yaml/loader.js:165:1)
    at throwError (/home/ssube/code/isolex/node_modules/js-yaml/lib/js-yaml/loader.js:171:1)
    at composeNode (/home/ssube/code/isolex/node_modules/js-yaml/lib/js-yaml/loader.js:1393:1)
    at readBlockSequence (/home/ssube/code/isolex/node_modules/js-yaml/lib/js-yaml/loader.js:928:1)
    at composeNode (/home/ssube/code/isolex/node_modules/js-yaml/lib/js-yaml/loader.js:1331:1)
    at readBlockMapping (/home/ssube/code/isolex/node_modules/js-yaml/lib/js-yaml/loader.js:1062:1)
    at composeNode (/home/ssube/code/isolex/node_modules/js-yaml/lib/js-yaml/loader.js:1332:1)
    at readBlockMapping (/home/ssube/code/isolex/node_modules/js-yaml/lib/js-yaml/loader.js:1062:1)
    at composeNode (/home/ssube/code/isolex/node_modules/js-yaml/lib/js-yaml/loader.js:1332:1)
    at readDocument (/home/ssube/code/isolex/node_modules/js-yaml/lib/js-yaml/loader.js:1492:1)
    at loadDocuments (/home/ssube/code/isolex/node_modules/js-yaml/lib/js-yaml/loader.js:1548:1)
    at load (/home/ssube/code/isolex/node_modules/js-yaml/lib/js-yaml/loader.js:1569:1)
    at safeLoad (/home/ssube/code/isolex/node_modules/js-yaml/lib/js-yaml/loader.js:1591:1)
    at readConfig (/home/ssube/code/isolex/src/config/index.ts:63:20)
  name: 'YAMLException',
  reason: 'cannot resolve a node with !<!include> explicit tag',

Expected Behavior

> make run-terminal                                                                                             
node /home/ssube/code/isolex//out/main-bundle.js    
(node:609) ExperimentalWarning: The fs.promises API is experimental
uncaught error during main: !include file did not exist

Details

Both types have resolve methods that check whether the variable or file exists. If those return false, the parser throws the above.

  • fix errors for !env
  • fix errors for !include

auth controller permissions

Summary

Users belong to Groups, which have Roles, which are granted permissions (or scopes). The AuthController should be able to compile the list of applicable permissions for a particular User and check to make sure a list of permissions are all present.

Scope

  • permission
    • compile (from user, roles, etc)
    • check
  • permission
    • get
    • list
  • role
    • get
    • list
    • create
  • user
    • get
    • create
    • update

Use Case

The k8s controllers should require permissions to scale or update resources.

The auth controller should require permissions to edit users, issue tokens, etc.

Issues

Need to resolve the full set of roles that apply to a user and compile their permissions in a semi-performant way. Maybe look at TypeORM caching (redis?).

Details

Use shiro-trie for permission tests.

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on Greenkeeper branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please click the 'fix repo' button on account.greenkeeper.io.

auth controller

Summary

Add an authentication and authorization controller.

Scope

v1:

  • user
    • create
  • session
    • create
    • context

Use Case

Some commands and controllers, like k8s and gitlab, should be access-controlled.

Issues

Will require new entities for role, token, and user. No utils for permissions or tries.

Details

Users should be attached to Roles, which are granted Scopes.

Permissions should use a Shiro-like trie structure, with foo:bar indicating each scope and following a noun:verb:args convention.

Listeners should have a way to associate a user ID/tag/snowflake with a session, in place of cookies or a token header, so users remain logged into the bot from Discord/Slack until their token expires.

remove articles from pick handler data

Summary

!!pick this or that could return any of [this, or, that]. That's not usually what you want.

Scope

  • add a Checklist to the PickHandler
  • filters items based on the list

counter handler

Summary

Add a handler that uses the database to store a counter.

Scope

  • store a key and numeric value
  • increment, decrement, and reset commands

Use Case

User rep, message stars, etc.

Details

It would be pretty cool if reactions could be used as rep/star triggers.

matchers and rules

Summary

In order to implement conditional transforms, select anything by label, or implement rule-based filters, we need matchers and rules.

Take an example of a pod that uses pod affinity:

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        topologyKey: failure-domain.beta.kubernetes.io/zone
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - S2
          topologyKey: kubernetes.io/hostname

This provides a weighted set of rules to match data (in this case, labels). Revising that slightly with isolex terminology:

metadata:
  kind: template-transform
  name: with-pod-affinity
  scope: foo
data:
  matches:
    - key: security
      operator: In
      values:
        - S1

Scope

  • config schema
  • matching utility class
    • string matches
    • regex matches
    • every operator
    • any operator
    • negate flag

Use Case

  1. Matching labels
  2. Conditional transforms
  3. Filtering messages
  4. Everything else with rules

Issues

Total rabbit hole. Implement operators as needed.

Details

Should be a utility class and some operators.

include git info in logs

Summary

The bot should print its version when it starts up.

Scope

v1:

  • print git info (commit hash, branch)
  • print build info (runner, pod, node, webpack)

v2:

  • print friendly version

Use Case

Logs.

Issues

Requires changes to the webpack config to read variables from the makefile.

slack listener

Summary

Add a listener for https://slack.com/

Scope

v1:

  • implement a Listener for Slack with:
    • incoming messages
    • outgoing messages
    • incoming reactions
      • with message
      • after message
    • sessions

v2:

  • outgoing reactions

Use Case

Necessary for work use.

Issues

The RTM client used to receive messages cannot search and may not be able to send all of the messages supported by the bot. Look at using the web client as well.

reload config on sighup

Summary

Daemons traditionally reload their configuration and reload when they receive a SIGHUP signal. Support this.

Scope

  • reload config with existing args
  • restart or recreate services

Use Case

Easy reloads when testing.
Managed/sidecar reloads in controlled pod.

Issues

Do services all handle stopping and starting over correctly? Will they be destroyed and reconnect (most likely)?

configure allowed command names for learn controller

Summary

The learn controller should take the command name from user input, but for security purposes, should filter commands before saving.

Scope

v1:

  • verify noun/verb before saving
  • verify noun/verb before executing
  • ensure noun/verb can be set in saved

Use Case

Prevent learned commands for a privileged controller.

expose prometheus metrics

Summary

The bot does many things and there should be a way to keep track of them. Since the bot can expose an HTTP API, that would be a great place to put Prometheus metrics. Do that.

Scope

  • basic prometheus metrics
  • add necessary bit to DI
  • begin adding metrics
    • bot commands
    • bot messages
    • express requests

Use Case

Monitoring the bot, making sure it hasn't crashed, sweet graphs, etc.

Issues

Clustering will be interesting.

The prom-client registry will need to be injected into anything which might report metrics.

Details

Need a library for metrics: https://github.com/siimon/prom-client

initial and reset tokens

Summary

Users do not and should not have passwords. Instead, upon signing up, an initial token is created with the session:create grant (and nothing else). This login token is used to log in, containing the uid and name. Login tokens should expire after a long time (30-90 days) and be treated like passwords. Users should be told in no uncertain terms to keep the login token in their password manager.

A "password reset" means deleting all existing tokens for a user, including their login token, and immediately (transactionally, even) issuing a new login token. This replaces all existing tokens and can be used to re-issue others.

Scope

  • figure out which controller handles this
  • sign up should create user and token
  • sign in should take token
  • reset should delete existing tokens and create new login token

Use Case

Implementing passwords opens up a million security concerns. Without passwords, most of them don't exist.

Security for tokens relies largely on the secrecy of the secretOrKey used to sign them. This is taken from config, meaning it can be an !env variable or !included from a mounted kind: Secret.

Issues

Ensure users cannot get stuck without a login token.

Details

Add anonymous roles (roles for an anonymous user) to the session controller. Any context without a user should be given these roles and their grants. Default to session:create and user:create, most likely.

In some controller, implement the sign up flow (create user, create token, reply with token) and reset flow (delete tokens, create token, reply with token). The sign in flow is already in session ctrl. Group these three and write some tests.

github comment listener

Summary

Github conveniently uses threaded issues and PRs, matching the bot's message neatly. It should be possible to set up a request-and-webhook based listener.

Scope

  • poll for new comments
  • create issue comments

v2:

  • listen to webhooks via extension API
  • create PR comments

Use Case

Using the bot to manage issue and PR workflows.

Issues

Needs #68 and a Github client.

break up auth ctrl

Summary

The auth controller is handling too many different nouns and has become too large. It's setting off a few different lint warnings:

  • file too long
  • too many methods

Scope

  • move tokens to their own controllers (tokens verify themselves)
  • move users and roles to their own controller (rbac)
  • leaving only sessions and permissions (seems ok)

build and publish releases

Summary

Having a consistent build and test process (or better, command) is a necessary part of every project. Having a reliable CI process and automatic packaging is also quite useful. Make that happen.

Scope

  • build the app in strict mode
    • fail on any typescript errors
    • consider failing on lint errors (means silencing all the webpack dynamic imports)
  • publish an npm package
    • ensure the .npmignore is correct
    • add credentials to the project secrets
    • add that user to the package
    • publish on tags
  • publish a docker image
    • ensure the docker ignore and dockerfile are correct
    • add credentials
    • add that user
    • publish on tags

Use Case

Nobody can use it without releases, not even me.

k8s controller for apps resources

Summary

Add support for apps/v1 resources to the k8s controller.

Scope

  • rename existing k8s controller to core
  • apps/v1
    • stateful
      • get
      • update
        • replicas
    • daemon
      • get
    • deploy
      • get
      • update
        • replicas

Use Case

Scale applications up and down, get their status.

Issues

The k8s controller will be many and varied, probably needing some common helpers (at least to set up the client and load context).

Details

k8s client is already installed.

make bot smaller

The bot file/class has been flagged by codeclimate as being too long, multiple methods as being too complex, and overall poor quality. This is absolutely a god class with a service locator mixed in. Fix it!

https://codeclimate.com/github/ssube/isolex/src/Bot.ts?strict=false&to_sha=56c871bf2074199f182dec3e8cfb032edd3e47f3

  • service data/option types
    • two service types (filter, listener) are missing their own options, leading to <Foo, {}> types when creating them
    • filter options
    • listener options
  • instance checks
    • there are two clumsy instance checks inside a loop, which should not be necessary
    • command check
    • message check
  • cognitive complexity
    • there are some ugly, complicated methods that need to be simplified
    • receive
    • startServices
  • overall length
    • the Bot itself is too long by a few lines, split parts out
    • service locator

refactor to k8s-style resources

Resources follow somewhat standard forms, but mix and match standard fields with configuration. This leads to complex types (some impossible to enforce) and endless reserved names. Kubernetes fixed this quite cleanly:

metadata:
  apiVersion: v1
  kind: Pod
  name: foo
  labels:
    bar: a
    bin: b
data:
  # actual body

Breaking out the metadata will allow easy definition of service definitions, better registration, and eventually tagging. It should also ease nesting and linking.

This will be a large refactor and needs to:

  • add Transform services

    • wire up to controllers
  • refactor Command (these are commands, not objects)

    • name to noun
    • type to verb
  • standardize some junk:

    • Config vs Data naming
    • emit config block (partial Command)
    • msg/msgs vs message/messages
    • other naming issues
  • document naming conventions

  • figure out:

    • tracking services from Context (any service that interacted with it?)

auth controller tokens

Summary

The AuthController should be able to issue, save, and (in)validate tokens.

Scope

  • token
    • issue
    • get (current)
    • list (current user)
    • delete (invalidate)
    • get (validate provided)

Use Case

API access via the express listener.

Issues

Need permissions in place first.

Need verbs for (in)validate.

Details

Token entity exists, fields map to JWT claims. Issue JWTs with permissions as scopes and validate.

learn controller should save target command name

Summary

The learn controller currently takes the command name as a run parameter. That requires anyone running the command to know what noun they are targeting, which is often asking too much.

Scope

  • make sure trigger entities save a command name
  • optionally interpret the first argument as the destination command name
  • keep the first argument when merging data

Use Case

Running a command without knowing the bot's config.

Issues

Breaking change for the learn controller (not much use yet, probably thanks to this issue).

consistent durations in config

Summary

The same way emit: always has CommandOptions to create a new command, intervals and durations should be standardized to support both cron and zeit (10s, 3 minutes, etc) expressions.

Scope

  • duration interfaces
  • emit seconds
  • set second/ms intervals

documentation via help verb

Summary

Each service instance should provide some structured documentation, fetched with the help verb, that can be used to build command line and web pages.

Scope

v1:

  • handlers for help verb
  • graphql help field
    • on services
  • internationalization
    • error messages
    • normal replies
    • help replies

Use Case

This isn't golang; documentation matters.

entity map helpers

There are a few entities with a Map property, which typeorm does not handle correctly through the simple-json type.

Currently this is handled with a protected shadowStr: string property and a pair of methods:

  @AfterLoad()
  public syncMap() {
    this.data = new Map(JSON.parse(this.dataStr));
    this.labels = new Map(JSON.parse(this.labelStr));
  }

  @BeforeInsert()
  @BeforeUpdate()
  public syncStr() {
    this.dataStr = JSON.stringify(Array.from(this.data));
    this.labelStr = JSON.stringify(Array.from(this.labels));
  }

These do not scale well to multiple fields. Turn them into helpers, base classes, or something.

  • data entity
  • labeled entity (labeled data? is data always present or vice versa?)
  • base command (shared by command and fragment)

gRPC handler

Summary

To support efficient calls to remote services, add a gRPC handler.

Scope

  • protobuf for each entity
    • command
    • message
  • grpc handler

Use Case

Safely executing code requires a strong sandbox. Running a gRPC server in that sandbox provides primarily-one-way communication. Since any language might be running the code and server, the method must be widely compatible.

Issues

afaik gRPC generates interfaces and shell classes from the protobuf layouts, which would have to be integrated into the make/webpack process.

Details

The gRPC library has a number of native components, but was added to package.json a while ago.

args parser

Summary

Add a parser that can handle CLI arguments: --foo --bar=3. Convert to a Map<string, Array<string>> suitable for cmds and msgs.

Scope

  • find a good cli parser
  • parse startup arguments & merge w/ config
  • cli args Parser class
  • schema

Use Case

CLI args are a well-known way of providing named text options, perfect for this use case. Unlike the split parser, args can handle named arguments and array values.

Issues

Need to find a good CLI library.

include relative paths

Summary

Not all include paths are absolute. Relative paths should use the existing config lookup logic and priority.

Scope

  • !include path without leading / should use config lookup logic

Use Case

Loading the database a relative directory, keeping the reference config portable.

trigger commands on reactions

Summary

Reactions should appear in the listener's stream as messages from the user, with the reaction emoji as the body. The message should otherwise be normal.

This should allow reactions (or any use of the emoji) to trigger a normal command for the bot.

Scope

v1:

  • discord listener should emit message for new reactions
  • differentiate reaction emojis from normal message body emojis
    • reaction will be entire body?

v2:

  • slack listener also

Use Case

Send increment/decrement commands to the counter handler.

Issues

Need to make sure emojis mid-sentence don't trigger rep changes.

Details

Requires #10

parser cmd helper

Summary

Parsers almost always create a Command, but some need the noun/verb configured and some take dynamic values. Some even switch depending on their config. Writer a helper to encapsulate that logic.

Scope

  • rename config emit stanza
  • add dynamic noun/verb to config
  • write helper to switch noun/verb

Use Case

Every parser does this or should.

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please delete the greenkeeper/initial branch in this repository, and then remove and re-add this repository to the Greenkeeper App’s white list on Github. You'll find this list on your repo or organization’s settings page, under Installed GitHub Apps.

remove entity create methods

Summary

The various entity create(data) static methods are leading to a lot of duplication. Unlike reply, emit, and some of the other helpers, they take the full FooData object. The Data and Options for each entity (unlike services) could be merged, meaning they're not actually Data and Options to begin with (most likely just Options). To merge those, mark context and the like as optional (they are, esp in the GraphQL schema). That should allow the create methods to be removed.

move service lifecycle to module

Summary

The Bot is currently acting as a service locator and manager for itself and every other service. This should be implemented in a DI module that tracks (starts and stops) services on behalf of the bot. This module will have some helpers to create/get services within the bot's managed scope, much like the prometheus registry for metrics.

Scope

  • add service locator module
  • manage service lifecycle from the bot, through the module
  • move createService and getService methods
  • add kind/name search to getService (along with id)

Use Case

The bot is getting too big (#37).

lifecycle events

Summary

The bot should be able to emit commands on lifecycle events.

Scope

  • bot
    • start
    • stop
    • reload (sighup)
    • reset (sigint)

Use Case

The bot should announce when it updates.

Issues

None

Details

Add git info to the webpack bundle, to use when announcing start.

bot may not shut down cleanly on signals

Summary

When shutting down the bot via signal (SIGINT or SIGTERM) it may throw an error. It should shut down cleanly, closing all resources in a controlled manner.

Steps to Reproduce

  • run the bot
  • shut it down via signal
  • :(

Actual Behavior

Error [ERR_UNHANDLED_ERROR]: Unhandled error. ([object Object])
    at Client.emit (events.js:171:17)
    at Client.EventEmitter.emit (domain.js:442:20)
    at WebSocketConnection.onError (/build/src/git.apextoaster.com/ssube/isolex/node_modules/discord.js/src/client/websocket/WebSocketConnection.js:374:1)
    at WebSocket.onError (/build/src/git.apextoaster.com/ssube/isolex/node_modules/discord.js/node_modules/ws/lib/event-target.js:128:1)
    at WebSocket.emit (events.js:182:13)
    at WebSocket.EventEmitter.emit (domain.js:442:20)
    at _receiver.cleanup (/build/src/git.apextoaster.com/ssube/isolex/node_modules/discord.js/node_modules/ws/lib/websocket.js:211:1)
    at Receiver.cleanup (/build/src/git.apextoaster.com/ssube/isolex/node_modules/discord.js/node_modules/ws/lib/receiver.js:557:1)
    at WebSocket.finalize (/build/src/git.apextoaster.com/ssube/isolex/node_modules/discord.js/node_modules/ws/lib/websocket.js:206:1)
    at TLSSocket.emit (events.js:182:13)
    at TLSSocket.EventEmitter.emit (domain.js:442:20)
    at emitErrorNT (internal/streams/destroy.js:82:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
    at process._tickCallback (internal/process/next_tick.js:63:19)

Expected Behavior

Clean shutdown logs.

Details

The Discord listener and/or other services are not being cleaned up properly.

document example use cases

Summary

Write docs for a bunch of common use cases. Include examples, refer to config, and everything necessary to run the example by pasting.

Scope

Readme:

  • badges
  • build
  • getting started

Getting Started:

  • intro
  • concepts
    • messages
    • commands (noun/verb)
  • dev
    • build
    • config
    • secrets
  • security
    • setup
    • tokens
    • grants

Auth:

  • sign up
    • deps
      • session ctrl
      • account:create
      • token entity
      • user entity
    • steps
      • create user
      • explain jwt
      • save initial token in password manager
  • sign in
    • deps
      • session ctrl
      • session:create
    • steps
      • log in with token
      • check grants
  • sign out
    • deps
      • session ctrl
      • account:delete
    • steps
      • revoke tokens
      • confirm
      • save new token

Code:

  • scale up k8s app
    • deps
      • k8s apps ctrl (#32)
      • k8s pod ctrl (#8)
      • pod:list
      • deployment:get
      • deployment:update
    • steps
      • list pods in namespace
      • get deployment
      • set deployment scale
      • list pods again
  • start gitlab job
    • deps
      • gitlab ci ctrl (pipeline & job, #71)
      • pipeline:create
      • pipeline:get
    • steps
      • start pipeline for project
      • check status
  • merge github PR
    • deps
      • github PR ctrl (#72)
      • github-pull-request:get
      • github-pull-request:update
    • steps
      • get PR changes
      • approve PR
      • merge or close PR

Chat:

  • add reaction to messages
    • deps
      • reaction ctrl
      • discord fetch
      • slack fetch
      • slack reactions
    • steps
      • post
      • react
  • solve math
    • deps
      • math ctrl
    • steps
      • solve
  • roll dice
    • deps
      • dice ctrl
    • steps
      • roll
  • learn command
    • deps
      • learn ctrl
    • steps
      • learn command
      • list commands
      • execute command w/ data

Help:

  • get controller help
    • list nouns (#70)
    • noun details
    • verb details

Use Case

People should be able to set the bot up, log in, and do a few things without ever typing an original command (pasting only). That entire process, from cloning to reactions, should exist in a single doc. Too many projects omit that guide.

database migrations

Summary

The database stores triggers and some other useful features, but there is no good way to update it (yet).

Scope

  • database migrations on or before the bot starts

Use Case

Schema changes require migrations or losing the database, which is bad.

Issues

The bot itself doesn't have connection info until it has loaded config. It would be possible to run migrations at that point, but should be optional (for clustered bots, testing, etc).

TypeORM has a system for migrations, but I'm not sure that will work with the build.

express listener sessions

Summary

The express (http) listener needs to support sessions and attach them to context. This will mostly use the existing session provider class (via auth controller), but HTTP differs from existing chat listeners because users do not remain connected. HTTP has ways to fix that: headers and cookies (a header).

Scope

v1:

  • session from token header
  • ensure session is passed to graph methods

Use Case

Webhooks should be able to authenticate.

Issues

No support for tokens yet (besides the entity).

Need to pass context to the graph methods.

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on Greenkeeper branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please click the 'fix repo' button on account.greenkeeper.io.

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on Greenkeeper branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please click the 'fix repo' button on account.greenkeeper.io.

gitlab comment listener

Summary

Gitlab conveniently uses threaded issues and MRs, matching the bot's message neatly. It should be possible to set up a request-and-webhook based listener.

Scope

  • listen to webhooks via extension api
  • create issue comments
  • create MR comments
  • check for new comments

Use Case

Using the bot to manage issue and MR workflows.

Issues

Requires #68 and a Gitlab client.

express listener

Summary

The bot should have an HTTP/S API for webhooks, debugging, and all sorts of other reasons.

Scope

  • listener
    • graph endpoint
      • mutation
        • emit commands
        • send messages
      • query
        • command
        • message
        • service
        • services

Use Case

Webhooks.

Issues

Binding to all of the data will take some changes.

No way to feed messages (replies) from a request back to the response, unless the listener can link the two method calls (receiveMessage and sendMessage).

Details

Need to install express and graphql.

missing reaction emojis in dscord may crash the bot

Summary

A reaction with an standard emoji (not a custom discord emoji) that is not preset in the emoji library will crash the bot.

Steps to Reproduce

  • react with an emoji
  • use the wrong one
  • ...
  • :(

Actual Behavior

/build/src/git.apextoaster.com/ssube/isolex/src/listener/DiscordListener.ts:170
      msg.body = emoji.find(reaction.emoji.toString()).key;
                                                      ^
TypeError: Cannot read property 'key' of undefined
    at DiscordListener.convertReaction (/build/src/git.apextoaster.com/ssube/isolex/src/listener/DiscordListener.ts:170:55)
    at Client.client.on (/build/src/git.apextoaster.com/ssube/isolex/src/listener/DiscordListener.ts:44:25)
    at Client.emit (events.js:182:13)
    at Client.EventEmitter.emit (domain.js:442:20)
    at MessageReactionAdd.handle (/build/src/git.apextoaster.com/ssube/isolex/node_modules/discord.js/src/client/actions/MessageReactionAdd.js:24:1)
    at MessageReactionAddHandler.handle (/build/src/git.apextoaster.com/ssube/isolex/node_modules/discord.js/src/client/websocket/packets/handlers/MessageReactionAdd.js:7:1)
    at WebSocketPacketManager.handle (/build/src/git.apextoaster.com/ssube/isolex/node_modules/discord.js/src/client/websocket/packets/WebSocketPacketManager.js:103:1)
    at WebSocketConnection.onPacket (/build/src/git.apextoaster.com/ssube/isolex/node_modules/discord.js/src/client/websocket/WebSocketConnection.js:333:1)
    at WebSocketConnection.onMessage (/build/src/git.apextoaster.com/ssube/isolex/node_modules/discord.js/src/client/websocket/WebSocketConnection.js:296:1)
    at WebSocket.onMessage (/build/src/git.apextoaster.com/ssube/isolex/node_modules/discord.js/node_modules/ws/lib/event-target.js:120:1)
    at WebSocket.emit (events.js:182:13)
    at WebSocket.EventEmitter.emit (domain.js:442:20)
    at Receiver._receiver.onmessage (/build/src/git.apextoaster.com/ssube/isolex/node_modules/discord.js/node_modules/ws/lib/websocket.js:137:1)
    at Receiver.dataMessage (/build/src/git.apextoaster.com/ssube/isolex/node_modules/discord.js/node_modules/ws/lib/receiver.js:409:1)
    at Receiver.getData (/build/src/git.apextoaster.com/ssube/isolex/node_modules/discord.js/node_modules/ws/lib/receiver.js:347:1)
    at Receiver.startLoop (/build/src/git.apextoaster.com/ssube/isolex/node_modules/discord.js/node_modules/ws/lib/receiver.js:143:1)
    at Receiver.add (/build/src/git.apextoaster.com/ssube/isolex/node_modules/discord.js/node_modules/ws/lib/receiver.js:117:1)
    at TLSSocket.emit (events.js:182:13)
    at TLSSocket.EventEmitter.emit (domain.js:442:20)
    at addChunk (_stream_readable.js:277:12)
    at readableAddChunk (_stream_readable.js:262:11)
    at TLSSocket.Readable.push (_stream_readable.js:217:10)

Expected Behavior

The bot should continue running but skip the reaction or use a default emoji/message.

Details

This is caused by the convertMessage and convertReaction calls in the DiscordListener throwing while outside of the async error handler.

validate config after loading

Summary

Most of the services assume the config will be present and valid. Usually this leads to nice, clean something is undefined errors (with mediocre stack traces), but properly validating the config and getting useful errors would be awful nice.

Scope

  • services should provide json schema snippet
  • validate config against schema
  • break with useful errors

Use Case

Good errors are good.

Issues

Getting validation snippets from each service without instantiating them will be interesting.

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.