juvet / juvet Goto Github PK
View Code? Open in Web Editor NEWThe MVC framework for chat apps built on a platform designed for communication systems.
Home Page: http://juvet.io
License: MIT License
The MVC framework for chat apps built on a platform designed for communication systems.
Home Page: http://juvet.io
License: MIT License
Connecting to a Slack RTM should be done within a Connection
module.
defmodule MyConnection do
use Juvet.Connection.Slack
def handle_connect(context) do
IO.puts "Connected to #{context.connection.type}..."
{:ok, context}
end
end
A connection should handle the following:
handle_connect
handle_disconnect
handle_close
A Process that receives new messages from multiple endpoints. These are the raw messages with an origin_platform
that describes where the message came from.
This is a simple pubsub process that simply forwards messages to anything that is interested from the SlackRTM
process right now.
Create a router that can accept parameters for a block_actions
in order to route the request to a controller and action.
A single route file will be available for every Juvet application which can define routes for a Slack endpoint. Here is an example of what some actions may look like within a route file:
# lib/tatsu_bot/router.ex
defmodule TatsuBot.Router do
use Juvet.Router
platform :slack do
action "action_id", "controller#action"
end
end
The above will find a route with a request that has a type
of block_actions
and it matches the action_id
specified. Here is the documentation around the block_actions
payload: https://api.slack.com/reference/interaction-payloads/block-actions
Add a supervisor tree to the connections so a new SlackRTM
connection is created for each new connection (e.g. Slack API token) that exists.
The following should be created:
Juvet.ConnnectionFactory
-> Worker that gets added to a Juvet.ConnectionFactorySupervisor
Juvet.ConnectionSupervisor
-> Supervises workers that get created
Handle when an error is received from running Juvet.Runner
when handling a Slack command route.
I think the supervisor architecture may need to change. Currently, the archiecture is something like this:
On Startup:
[Juvet.ConnectionFactorySupervisor]
-> [Juvet.ConnectionFactory]
-> [Juvet.ConnectionSupervisor]
[Juvet.BotFactorySupervisor]
-> [Juvet.BotFactory]
-> [Juvet.BotSupervisor]
On Connecting:
[Juvet.ConnectionFactorySupervisor]
-> [Juvet.ConnectionFactory]
-> [Juvet.ConnectionSupervisor]
-> [Juvet.Connection.SlackRTM]
[Juvet.BotFactorySupervisor]
-> [Juvet.BotFactory]
-> [Juvet.BotSupervisor]
-> [tatsuio (Juvet.Bot.Server)]
It would be nice to connect each connection to the bot so a bot may have supervise multiple connections so if one goes down, they can be restarted by the bot that has the state.
Also, we should research the architecture a bit to see if the Factory workers are needed to be under the FactorySupervisor or if those can just be stand alone processes. If they can be standalone processes, we should rename the FactorySupervisor processes.
Setup CI using GitHub actions so the library is built on every merge into main
as well as all new pull requests.
The connections, bot processes, and bots should have an organized Juvet.State.Slack
state struct that holds onto the state when the connection initially connects.
platform
connection_id
(e.g. in Slack, this would be the team id)Wrap Slack's IM.Open so bot's can open a direct message with a user.
The connections, bot processes, and bots should have an organized Juvet.State.Slack state struct that holds onto the state when the connection initially connects.
Allow a client to configure the verifying of requests for Slack.
A user should be able to:
Allow for the rtm.start method to be called instead of the rtm.connect method.
The start method is heavier weight because it returns much more state but some may opt to use it. This should be passed in as config but it would also be nice to config it on a per Slack bot basis.
The user should be able to specify the middleware that gets run when a route is identified and then run.
Should work similar to GraphQL
"base middleware".
Update the Juvet.Middleware
module so the MiddlewareProcessor
can retrieve the correct middleware.
Allow client applications to handle errors.
This would allow custom error handlers and handle hard-coded errors like https://github.com/juvet/juvet/blob/main/lib/juvet/plug.ex#L32.
Refer to Plug.ErrorHandler
Juvet should handle the intricacies of oauthing with Slack (and future providers like MS Teams and Amazon). This will allow the setup of a bot within a particular framework easier and built in.
request
and callback
routes through the SlackEndpointRouter
via a SlackAuthenticationRouter
and allow them to be overridenauthorize_url
with configured scopes, app identifiers and secretsauthorize_url
should be available publically within the OAuth libraryAccess
callback which gets the token, an Authenticating
callback which creates the bot and installs the user and bot, and an Authenticated
callback which is called after the bot is installed (can be a callback on the bot).SlackAuthenticationRouter
handler should be a one line call so it can easily be called in overridden callbacksCreate a module that allows a client to easily extract the submission values from a submission payload:
Juvet.Slack.View.values(payload)
This would extract a view payload like the following:
{
payload: {
type: "view_submission",
view: {
state: {
values: {
"block_id" => {
"my_action" => {
type: "plain_text_input",
value: "my value"
}
}
}
}
}
}
}
And would return the following:
%{
"my_action" => "my value"
}
Create a behavior or module that can be injected into custom bots to help outside implementors create a bot.
defmodule MyBot do
use Juvet.Bot
def handle_message(:slack, %{type: "message"} = message) do
#...
send_message(:slack, %{})...
end
end
Called when a user authenticates with Juvet.
def user_install(bot, platform, payload)
end
# USAGE: Juvet.BotFactory.find_or_create(auth.team.team_name) |> MyBot.user_install(:slack, auth)
# Juvet.find_or_create_bot could be a shortcut
This method runs through a series of behavior callbacks which will perform the following:
mounted
callback if started -> maybe called when the bot is created?authenticated
callbackinstalled
callbackfailed_authentication
callback if the auth failedsignup
if user is newsignin
if user is existing{ team: { name: "Tatsu", identifiers: [{ slack: "T12345" }, { facebook: "" }] } }
{ user: { name: "Jimmy Page", identifiers: [{ slack: "T12345/U12345" }, { facebook: "" }] } }
Juvet.create_bot!/1
, Juvet.connect_bot!/3
and Juvet.start_bot!/3
because Juvet.user_install/3
would be the next logical step and it does what connect_bot!
does.Wrap the Slack API method of team.info so it can be used to retrieve information about a user based on the user id.
Create a router that can accept parameters for a command in order to route the request to a controller and action.
A single route file will be available for every Juvet application which can define routes for a Slack endpoint. Here is an example of what some commands may look like within a route file:
# lib/tatsu_bot/router.ex
defmodule TatsuBot.Router do
use Juvet.Router
platform :slack do
command :start, MeetingController, :start
end
end
I think the supervisor architecture may need to change. Currently, the archiecture is something like this:
On Startup:
[Juvet.ConnectionFactorySupervisor
]
-> [Juvet.ConnectionFactory
]
-> [Juvet.ConnectionSupervisor
]
[Juvet.BotFactorySupervisor
]
-> [Juvet.BotFactory
]
-> [Juvet.BotSupervisor
]
On Connecting:
[Juvet.ConnectionFactorySupervisor
]
-> [Juvet.ConnectionFactory
]
-> [Juvet.ConnectionSupervisor
]
-> [Juvet.Connection.SlackRTM
]
[Juvet.BotFactorySupervisor
]
-> [Juvet.BotFactory
]
-> [Juvet.BotSupervisor
]
-> [tatsuio (Juvet.Bot.Server
)]
It would be nice to connect each connection to the bot so a bot may have supervise multiple connections so if one goes down, they can be restarted by the bot that has the state.
Also, we should research the architecture a bit to see if the Factory
workers are needed to be under the FactorySupervisor
or if those can just be stand alone processes. If they can be standalone processes, we should rename the FactorySupervisor
processes.
Allow for the rtm.start
method to be called instead of the rtm.connect
method.
The start
method is heavier weight because it returns much more state but some may opt to use it. This should be passed in as config but it would also be nice to config it on a per Slack bot basis.
Adding Juvet to an application should not on it's own start it's own Plug.Router
as that is another HTTP endpoint that has to be managed in the deployed application's environment.
Since most bot applications are going to have their own web presence, Juvet should expose the Plug.Router
that can be mounted inside another application like so:
defmodule Web.Router do
use Plug.Router
forward "/slack", to: Juvet.EndpointRouter
end
This should not start the Juvet.Endpoint
supervisor as Juvet itself does not need to start a Cowboy plug. Future options may allow for a standalone bot instance that does not have an endpoint
Upgrade the current Elixir version (1.10
) to the newest version (1.13
).
Juvet.GregorianDateTime
: https://hexdocs.pm/elixir/1.13.1/DateTime.html#from_gregorian_seconds/3Create a mix task that will easily create ExVCR cassettes for the Slack endpoints.
CI should be setup so it is run and the GitHub Checks API checks and secures the master branch. CircleCI is preferred.
It would allow dealing with finding platforms based on their name.
Replace:
Process that is used to create bots based on various messages that are received. This bot factory should have child processes for all of the bot children it creates.
It listens for the following messages:
new_slack_connection
-> Creates a new bot process for the specified teamWrap the Slack API method of users.info so it can be used to retrieve information about a user based on the user id.
The SlackAPI
is lacking some basic Slack API communication. These upgrades need to be made:
POST
for the requests instead of using GET
content-type
of application/x-www-form-urlencoded
SlackAPI.request_params/1
and just use a Map
(which should be handled by HTTPoison
)The bot behavior should have a send_message
function that can send text or a Map to Slack via the SlackRTM
connection.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.