Initial commit
This commit is contained in:
commit
7d554f3c9e
|
@ -0,0 +1 @@
|
|||
.env
|
|
@ -0,0 +1,63 @@
|
|||
package haccerinteractions
|
||||
|
||||
import "github.com/bwmarrin/discordgo"
|
||||
|
||||
type Command struct {
|
||||
Type int `json:"type"`
|
||||
ID string `json:"id"`
|
||||
ApplicationID string `json:"application_id"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Options []CommandOption `json:"options"`
|
||||
}
|
||||
type GuildChannel struct {
|
||||
GuildID string
|
||||
ChannelID string
|
||||
}
|
||||
|
||||
type commandRunRequest struct {
|
||||
Type int `json:"type"`
|
||||
BotID string `json:"application_id"`
|
||||
GuildID string `json:"guild_id"`
|
||||
ChannelID string `json:"channel_id"`
|
||||
SessionID string `json:"session_id"`
|
||||
Data commandRunData `json:"data"`
|
||||
}
|
||||
type commandRunData struct {
|
||||
ID string `json:"id"`
|
||||
Type int `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Options []CommandRunOption `json:"options"`
|
||||
}
|
||||
type CommandRunOption struct {
|
||||
Type int `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type CommandSearchResponse struct {
|
||||
Commands []Command `json:"application_commands"`
|
||||
}
|
||||
|
||||
type CommandOption struct {
|
||||
Type int `json:"type"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
type ComponentInteractRequest struct {
|
||||
Type discordgo.InteractionType `json:"type"`
|
||||
Flags int `json:"message_flags"`
|
||||
SessionID string `json:"session_id"`
|
||||
Nonce string `json:"nonce"`
|
||||
GuildID string `json:"guild_id"`
|
||||
ChannelID string `json:"channel_id"`
|
||||
MessageID string `json:"message_id"`
|
||||
BotID string `json:"application_id"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
type ButtonClickRequestData struct{}
|
||||
type SelectMenuSelectRequestData struct {
|
||||
Type discordgo.SelectMenuType `json:"type"`
|
||||
Values []string `json:"values"`
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
module github.com/jacks0n9/haccerinteractions
|
||||
|
||||
go 1.20
|
||||
|
||||
require github.com/bwmarrin/discordgo v0.27.1
|
||||
|
||||
require (
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect
|
||||
)
|
|
@ -0,0 +1,12 @@
|
|||
github.com/bwmarrin/discordgo v0.27.1 h1:ib9AIc/dom1E/fSIulrBwnez0CToJE113ZGt4HoliGY=
|
||||
github.com/bwmarrin/discordgo v0.27.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
@ -0,0 +1,95 @@
|
|||
package haccerinteractions
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
)
|
||||
|
||||
type haccerInteractionsRunner struct {
|
||||
Session *discordgo.Session
|
||||
commandRunLock map[string]*sync.Mutex
|
||||
}
|
||||
|
||||
func (hir *haccerInteractionsRunner) getCommandMutex(name string) *sync.Mutex {
|
||||
if _, ok := hir.commandRunLock[name]; !ok {
|
||||
newMutex := sync.Mutex{}
|
||||
hir.commandRunLock[name] = &newMutex
|
||||
return &newMutex
|
||||
}
|
||||
return hir.commandRunLock[name]
|
||||
}
|
||||
|
||||
// Create a command runner
|
||||
func NewRunner(s *discordgo.Session) haccerInteractionsRunner {
|
||||
s.StateEnabled = true
|
||||
s.Identify.Intents = discordgo.IntentsAll
|
||||
s.Open()
|
||||
newRunner := haccerInteractionsRunner{
|
||||
Session: s,
|
||||
commandRunLock: make(map[string]*sync.Mutex),
|
||||
}
|
||||
return newRunner
|
||||
}
|
||||
|
||||
// Get slash commands in a channel. Limit is ignored if application id is set.
|
||||
func (hir haccerInteractionsRunner) GuildChannelGetSlashCommands(channelID string, limit int, applicationID string) (*[]Command, error) {
|
||||
payload := url.Values{}
|
||||
payload.Add("type", "1")
|
||||
if applicationID != "" {
|
||||
payload.Add("application_id", applicationID)
|
||||
} else {
|
||||
payload.Add("limit", fmt.Sprint(limit))
|
||||
}
|
||||
response, err := hir.Session.Request(http.MethodGet, fmt.Sprintf(`https://discord.com/api/v9/channels/%s/application-commands/search?%s`, channelID, payload.Encode()), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
searchResponse := CommandSearchResponse{}
|
||||
json.Unmarshal(response, &searchResponse)
|
||||
return &searchResponse.Commands, nil
|
||||
}
|
||||
|
||||
// Interact with a component
|
||||
// Remember that the top level components in a message are action rows.
|
||||
func (hir haccerInteractionsRunner) GuildChannelComponentRequest(gc GuildChannel, messageID string, botID string, customID string, data interface{}) error {
|
||||
var dataMap map[string]interface{}
|
||||
jsonEncoded, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return errors.New("error encoding data to json for component type detection: " + err.Error())
|
||||
}
|
||||
json.Unmarshal(jsonEncoded, &dataMap)
|
||||
var componentType discordgo.ComponentType
|
||||
switch data.(type) {
|
||||
case ButtonClickRequestData:
|
||||
componentType = discordgo.ButtonComponent
|
||||
case SelectMenuSelectRequestData:
|
||||
componentType = dataMap["type"].(discordgo.ComponentType)
|
||||
}
|
||||
|
||||
dataMap["component_type"] = componentType
|
||||
dataMap["custom_id"] = customID
|
||||
source := rand.NewSource(int64(time.Now().Nanosecond()))
|
||||
gen := rand.New(source)
|
||||
requestStruct := ComponentInteractRequest{
|
||||
Type: discordgo.InteractionMessageComponent,
|
||||
Flags: 0,
|
||||
SessionID: hir.Session.State.SessionID,
|
||||
Nonce: fmt.Sprint(gen.Intn(99999999999999)),
|
||||
GuildID: gc.GuildID,
|
||||
ChannelID: gc.ChannelID,
|
||||
MessageID: messageID,
|
||||
BotID: botID,
|
||||
Data: dataMap,
|
||||
}
|
||||
_, err = hir.Session.Request(http.MethodPost, "https://discord.com/api/v9/interactions", requestStruct)
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
# Haccerinteractions
|
||||
## Welcome to Haccerinteractions, a package for advanced selfbotters
|
||||
Haccerinteractions is a package that expands the selfbotting capabilities of discordgo by giving you the ability to run slash commands, get their output, and interact with message components like buttons.
|
||||
## Getting started
|
||||
After installing and importing Haccerinteractions, follow these steps.
|
||||
### Create a new discordgo session
|
||||
Because Haccerinteractions is powered by discordgo, you first need to make a session with this code:
|
||||
```go
|
||||
session,_:=discordgo.New("insert_token_here")
|
||||
```
|
||||
### Create a Haccerinteractions runner
|
||||
This will be the thing that runs commands and clicks buttons. Use this code to make a runner:
|
||||
```go
|
||||
runner:=haccerinteractions.NewRunner(session)
|
||||
```
|
||||
This will configure required parameters within your session as well as opening a gateway connection.
|
||||
### Get commands
|
||||
You first must get commands for a channel with this code:
|
||||
```go
|
||||
// You can leave the application/bot id empty.
|
||||
// The limit is ignored when the bot_id is set, however
|
||||
commands,err:=runner.GuildChannelGetSlashCommands("channel_id_here",10,"bot_id_here")
|
||||
```
|
||||
### Run Commands
|
||||
```go
|
||||
// Run a command.
|
||||
// Set arguments to nil to pass no arguments
|
||||
responseMessage,err:=runner.GuildChannelRunCommand(commands[0],nil,"channel_id_here")
|
||||
```
|
||||
### Interact with components
|
||||
```go
|
||||
// You can interact with various components by using different request data structs
|
||||
button:=responseMessage.Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.Button)
|
||||
runner.GuildChannelComponentRequest("channel_id_here",responseMessage.ID,"bot_id_here",button.CustomID,haccerinteractions.ButtonClickRequestData{})
|
||||
```
|
|
@ -0,0 +1,46 @@
|
|||
package haccerinteractions
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
)
|
||||
|
||||
// Run a command in a channel
|
||||
func (hir *haccerInteractionsRunner) GuildChannelRunCommand(c Command, args *[]CommandRunOption, gc GuildChannel) (*discordgo.Message, error) {
|
||||
if args == nil {
|
||||
args = &[]CommandRunOption{}
|
||||
}
|
||||
reqData := commandRunRequest{
|
||||
Type: 2,
|
||||
BotID: c.ApplicationID,
|
||||
GuildID: gc.GuildID,
|
||||
ChannelID: gc.ChannelID,
|
||||
SessionID: hir.Session.State.SessionID,
|
||||
Data: commandRunData{
|
||||
ID: c.ID,
|
||||
Type: c.Type,
|
||||
Name: c.Name,
|
||||
Version: c.Version,
|
||||
Options: *args,
|
||||
},
|
||||
}
|
||||
_, err := hir.Session.Request(http.MethodPost, "https://discord.com/api/v9/interactions", reqData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmdMutex := hir.getCommandMutex(c.Name)
|
||||
cmdMutex.Lock()
|
||||
commandRespChan := make(chan discordgo.Message)
|
||||
hir.Session.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
if m.Interaction == nil {
|
||||
return
|
||||
}
|
||||
if m.Interaction.User.ID == s.State.User.ID && m.Interaction.Name == c.Name {
|
||||
commandRespChan <- *m.Message
|
||||
cmdMutex.Unlock()
|
||||
}
|
||||
})
|
||||
cmdRespMsg := <-commandRespChan
|
||||
return &cmdRespMsg, nil
|
||||
}
|
Loading…
Reference in New Issue