diff options
| author | Xe Iaso <me@xeiaso.net> | 2023-06-12 17:47:10 -0400 |
|---|---|---|
| committer | Xe Iaso <me@xeiaso.net> | 2023-06-12 17:47:25 -0400 |
| commit | a155f3cd8556d30185bc4e7a0a87dd7861c0afdb (patch) | |
| tree | 8c2689b670d26bd5ba74895d60ceb1d304e4433d /web | |
| parent | b4605f6b6f99964aab4c786bb7b9df6e8dc39f01 (diff) | |
| download | x-a155f3cd8556d30185bc4e7a0a87dd7861c0afdb.tar.xz x-a155f3cd8556d30185bc4e7a0a87dd7861c0afdb.zip | |
import revolt package
Signed-off-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'web')
| -rw-r--r-- | web/revolt/LICENSE | 7 | ||||
| -rw-r--r-- | web/revolt/README.md | 155 | ||||
| -rw-r--r-- | web/revolt/bot.go | 56 | ||||
| -rw-r--r-- | web/revolt/cache.go | 123 | ||||
| -rw-r--r-- | web/revolt/channel.go | 201 | ||||
| -rw-r--r-- | web/revolt/client.go | 403 | ||||
| -rw-r--r-- | web/revolt/emoji.go | 6 | ||||
| -rw-r--r-- | web/revolt/events.go | 5 | ||||
| -rw-r--r-- | web/revolt/go.sum | 10 | ||||
| -rw-r--r-- | web/revolt/group.go | 71 | ||||
| -rw-r--r-- | web/revolt/http.go | 48 | ||||
| -rw-r--r-- | web/revolt/interaction.go | 6 | ||||
| -rw-r--r-- | web/revolt/message.go | 150 | ||||
| -rw-r--r-- | web/revolt/other.go | 324 | ||||
| -rw-r--r-- | web/revolt/permissions.go | 100 | ||||
| -rw-r--r-- | web/revolt/server.go | 368 | ||||
| -rw-r--r-- | web/revolt/user.go | 133 | ||||
| -rw-r--r-- | web/revolt/utils.go | 15 | ||||
| -rw-r--r-- | web/revolt/websocket.go | 364 |
19 files changed, 2545 insertions, 0 deletions
diff --git a/web/revolt/LICENSE b/web/revolt/LICENSE new file mode 100644 index 0000000..6972546 --- /dev/null +++ b/web/revolt/LICENSE @@ -0,0 +1,7 @@ +Copyright 2021 5elenay, itsTheMeow, & Ben Forster + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file diff --git a/web/revolt/README.md b/web/revolt/README.md new file mode 100644 index 0000000..d532534 --- /dev/null +++ b/web/revolt/README.md @@ -0,0 +1,155 @@ +# revolt.go + +Revolt.go is a Go package for writing bots and self-bots in Revolt +easily. This project is a mantained and re-worked version +[ben-forster's fork](https://github.com/ben-forster/revolt) of +5elenay's library [revoltgo](https://github.com/5elenay/revoltgo). + +## Features + +- Multiple event listen +- Easy to use +- Supports self bots +- Simple cache system + +## API Reference + +Click [here](https://pkg.go.dev/within.website/x/web/revolt) for api reference. + +## Notice + +Please note that you will need the Go 1.20 to use revolt. + +This package is still under development and while you can create a +working bot, the library is not finished. Create an issue if you would +like to contribute. + +## Ping Pong Example (Bot) + +```go +package main + +import ( + "os" + "os/signal" + "syscall" + + "within.website/x/web/revolt" +) + +func main() { + // Init a new client. + client := revolt.Client{ + Token: "bot token", + } + + // Listen a on message event. + client.OnMessage(func(m *revolt.Message) { + if m.Content == "!ping" { + sendMsg := &revolt.SendMessage{} + sendMsg.SetContent("🏓 Pong!") + + m.Reply(true, sendMsg) + } + }) + + // Start the client. + client.Start() + + // Wait for close. + sc := make(chan os.Signal, 1) + + signal.Notify( + sc, + syscall.SIGINT, + syscall.SIGTERM, + os.Interrupt, + ) + <-sc + + // Destroy client. + client.Destroy() +} + +``` + +## Ping Pong Example (Self-Bot) + +```go +package main + +import ( + "os" + "os/signal" + "syscall" + + "within.website/x/web/revolt" +) + +func main() { + // Init a new client. + client := revolt.Client{ + SelfBot: &revolt.SelfBot{ + Id: "session id", + SessionToken: "session token", + UserId: "user id", + }, + } + + // Listen a on message event. + client.OnMessage(func(m *revolt.Message) { + if m.Content == "!ping" { + sendMsg := &revolt.SendMessage{} + sendMsg.SetContent("🏓 Pong!") + + m.Reply(true, sendMsg) + } + }) + + // Start the client. + client.Start() + + // Wait for close. + sc := make(chan os.Signal, 1) + + signal.Notify( + sc, + syscall.SIGINT, + syscall.SIGTERM, + os.Interrupt, + ) + <-sc + + // Destroy client. + client.Destroy() +} + +``` + +## To-Do + +- [x] OnReady +- [x] OnMessage +- [x] OnMessageUpdate +- [ ] OnMessageAppend +- [x] OnMessageDelete +- [x] OnChannelCreate +- [x] OnChannelUpdate +- [x] OnChannelDelete +- [ ] OnChannelGroupJoin +- [ ] OnChannelGroupLeave +- [x] OnChannelStartTyping +- [x] OnChannelStopTyping +- [ ] OnChannelAck +- [x] OnServerCreate +- [x] OnServerUpdate +- [x] OnServerDelete +- [x] OnServerMemberUpdate +- [x] OnServerMemberJoin +- [x] OnServerMemberLeave +- [ ] OnServerRoleUpdate +- [ ] OnServerRoleDelete +- [ ] OnUserUpdate +- [ ] OnUserRelationship +- [ ] OnEmojiCreate +- [ ] OnEmojiDelete diff --git a/web/revolt/bot.go b/web/revolt/bot.go new file mode 100644 index 0000000..de29081 --- /dev/null +++ b/web/revolt/bot.go @@ -0,0 +1,56 @@ +package revolt + +import ( + "encoding/json" + "time" + + "github.com/oklog/ulid/v2" +) + +// Bot struct. +type Bot struct { + Client *Client + CreatedAt time.Time + + Id string `json:"_id"` + OwnerId string `json:"owner"` + Token string `json:"token"` + IsPublic bool `json:"public"` + InteractionsUrl string `json:"interactionsURL"` +} + +// Fetched bots struct. +type FetchedBots struct { + Bots []*Bot `json:"bots"` + Users []*User `json:"users"` +} + +// Calculate creation date and edit the struct. +func (b *Bot) CalculateCreationDate() error { + ulid, err := ulid.Parse(b.Id) + + if err != nil { + return err + } + + b.CreatedAt = time.UnixMilli(int64(ulid.Time())) + return nil +} + +// Edit the bot. +func (b *Bot) Edit(eb *EditBot) error { + data, err := json.Marshal(eb) + + if err != nil { + return err + } + + _, err = b.Client.Request("PATCH", "/bots/"+b.Id, data) + return err +} + +// Delete the bot. +func (b *Bot) Delete() error { + _, err := b.Client.Request("DELETE", "/bots/"+b.Id, []byte{}) + return err +} diff --git a/web/revolt/cache.go b/web/revolt/cache.go new file mode 100644 index 0000000..c04c80d --- /dev/null +++ b/web/revolt/cache.go @@ -0,0 +1,123 @@ +package revolt + +import "fmt" + +// Client cache struct. +type Cache struct { + Users []*User `json:"users"` + Servers []*Server `json:"servers"` + Channels []*Channel `json:"channels"` + Members []*Member `json:"members"` +} + +// Get a channel from cache by Id. +// Will return an empty channel struct if not found. +func (c *Cache) GetChannel(id string) *Channel { + for _, i := range c.Channels { + if i.Id == id { + return i + } + } + + return &Channel{} +} + +// Get a server from cache by Id. +// Will return an empty server struct if not found. +func (c *Cache) GetServer(id string) *Server { + for _, i := range c.Servers { + if i.Id == id { + return i + } + } + + return &Server{} +} + +// Get an user from cache by Id. +// Will return an empty user struct if not found. +func (c *Cache) GetUser(id string) *User { + for _, i := range c.Users { + if i.Id == id { + return i + } + } + + return &User{} +} + +// Get a member from cache by Id. +// Will return an empty member struct if not found. +func (c *Cache) GetMember(id string) *Member { + for _, i := range c.Members { + if i.Informations.UserId == id { + return i + } + } + + return &Member{} +} + +// Remove a channel from cache by Id. +// Will not delete the channel, just deletes the channel from cache. +// Will change the entire channel cache order! +func (c *Cache) RemoveChannel(id string) error { + for i, v := range c.Channels { + if v.Id == id { + c.Channels[i] = c.Channels[len(c.Channels)-1] + c.Channels = c.Channels[:len(c.Channels)-1] + + return nil + } + } + + return fmt.Errorf("channel not found") +} + +// Remove a server from cache by Id. +// Will not delete the server, just deletes the server from cache. +// Will change the entire server cache order! +func (c *Cache) RemoveServer(id string) error { + for i, v := range c.Servers { + if v.Id == id { + c.Servers[i] = c.Servers[len(c.Servers)-1] + c.Servers = c.Servers[:len(c.Servers)-1] + + return nil + } + } + + return fmt.Errorf("server not found") +} + +// Remove an user from cache by Id. +// Will not delete the user, just deletes the user from cache. +// Will change the entire user cache order! +func (c *Cache) RemoveUser(id string) error { + for i, v := range c.Users { + if v.Id == id { + c.Users[i] = c.Users[len(c.Users)-1] + c.Users = c.Users[:len(c.Users)-1] + + return nil + } + } + + return fmt.Errorf("user not found") +} + +// Remove a member from cache by Id. +// Will not delete the member, just deletes the member from cache. +// Will change the entire member cache order! +func (c *Cache) RemoveMember(id string) error { + for i, v := range c.Members { + if v.Informations.UserId == id { + c.Members[i] = c.Members[len(c.Members)-1] + c.Members = c.Members[:len(c.Members)-1] + + return nil + } + } + + return fmt.Errorf("member not found") +} diff --git a/web/revolt/channel.go b/web/revolt/channel.go new file mode 100644 index 0000000..99211ba --- /dev/null +++ b/web/revolt/channel.go @@ -0,0 +1,201 @@ +package revolt + +import ( + "encoding/json" + "fmt" + "reflect" + "time" + + "github.com/oklog/ulid/v2" +) + +// Channel struct. +type Channel struct { + Client *Client + CreatedAt time.Time + + Id string `json:"_id"` + Nonce string `json:"nonce"` + OwnerId string `json:"owner"` + Name string `json:"name"` + Active bool `json:"active"` + Recipients []string `json:"recipients"` + LastMessage interface{} `json:"last_message"` + Description string `json:"description"` + Icon *Attachment `json:"icon"` + DefaultPermissions uint `json:"default_permissions"` + RolePermissions interface{} `json:"role_permissions"` + Permissions uint `json:"permissions"` +} + +// Fetched messages struct. +type FetchedMessages struct { + Messages []*Message `json:"messages"` + Users []*User `json:"users"` +} + +// Calculate creation date and edit the struct. +func (c *Channel) CalculateCreationDate() error { + ulid, err := ulid.Parse(c.Id) + + if err != nil { + return err + } + + c.CreatedAt = time.UnixMilli(int64(ulid.Time())) + return nil +} + +// Send a message to the channel. +func (c Channel) SendMessage(message *SendMessage) (*Message, error) { + if message.Nonce == "" { + message.CreateNonce() + } + + respMessage := &Message{} + respMessage.Client = c.Client + msgData, err := json.Marshal(message) + + if err != nil { + return respMessage, err + } + + resp, err := c.Client.Request("POST", "/channels/"+c.Id+"/messages", msgData) + + if err != nil { + return respMessage, err + } + + err = json.Unmarshal(resp, respMessage) + + if err != nil { + return respMessage, err + } + + if message.DeleteAfter != 0 { + go func() { + time.Sleep(time.Second * time.Duration(message.DeleteAfter)) + respMessage.Delete() + }() + } + + return respMessage, nil +} + +// Fetch messages from channel. +// Check: https://developers.revolt.chat/api/#tag/Messaging/paths/~1channels~1:channel~1messages/get for map parameters. +func (c Channel) FetchMessages(options map[string]interface{}) (*FetchedMessages, error) { + // Format url + url := "/channels/" + c.Id + "/messages?" + + for key, value := range options { + if !reflect.ValueOf(value).IsZero() { + url += fmt.Sprintf("%s=%v&", key, value) + } + } + + url = url[:len(url)-1] + + fetchedMsgs := &FetchedMessages{} + + // Send request + resp, err := c.Client.Request("GET", url, []byte{}) + + if err != nil { + return fetchedMsgs, err + } + + err = json.Unmarshal(resp, &fetchedMsgs) + + if err != nil { + err = json.Unmarshal([]byte(fmt.Sprintf("{\"messages\": %s}", resp)), &fetchedMsgs) + + if err != nil { + return fetchedMsgs, err + } + } + + // Add client to users & messages + for _, msg := range fetchedMsgs.Messages { + msg.Client = c.Client + } + + if fetchedMsgs.Users != nil { + for _, msg := range fetchedMsgs.Users { + msg.Client = c.Client + } + } + + return fetchedMsgs, nil +} + +// Fetch a message from channel by Id. +func (c Channel) FetchMessage(id string) (*Message, error) { + msg := &Message{} + msg.Client = c.Client + + resp, err := c.Client.Request("GET", "/channels/"+c.Id+"/messages/"+id, []byte{}) + + if err != nil { + return msg, err + } + + err = json.Unmarshal(resp, msg) + return msg, err +} + +// Edit channel. +func (c Channel) Edit(ec *EditChannel) error { + data, err := json.Marshal(ec) + + if err != nil { + return err + } + + _, err = c.Client.Request("PATCH", "/channels/"+c.Id, data) + return err +} + +// Delete channel. +func (c Channel) Delete() error { + _, err := c.Client.Request("DELETE", "/channels/"+c.Id, []byte{}) + return err +} + +// Create a new invite. +// Returns a string (invite code) and error (nil if not exists). +func (c Channel) CreateInvite() (string, error) { + data, err := c.Client.Request("POST", "/channels/"+c.Id+"/invites", []byte{}) + + if err != nil { + return "", err + } + + dataStruct := &struct { + InviteCode string `json:"code"` + }{} + + err = json.Unmarshal(data, dataStruct) + return dataStruct.InviteCode, err +} + +// Set channel permissions for a role. +// Leave role field empty if you want to edit default permissions +func (c Channel) SetPermissions(role_id string, permissions uint) error { + if role_id == "" { + role_id = "default" + } + + _, err := c.Client.Request("PUT", "/channels/"+c.Id+"/permissions/"+role_id, []byte(fmt.Sprintf("{\"permissions\":%d}", permissions))) + return err +} + +// Send a typing start event to the channel. +func (c *Channel) BeginTyping() { + c.Client.Socket.SendText(fmt.Sprintf("{\"type\":\"BeginTyping\",\"channel\":\"%s\"}", c.Id)) +} + +// End the typing event in the channel. +func (c *Channel) EndTyping() { + c.Client.Socket.SendText(fmt.Sprintf("{\"type\":\"EndTyping\",\"channel\":\"%s\"}", c.Id)) +} diff --git a/web/revolt/client.go b/web/revolt/client.go new file mode 100644 index 0000000..b58479f --- /dev/null +++ b/web/revolt/client.go @@ -0,0 +1,403 @@ +package revolt + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/sacOO7/gowebsocket" +) + +const ( + WS_URL = "wss://ws.revolt.chat" + API_URL = "https://api.revolt.chat" +) + +// Client struct. +type Client struct { + SelfBot *SelfBot + Token string + Socket gowebsocket.Socket + HTTP *http.Client + Cache *Cache + + // Event Functions + OnUnknownEventFunctions []func(message string) + OnReadyFunctions []func() + OnMessageFunctions []func(message *Message) + OnMessageUpdateFunctions []func(channel_id, message_id string, payload map[string]interface{}) + OnMessageDeleteFunctions []func(channel_id, message_id string) + OnChannelCreateFunctions []func(channel *Channel) + OnChannelUpdateFunctions []func(channel_id, clear string, payload map[string]interface{}) + OnChannelDeleteFunctions []func(channel_id string) + OnGroupCreateFunctions []func(group *Group) + OnGroupMemberAddedFunctions []func(group_id, user_id string) + OnGroupMemberRemovedFunctions []func(group_id, user_id string) + OnChannelStartTypingFunctions []func(channel_id, user_id string) + OnChannelStopTypingFunctions []func(channel_id, user_id string) + OnServerCreateFunctions []func(server_id *Server) + OnServerUpdateFunctions []func(server_id, clear string, payload map[string]interface{}) + OnServerDeleteFunctions []func(server_id string) + OnServerMemberUpdateFunctions []func(server_id, clear string, payload map[string]interface{}) + OnServerMemberJoinFunctions []func(server_id, user_id string) + OnServerMemberLeaveFunctions []func(server_id, user_id string) +} + +// Self bot struct. +type SelfBot struct { + Email string `json:"-"` + Password string `json:"-"` + Id string `json:"id"` + UserId string `json:"user_id"` + SessionToken string `json:"token"` +} + +// On ready event will run when websocket connection is started and bot is ready to work. +func (c *Client) OnReady(fn func()) { + c.OnReadyFunctions = append(c.OnReadyFunctions, fn) +} + +// On message event will run when someone sends a message. +func (c *Client) OnMessage(fn func(message *Message)) { + c.OnMessageFunctions = append(c.OnMessageFunctions, fn) +} + +// On message update event will run when someone updates a message. +func (c *Client) OnMessageUpdate(fn func(channel_id, message_id string, payload map[string]interface{})) { + c.OnMessageUpdateFunctions = append(c.OnMessageUpdateFunctions, fn) +} + +// On message delete event will run when someone deletes a message. +func (c *Client) OnMessageDelete(fn func(channel_id, message_id string)) { + c.OnMessageDeleteFunctions = append(c.OnMessageDeleteFunctions, fn) +} + +// On channel create event will run when someone creates a channel. +func (c *Client) OnChannelCreate(fn func(channel *Channel)) { + c.OnChannelCreateFunctions = append(c.OnChannelCreateFunctions, fn) +} + +// On channel update event will run when someone updates a channel. +func (c *Client) OnChannelUpdate(fn func(channel_id, clear string, payload map[string]interface{})) { + c.OnChannelUpdateFunctions = append(c.OnChannelUpdateFunctions, fn) +} + +// On channel delete event will run when someone deletes a channel. +func (c *Client) OnChannelDelete(fn func(channel_id string)) { + c.OnChannelDeleteFunctions = append(c.OnChannelDeleteFunctions, fn) +} + +// On group channel create event will run when someones creates a group channel. +func (c *Client) OnGroupCreate(fn func(group *Group)) { + c.OnGroupCreateFunctions = append(c.OnGroupCreateFunctions, fn) +} + +// On group member added will run when someone is added to a group channel. +func (c *Client) OnGroupMemberAdded(fn func(group_id string, user_id string)) { + c.OnGroupMemberAddedFunctions = append(c.OnGroupMemberAddedFunctions, fn) +} + +// On group member removed will run when someone is removed from a group channel. +func (c *Client) OnGroupMemberRemoved(fn func(group_id string, user_id string)) { + c.OnGroupMemberRemovedFunctions = append(c.OnGroupMemberRemovedFunctions, fn) +} + +// On unknown event will run when client gets a unknown event. +func (c *Client) OnUnknownEvent(fn func(message string)) { + c.OnUnknownEventFunctions = append(c.OnUnknownEventFunctions, fn) +} + +// On channel start typing will run when someone starts to type a message. +func (c *Client) OnChannelStartTyping(fn func(channel_id, user_id string)) { + c.OnChannelStartTypingFunctions = append(c.OnChannelStartTypingFunctions, fn) +} + +// On channel stop typing will run when someone stops the typing status. +func (c *Client) OnChannelStopTyping(fn func(channel_id, user_id string)) { + c.OnChannelStopTypingFunctions = append(c.OnChannelStopTypingFunctions, fn) +} + +// On server create event will run when someone creates a server. +func (c *Client) OnServerCreate(fn func(server *Server)) { + c.OnServerCreateFunctions = append(c.OnServerCreateFunctions, fn) +} + +// On server update will run when someone updates a server. +func (c *Client) OnServerUpdate(fn func(server_id, clear string, payload map[string]interface{})) { + c.OnServerUpdateFunctions = append(c.OnServerUpdateFunctions, fn) +} + +// On server delete will run when someone deletes a server. +func (c *Client) OnServerDelete(fn func(server_id string)) { + c.OnServerDeleteFunctions = append(c.OnServerDeleteFunctions, fn) +} + +// On server member update will run when a server member updates. +func (c *Client) OnServerMemberUpdate(fn func(server_id, clear string, payload map[string]interface{})) { + c.OnServerMemberUpdateFunctions = append(c.OnServerMemberUpdateFunctions, fn) +} + +// On server member join will run when someone joins to the server. +func (c *Client) OnServerMemberJoin(fn func(server_id string, user_id string)) { + c.OnServerMemberJoinFunctions = append(c.OnServerMemberJoinFunctions, fn) +} + +// On server member leave will run when someone left from server. +func (c *Client) OnServerMemberLeave(fn func(server_id string, user_id string)) { + c.OnServerMemberLeaveFunctions = append(c.OnServerMemberLeaveFunctions, fn) +} + +// Fetch a channel by Id. +func (c *Client) FetchChannel(id string) (*Channel, error) { + channel := &Channel{} + channel.Client = c + + data, err := c.Request("GET", "/channels/"+id, []byte{}) + + if err != nil { + return channel, err + } + + err = json.Unmarshal(data, channel) + return channel, err +} + +// Fetch an user by Id. +func (c *Client) FetchUser(id string) (*User, error) { + user := &User{} + user.Client = c + + data, err := c.Request("GET", "/users/"+id, []byte{}) + + if err != nil { + return user, err + } + + err = json.Unmarshal(data, user) + return user, err +} + +// Fetch a server by Id. +func (c *Client) FetchServer(id string) (*Server, error) { + server := &Server{} + server.Client = c + + data, err := c.Request("GET", "/servers/"+id, []byte{}) + + if err != nil { + return server, err + } + + err = json.Unmarshal(data, server) + return server, err +} + +// Create a server. +func (c *Client) CreateServer(name, description string) (*Server, error) { + server := &Server{} + server.Client = c + + data, err := c.Request("POST", "/servers/create", []byte("{\"name\":\""+name+"\",\"description\":\""+description+"\",\"nonce\":\""+genULID()+"\"}")) + + if err != nil { + return server, err + } + + err = json.Unmarshal(data, server) + return server, err +} + +// Auth client user. +func (c *Client) Auth(friendlyName string) error { + if c.SelfBot == nil { + return fmt.Errorf("can't auth user (not a self-bot.)") + } + + resp, err := c.Request("POST", "/auth/session/login", []byte("{\"email\":\""+c.SelfBot.Email+"\",\"password\":\""+c.SelfBot.Password+"\",\"friendly_name\":\""+friendlyName+"\"}")) + + if err != nil { + return err + } + + err = json.Unmarshal(resp, c.SelfBot) + return err +} + +// Fetch all of the DMs. +func (c *Client) FetchDirectMessages() ([]*Channel, error) { + var dmChannels []*Channel + + resp, err := c.Request("GET", "/users/dms", []byte{}) + + if err != nil { + return dmChannels, err + } + + err = json.Unmarshal(resp, &dmChannels) + + if err != nil { + return dmChannels, err + } + + // Prepare channels. + for _, i := range dmChannels { + i.Client = c + } + + return dmChannels, nil +} + +// Edit client user. +func (c Client) Edit(eu *EditUser) error { + data, err := json.Marshal(eu) + + if err != nil { + return err + } + + _, err = c.Request("PATCH", "/users/@me", data) + return err +} + +// Create a new group. +// Users parameter is a list of users will be added. +func (c *Client) CreateGroup(name, description string, users []string) (*Channel, error) { + groupChannel := &Channel{} + groupChannel.Client = c + + dataStruct := &struct { + Name string `json:"name"` + Description string `json:"description,omitempty"` + Users []string `json:"users"` + Nonce string `json:"nonce"` + }{ + Nonce: genULID(), + Name: name, + Description: description, + Users: users, + } + + data, err := json.Marshal(dataStruct) + + if err != nil { + return groupChannel, err + } + + resp, err := c.Request("POST", "/channels/create", data) + + if err != nil { + return groupChannel, err + } + + err = json.Unmarshal(resp, groupChannel) + return groupChannel, err +} + +// Fetch relationships. +func (c Client) FetchRelationships() ([]*UserRelations, error) { + relationshipDatas := []*UserRelations{} + + resp, err := c.Request("GET", "/users/relationships", []byte{}) + + if err != nil { + return relationshipDatas, err + } + + err = json.Unmarshal(resp, &relationshipDatas) + return relationshipDatas, err +} + +// Send friend request. / Accept friend request. +// User relations struct only will have status. id is not defined for this function. +func (c Client) AddFriend(username string) (*UserRelations, error) { + relationshipData := &UserRelations{} + + resp, err := c.Request("PUT", "/users/"+username+"/friend", []byte{}) + + if err != nil { + return relationshipData, err + } + + err = json.Unmarshal(resp, relationshipData) + return relationshipData, err +} + +// Deny friend request. / Remove friend. +// User relations struct only will have status. id is not defined for this function. +func (c Client) RemoveFriend(username string) (*UserRelations, error) { + relationshipData := &UserRelations{} + + resp, err := c.Request("DELETE", "/users/"+username+"/friend", []byte{}) + + if err != nil { + return relationshipData, err + } + + err = json.Unmarshal(resp, relationshipData) + return relationshipData, err +} + +// Create a new bot. +func (c *Client) CreateBot(name string) (*Bot, error) { + botData := &Bot{} + botData.Client = c + + resp, err := c.Request("POST", "/bots/create", []byte("{\"name\":\""+name+"\"}")) + + if err != nil { + return botData, err + } + + err = json.Unmarshal(resp, botData) + return botData, err + +} + +// Fetch client bots. +func (c *Client) FetchBots() (*FetchedBots, error) { + bots := &FetchedBots{} + + resp, err := c.Request("GET", "/bots/@me", []byte{}) + + if err != nil { + return bots, err + } + + err = json.Unmarshal(resp, bots) + + if err != nil { + return bots, err + } + + // Add client for bots. + for _, i := range bots.Bots { + i.Client = c + } + + // Add client for users. + for _, i := range bots.Users { + i.Client = c + } + + return bots, nil +} + +// Fetch a bot. +func (c *Client) FetchBot(id string) (*Bot, error) { + bot := &struct { + Bot *Bot `json:"bot"` + }{ + Bot: &Bot{ + Client: c, + }, + } + + resp, err := c.Request("GET", "/bots/"+id, []byte{}) + + if err != nil { + return bot.Bot, err + } + + err = json.Unmarshal(resp, bot) + return bot.Bot, err +} diff --git a/web/revolt/emoji.go b/web/revolt/emoji.go new file mode 100644 index 0000000..57f37ac --- /dev/null +++ b/web/revolt/emoji.go @@ -0,0 +1,6 @@ +package revolt + +// Emoji struct. +type Emoji struct { + +} diff --git a/web/revolt/events.go b/web/revolt/events.go new file mode 100644 index 0000000..6e9c608 --- /dev/null +++ b/web/revolt/events.go @@ -0,0 +1,5 @@ +package revolt + +type Events struct { + +} diff --git a/web/revolt/go.sum b/web/revolt/go.sum new file mode 100644 index 0000000..c1fa47c --- /dev/null +++ b/web/revolt/go.sum @@ -0,0 +1,10 @@ +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU= +github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= +github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= +github.com/sacOO7/go-logger v0.0.0-20180719173527-9ac9add5a50d h1:5T+fbRuQbpi+WZtB2yfuu59r00F6T2HV/zGYrwX8nvE= +github.com/sacOO7/go-logger v0.0.0-20180719173527-9ac9add5a50d/go.mod h1:L5EJe2k8GwpBoGXDRLAEs58R239jpZuE7NNEtW+T7oo= +github.com/sacOO7/gowebsocket v0.0.0-20221109081133-70ac927be105 h1:WgzGzpeh4gpYaVzpdMlThUp5HK2w+tmX8FiGxyVMLys= +github.com/sacOO7/gowebsocket v0.0.0-20221109081133-70ac927be105/go.mod h1:h00QywbM5Le22ESUiI8Yz2/9TVGD8eAz/cAk55Kcz/E= diff --git a/web/revolt/group.go b/web/revolt/group.go new file mode 100644 index 0000000..6d3179d --- /dev/null +++ b/web/revolt/group.go @@ -0,0 +1,71 @@ +package revolt + +import ( + "encoding/json" + "time" + + "github.com/oklog/ulid/v2" +) + +// Group channel struct. +type Group struct { + Client *Client + CreatedAt time.Time + + Id string `json:"_id"` + Nonce string `json:"nonce"` + OwnerId string `json:"owner"` + Name string `json:"name"` + Description string `json:"description,omitempty"` + Users []string `json:"users"` +} + +// Fetched group members struct. +type FetchedGroupMembers struct { + Messages []*Message `json:"messages"` + Users []*User `json:"users"` +} + +// System messages struct. +type GroupSystemMessages struct { + UserJoined string `json:"user_joined,omitempty"` + UserLeft string `json:"user_left,omitempty"` +} + +// Calculate creation date and edit the struct. +func (c *Group) CalculateCreationDate() error { + u |
