Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Threads reloaded #1058

Merged
merged 24 commits into from Feb 17, 2022
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
32aac90
feat(endpoints): bumped discord version to 9
FedorLap2006 Dec 15, 2021
9dfbd8b
feat: threads barebones
FedorLap2006 Dec 18, 2021
2052f86
feat(threads): documentation
FedorLap2006 Dec 19, 2021
85a65a5
feat(threads): membership caching
FedorLap2006 Dec 19, 2021
1a55a00
feat(threads): added type to StartThread method
FedorLap2006 Dec 21, 2021
ea21d30
Merge branch 'master' into threads
FedorLap2006 Dec 24, 2021
40d1c33
fix: replaced missing Timestamp definitions with time.Time
FedorLap2006 Dec 24, 2021
4337569
chore: removed debug logs
FedorLap2006 Dec 24, 2021
dcadeca
chore: removed thread alias for channel type
FedorLap2006 Dec 24, 2021
6b2e5f3
feat(webhooks): separated thread option into method
FedorLap2006 Dec 24, 2021
5955bcf
fix(state): ThreadMembersUpdate member duplication bug
FedorLap2006 Dec 24, 2021
1651052
fix: golint
FedorLap2006 Dec 24, 2021
2939156
feat(threads): pr fixes and BeforeUpdate in ThreadUpdate
FedorLap2006 Jan 15, 2022
f2dc014
feat: removed unnecessary todo
FedorLap2006 Jan 15, 2022
4ca359f
feat(state): removed thread last message update in MessageAdd
FedorLap2006 Jan 15, 2022
e9e927d
Merge branch 'master' into threads
FedorLap2006 Feb 2, 2022
1d308df
Revert "feat(state): removed thread last message update in MessageAdd"
FedorLap2006 Feb 2, 2022
efed253
feat(state): update only last message id for thread update
FedorLap2006 Feb 2, 2022
9321cd3
fix(restapi): passing threadID in WebhookThreadExecute
FedorLap2006 Feb 5, 2022
b1bb26d
feat(state): dropped last_message_id updates for threads
FedorLap2006 Feb 17, 2022
4389357
Merge branch 'master' into threads
FedorLap2006 Feb 17, 2022
a4c5375
fix: gofmt
FedorLap2006 Feb 17, 2022
505ff58
feat(events#ThreadCreate): added newly_created field
FedorLap2006 Feb 17, 2022
03c1947
feat(restapi)!: corrected names of thread functions
FedorLap2006 Feb 17, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
38 changes: 24 additions & 14 deletions endpoints.go
Expand Up @@ -14,7 +14,7 @@ package discordgo
import "strconv"

// APIVersion is the Discord API version used for the REST and Websocket API.
var APIVersion = "8"
var APIVersion = "9"

// Known Discord API Endpoints.
var (
Expand Down Expand Up @@ -78,6 +78,8 @@ var (
EndpointUserNotes = func(uID string) string { return EndpointUsers + "@me/notes/" + uID }

EndpointGuild = func(gID string) string { return EndpointGuilds + gID }
EndpointGuildThreads = func(gID string) string { return EndpointGuild(gID) + "/threads" }
EndpointGuildActiveThreads = func(gID string) string { return EndpointGuildThreads(gID) + "/active" }
EndpointGuildPreview = func(gID string) string { return EndpointGuilds + gID + "/preview" }
EndpointGuildChannels = func(gID string) string { return EndpointGuilds + gID + "/channels" }
EndpointGuildMembers = func(gID string) string { return EndpointGuilds + gID + "/members" }
Expand All @@ -103,19 +105,27 @@ var (
EndpointGuildEmoji = func(gID, eID string) string { return EndpointGuilds + gID + "/emojis/" + eID }
EndpointGuildBanner = func(gID, hash string) string { return EndpointCDNBanners + gID + "/" + hash + ".png" }

EndpointChannel = func(cID string) string { return EndpointChannels + cID }
EndpointChannelPermissions = func(cID string) string { return EndpointChannels + cID + "/permissions" }
EndpointChannelPermission = func(cID, tID string) string { return EndpointChannels + cID + "/permissions/" + tID }
EndpointChannelInvites = func(cID string) string { return EndpointChannels + cID + "/invites" }
EndpointChannelTyping = func(cID string) string { return EndpointChannels + cID + "/typing" }
EndpointChannelMessages = func(cID string) string { return EndpointChannels + cID + "/messages" }
EndpointChannelMessage = func(cID, mID string) string { return EndpointChannels + cID + "/messages/" + mID }
EndpointChannelMessageAck = func(cID, mID string) string { return EndpointChannels + cID + "/messages/" + mID + "/ack" }
EndpointChannelMessagesBulkDelete = func(cID string) string { return EndpointChannel(cID) + "/messages/bulk-delete" }
EndpointChannelMessagesPins = func(cID string) string { return EndpointChannel(cID) + "/pins" }
EndpointChannelMessagePin = func(cID, mID string) string { return EndpointChannel(cID) + "/pins/" + mID }
EndpointChannelMessageCrosspost = func(cID, mID string) string { return EndpointChannel(cID) + "/messages/" + mID + "/crosspost" }
EndpointChannelFollow = func(cID string) string { return EndpointChannel(cID) + "/followers" }
EndpointChannel = func(cID string) string { return EndpointChannels + cID }
EndpointChannelThreads = func(cID string) string { return EndpointChannel(cID) + "/threads" }
EndpointChannelActiveThreads = func(cID string) string { return EndpointChannelThreads(cID) + "/active" }
EndpointChannelPublicArchivedThreads = func(cID string) string { return EndpointChannelThreads(cID) + "/archived/public" }
EndpointChannelPrivateArchivedThreads = func(cID string) string { return EndpointChannelThreads(cID) + "/archived/private" }
EndpointChannelJoinedPrivateArchivedThreads = func(cID string) string { return EndpointChannel(cID) + "/users/@me/threads/archived/private" }
EndpointChannelPermissions = func(cID string) string { return EndpointChannels + cID + "/permissions" }
EndpointChannelPermission = func(cID, tID string) string { return EndpointChannels + cID + "/permissions/" + tID }
EndpointChannelInvites = func(cID string) string { return EndpointChannels + cID + "/invites" }
EndpointChannelTyping = func(cID string) string { return EndpointChannels + cID + "/typing" }
EndpointChannelMessages = func(cID string) string { return EndpointChannels + cID + "/messages" }
EndpointChannelMessage = func(cID, mID string) string { return EndpointChannels + cID + "/messages/" + mID }
EndpointChannelMessageThread = func(cID, mID string) string { return EndpointChannelMessage(cID, mID) + "/threads" }
EndpointChannelMessageAck = func(cID, mID string) string { return EndpointChannels + cID + "/messages/" + mID + "/ack" }
EndpointChannelMessagesBulkDelete = func(cID string) string { return EndpointChannel(cID) + "/messages/bulk-delete" }
EndpointChannelMessagesPins = func(cID string) string { return EndpointChannel(cID) + "/pins" }
EndpointChannelMessagePin = func(cID, mID string) string { return EndpointChannel(cID) + "/pins/" + mID }
EndpointChannelMessageCrosspost = func(cID, mID string) string { return EndpointChannel(cID) + "/messages/" + mID + "/crosspost" }
EndpointChannelFollow = func(cID string) string { return EndpointChannel(cID) + "/followers" }
EndpointThreadMembers = func(tID string) string { return EndpointChannel(tID) + "/thread-members" }
EndpointThreadMember = func(tID, mID string) string { return EndpointThreadMembers(tID) + "/" + mID }

EndpointGroupIcon = func(cID, hash string) string { return EndpointCDNChannelIcons + cID + "/" + hash + ".png" }

Expand Down
144 changes: 144 additions & 0 deletions eventhandlers.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions events.go
Expand Up @@ -73,6 +73,52 @@ type ChannelPinsUpdate struct {
GuildID string `json:"guild_id,omitempty"`
}

// ThreadCreate is the data for a ThreadCreate event.
type ThreadCreate struct {
*Channel
}

// ThreadUpdate is the data for a ThreadUpdate event.
type ThreadUpdate struct {
*Channel
// TODO: BeforeUpdate
FedorLap2006 marked this conversation as resolved.
Show resolved Hide resolved
}

// ThreadDelete is the data for a ThreadDelete event.
type ThreadDelete struct {
*Channel
}

// ThreadListSync is the data for a ThreadListSync event.
type ThreadListSync struct {
// The id of the guild
GuildID string `json:"guild_id"`
// The parent channel ids whose threads are being synced.
// If omitted, then threads were synced for the entire guild.
// This array may contain channel_ids that have no active threads as well, so you know to clear that data.
ChannelIDs []string `json:"channel_ids"`
// All active threads in the given channels that the current user can access
Threads []*Channel `json:"threads"`
// All thread member objects from the synced threads for the current user,
// indicating which threads the current user has been added to
Members []*ThreadMember `json:"members"`
}

// ThreadMemberUpdate is the data for a ThreadMemberUpdate event.
type ThreadMemberUpdate struct {
*ThreadMember
GuildID string `json:"guild_id"`
}

// ThreadMembersUpdate is the data for a ThreadMembersUpdate event.
type ThreadMembersUpdate struct {
ID string `json:"id"`
GuildID string `json:"guild_id"`
MemberCount int `json:"member_count"`
AddedMembers []AddedThreadMember `json:"added_members"`
RemovedMembers []string `json:"removed_member_ids"`
}

// GuildCreate is the data for a GuildCreate event.
type GuildCreate struct {
*Guild
Expand Down
73 changes: 73 additions & 0 deletions examples/threads/main.go
@@ -0,0 +1,73 @@
package main

import (
"flag"
"fmt"
"log"
"os"
"os/signal"
"strings"
"time"

"github.com/bwmarrin/discordgo"
)

// Flags
var (
BotToken = flag.String("token", "", "Bot token")
)

const timeout time.Duration = time.Second * 10

var games map[string]time.Time = make(map[string]time.Time)

func main() {
flag.Parse()
s, _ := discordgo.New("Bot " + *BotToken)
s.AddHandler(func(s *discordgo.Session, r *discordgo.Ready) {
fmt.Println("Bot is ready")
})
s.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) {
if strings.Contains(m.Content, "ping") {
if ch, err := s.State.Channel(m.ChannelID); err != nil || !ch.IsThread() {
thread, err := s.StartMessageThreadComplex(m.ChannelID, m.ID, &discordgo.ThreadStart{
Name: "Pong game with " + m.Author.Username,
AutoArchiveDuration: 60,
Invitable: false,
RateLimitPerUser: 10,
})
if err != nil {
panic(err)
}
_, _ = s.ChannelMessageSend(thread.ID, "pong")
m.ChannelID = thread.ID
} else {
_, _ = s.ChannelMessageSendReply(m.ChannelID, "pong", m.Reference())
}
games[m.ChannelID] = time.Now()
<-time.After(timeout)
if time.Since(games[m.ChannelID]) >= timeout {
_, err := s.ChannelEditComplex(m.ChannelID, &discordgo.ChannelEdit{
Archived: true,
Locked: true,
})
if err != nil {
panic(err)
}
}
}
})
s.Identify.Intents = discordgo.MakeIntent(discordgo.IntentsAllWithoutPrivileged)

err := s.Open()
if err != nil {
log.Fatalf("Cannot open the session: %v", err)
}
defer s.Close()

stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt)
<-stop
log.Println("Graceful shutdown")

}
12 changes: 12 additions & 0 deletions message.go
Expand Up @@ -38,8 +38,10 @@ const (
MessageTypeChannelFollowAdd MessageType = 12
MessageTypeGuildDiscoveryDisqualified MessageType = 14
MessageTypeGuildDiscoveryRequalified MessageType = 15
MessageTypeThreadCreated MessageType = 18
MessageTypeReply MessageType = 19
MessageTypeChatInputCommand MessageType = 20
MessageTypeThreadStarterMessage MessageType = 21
MessageTypeContextMenuCommand MessageType = 23
)

Expand Down Expand Up @@ -126,10 +128,20 @@ type Message struct {
// To generate a reference to this message, use (*Message).Reference().
MessageReference *MessageReference `json:"message_reference"`

// The message associated with the message_reference
// NOTE: This field is only returned for messages with a type of 19 (REPLY) or 21 (THREAD_STARTER_MESSAGE).
// If the message is a reply but the referenced_message field is not present,
// the backend did not attempt to fetch the message that was being replied to, so its state is unknown.
// If the field exists but is null, the referenced message was deleted.
ReferencedMessage *Message `json:"referenced_message"`

// The flags of the message, which describe extra features of a message.
// This is a combination of bit masks; the presence of a certain permission can
// be checked by performing a bitwise AND between this int and the flag.
Flags MessageFlags `json:"flags"`

// The thread that was started from this message, includes thread member object
Thread *Channel `json:"thread,omitempty"`
}

// UnmarshalJSON is a helper function to unmarshal the Message.
Expand Down