First version
This commit is contained in:
parent
fc2efe3988
commit
fcc76b05ca
18 changed files with 264 additions and 32013 deletions
248
server/plugin.go
248
server/plugin.go
|
@ -1,11 +1,15 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/plugin"
|
||||
pluginapi "github.com/mattermost/mattermost/server/public/pluginapi"
|
||||
)
|
||||
|
||||
// Plugin implements the interface expected by the Mattermost server to communicate between the server and plugin processes.
|
||||
|
@ -18,11 +22,249 @@ type Plugin struct {
|
|||
// configuration is the active plugin configuration. Consult getConfiguration and
|
||||
// setConfiguration for usage.
|
||||
configuration *configuration
|
||||
|
||||
apiClient *pluginapi.Client
|
||||
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
// ServeHTTP demonstrates a plugin that handles HTTP requests by greeting the world.
|
||||
func (p *Plugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprint(w, "Hello, world!")
|
||||
// func (p *Plugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) {
|
||||
// fmt.Fprint(w, "Hello, world!")
|
||||
// }
|
||||
|
||||
func (p *Plugin) Q() sq.StatementBuilderType {
|
||||
return sq.StatementBuilder.PlaceholderFormat(sq.Dollar).RunWith(p.db)
|
||||
}
|
||||
|
||||
func (p *Plugin) OnActivate() error {
|
||||
p.apiClient = pluginapi.NewClient(p.API, p.Driver)
|
||||
|
||||
db, dbErr := p.apiClient.Store.GetMasterDB()
|
||||
if dbErr != nil {
|
||||
return dbErr
|
||||
}
|
||||
p.db = db
|
||||
|
||||
if err := p.API.UnregisterCommand("", "fawkes"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
autocompleteData := model.NewAutocompleteData("fawkes", "[command]", "Gets information about the msteams current state")
|
||||
|
||||
whitelistedCmd := model.NewAutocompleteData("count-whitelisted", "", "Counts the amount of whitelisted users in msteamssync_whitelisted_users")
|
||||
// adds the from arg?
|
||||
autocompleteData.AddCommand(whitelistedCmd)
|
||||
|
||||
lastConnectAtCmd := model.NewAutocompleteData("count-lastconnectat", "", "Counts the amount of users with a lastconnectat value != 0 in msteamssync_whitelisted_users")
|
||||
autocompleteData.AddCommand(lastConnectAtCmd)
|
||||
|
||||
lastDisconnectAtCmd := model.NewAutocompleteData("count-lastdisconnectat", "", "Counts the amount of users with a lastdisconnectat value != 0 in msteamssync_whitelisted_users")
|
||||
autocompleteData.AddCommand(lastDisconnectAtCmd)
|
||||
|
||||
userInfoCmd := model.NewAutocompleteData("user-info", "[username|email]", "Returns information about the user state regarding msteams")
|
||||
autocompleteData.AddCommand(userInfoCmd)
|
||||
|
||||
channelInfoCmd := model.NewAutocompleteData("channel-info", "[channelID]", "Returns information about the channel state regarding msteams")
|
||||
autocompleteData.AddCommand(channelInfoCmd)
|
||||
|
||||
listInvitesCmd := model.NewAutocompleteData("list-invites", "", "List the current invites")
|
||||
autocompleteData.AddCommand(listInvitesCmd)
|
||||
|
||||
removeInviteCmd := model.NewAutocompleteData("remove-invite", "[mmUserID]", "Deletes the invite for the user ID")
|
||||
autocompleteData.AddCommand(removeInviteCmd)
|
||||
|
||||
cmd := &model.Command{
|
||||
Trigger: "fawkes",
|
||||
AutoComplete: true,
|
||||
AutoCompleteDesc: "Get insights of the user state",
|
||||
AutocompleteData: autocompleteData,
|
||||
}
|
||||
|
||||
if err := p.API.RegisterCommand(cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
p.API.LogDebug("plugin started")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Plugin) ExecuteCommand(_ *plugin.Context, args *model.CommandArgs) (*model.CommandResponse, *model.AppError) {
|
||||
split := strings.Fields(args.Command)
|
||||
command := split[0]
|
||||
var parameters []string
|
||||
action := ""
|
||||
if len(split) > 1 {
|
||||
action = split[1]
|
||||
}
|
||||
if len(split) > 2 {
|
||||
parameters = split[2:]
|
||||
}
|
||||
|
||||
if command != "/fawkes" {
|
||||
return &model.CommandResponse{}, nil
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case "count-whitelisted":
|
||||
rows, err := p.Q().Select("count(*)").From("msteamssync_whitelisted_users").Query()
|
||||
if err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR: %s", err), args)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var result int
|
||||
rows.Next()
|
||||
if err := rows.Scan(&result); err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR: %s", err), args)
|
||||
}
|
||||
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("There are %d users in the msteamssync_whitelisted_users table", result), args)
|
||||
case "count-lastconnectat":
|
||||
rows, err := p.Q().Select("count(*)").From("msteamssync_users").Where(sq.NotEq{"lastconnectat": 0}).Query()
|
||||
if err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR: %s", err), args)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var result int
|
||||
rows.Next()
|
||||
if err := rows.Scan(&result); err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR: %s", err), args)
|
||||
}
|
||||
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("There are %d users in the msteamssync_users table with `lastconnectat != 0`", result), args)
|
||||
case "count-lastdisconnectat":
|
||||
rows, err := p.Q().Select("count(*)").From("msteamssync_users").Where(sq.NotEq{"lastdisconnectat": 0}).Query()
|
||||
if err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR: %s", err), args)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var result int
|
||||
rows.Next()
|
||||
if err := rows.Scan(&result); err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR: %s", err), args)
|
||||
}
|
||||
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("There are %d users in the msteamssync_users table with `lastdisconnectat != 0`", result), args)
|
||||
case "user-info":
|
||||
if len(parameters) != 1 {
|
||||
return p.sendEphemeralAndExit("user-info must receive one \"username\" or \"email\" parameter", args)
|
||||
}
|
||||
|
||||
email := parameters[0]
|
||||
|
||||
var user *model.User
|
||||
var appErr *model.AppError
|
||||
user, appErr = p.API.GetUserByEmail(email)
|
||||
if appErr != nil {
|
||||
user, appErr = p.API.GetUserByUsername(email)
|
||||
if appErr != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR getting the user by email and username: %s", appErr.Error()), args)
|
||||
}
|
||||
}
|
||||
|
||||
rows, err := p.Q().
|
||||
Select("msteamsuserid, token, lastconnectat, lastdisconnectat").
|
||||
From("msteamssync_users").
|
||||
Where(sq.Eq{"mmuserid": user.Id}).
|
||||
Query()
|
||||
if err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR querying for msteamssync user: %s", err), args)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var mmTeamsUserID string
|
||||
var token string
|
||||
var lastConnectAt int
|
||||
var lastDisconnectAt int
|
||||
if !rows.Next() {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("User %q not found in the msteamssync_users table", email), args)
|
||||
}
|
||||
if err := rows.Scan(&mmTeamsUserID, &token, &lastConnectAt, &lastDisconnectAt); err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR scanning rows: %s", err), args)
|
||||
}
|
||||
|
||||
var remoteID string
|
||||
if user.RemoteId != nil {
|
||||
remoteID = *user.RemoteId
|
||||
}
|
||||
|
||||
hasToken := false
|
||||
if token != "" {
|
||||
hasToken = true
|
||||
}
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("User %q has\n - `mmTeamsUserID`: %s\n - `hasToken`: %v\n - `lastConnectAt`: %d\n - `lastDisconnectAt`: %d\n - `remoteID`: %s", email, mmTeamsUserID, hasToken, lastConnectAt, lastDisconnectAt, remoteID), args)
|
||||
case "channel-info":
|
||||
if len(parameters) != 1 {
|
||||
return p.sendEphemeralAndExit("channel-info must receive the channel ID", args)
|
||||
}
|
||||
|
||||
channelID := parameters[0]
|
||||
|
||||
channel, appErr := p.API.GetChannel(channelID)
|
||||
if appErr != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR getting the channel: %s", appErr.Error()), args)
|
||||
}
|
||||
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf(" - `Id`: %s\n - `name`: %s\n - `IsShared`: %v", channel.Id, channel.Name, channel.IsShared()), args)
|
||||
case "list-invites":
|
||||
rows, err := p.Q().
|
||||
Select("mmuserid, invitependingsince, invitelastsentat").
|
||||
From("msteamssync_invited_users").
|
||||
Query()
|
||||
if err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR querying for invited users: %s", err), args)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
invites := []map[string]any{}
|
||||
for rows.Next() {
|
||||
var mmUserID string
|
||||
var invitePendingSince int
|
||||
var inviteLastSentAt int
|
||||
if err := rows.Scan(&mmUserID, &invitePendingSince, &inviteLastSentAt); err != nil {
|
||||
return p.sendEphemeralAndExit(fmt.Sprintf("ERROR scanning row: %s", err), args)
|
||||
}
|
||||
|
||||
invites = append(invites, map[string]any{
|
||||
"mmUserID": mmUserID,
|
||||
"invitePendingSince": invitePendingSince,
|
||||
"inviteLastSentAt": inviteLastSentAt,
|
||||
})
|
||||
}
|
||||
|
||||
message := "Invite list:\n"
|
||||
for _, invite := range invites {
|
||||
message += fmt.Sprintf(
|
||||
" - `mmUserID`: %s :: `invitePendingSince`: %d :: `inviteLastSentAt`: %d\n",
|
||||
invite["mmUserID"],
|
||||
invite["invitePendingSince"],
|
||||
invite["inviteLastSentAt"],
|
||||
)
|
||||
}
|
||||
|
||||
return p.sendEphemeralAndExit(message, args)
|
||||
case "delete-invite":
|
||||
return p.sendEphemeralAndExit("Not implemented yet", args)
|
||||
default:
|
||||
p.sendEphemeral(fmt.Sprintf("Invalid command %q", action), args)
|
||||
return &model.CommandResponse{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Plugin) sendEphemeral(message string, args *model.CommandArgs) {
|
||||
_ = p.API.SendEphemeralPost(args.UserId, &model.Post{
|
||||
Message: message,
|
||||
UserId: args.UserId,
|
||||
ChannelId: args.ChannelId,
|
||||
})
|
||||
}
|
||||
|
||||
func (p *Plugin) sendEphemeralAndExit(message string, args *model.CommandArgs) (*model.CommandResponse, *model.AppError) {
|
||||
p.sendEphemeral(message, args)
|
||||
return &model.CommandResponse{}, nil
|
||||
}
|
||||
|
||||
// See https://developers.mattermost.com/extend/plugins/server/reference/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue