mirror of
https://github.com/Penguin-71630/meme-bot-frontend-dc.git
synced 2026-03-12 12:30:15 +08:00
added slash web
This commit is contained in:
10
README.md
10
README.md
@@ -7,3 +7,13 @@ https://hackmd.io/@penguin71630/go-final-project
|
||||
Note:
|
||||
- View API document: `make viewapi`
|
||||
|
||||
<!-- My friend wrote this login test script. So our goal is to make bot generates a link and send this link in the form of Ephemeral message to user. User can open the webpage with provided link (this way we can skip the hassles over Discord OAuth in webpage), and use some magic mechanism (my friend said cookie but I'm not familiar with it).
|
||||
|
||||
Here's my understanding of the entire workflow:
|
||||
1. User types /web in discord chat room.
|
||||
2. Bot calls POST /auth/get-login-url with payload {
|
||||
"userId": "string"
|
||||
}, and receive a response: {
|
||||
"loginUrl": "http://localhost:8080/login?token=T2KsDcj-kiULQLdotioxmsZG"
|
||||
}
|
||||
3. -->
|
||||
@@ -31,6 +31,14 @@ type AliasesResponse struct {
|
||||
Aliases []string `json:"aliases"`
|
||||
}
|
||||
|
||||
type GenLoginURLRequest struct {
|
||||
UserID string `json:"userId"`
|
||||
}
|
||||
|
||||
type GenLoginURLResponse struct {
|
||||
LoginURL string `json:"loginUrl"`
|
||||
}
|
||||
|
||||
func NewClient(baseURL string) *Client {
|
||||
return &Client{
|
||||
baseURL: baseURL,
|
||||
@@ -216,3 +224,41 @@ func (c *Client) GetImageFile(id string) ([]byte, error) {
|
||||
|
||||
return io.ReadAll(resp.Body)
|
||||
}
|
||||
|
||||
func (c *Client) GenerateLoginURL(userID string) (string, error) {
|
||||
url := fmt.Sprintf("%s/auth/gen-login-url", c.baseURL)
|
||||
|
||||
reqBody := GenLoginURLRequest{UserID: userID}
|
||||
jsonBody, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonBody))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
// TODO: Set preshared key authorization
|
||||
req.Header.Set("Authorization", "Bearer poop")
|
||||
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
return "", fmt.Errorf("API returned status %d: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
var result GenLoginURLResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return result.LoginURL, nil
|
||||
}
|
||||
|
||||
36
bot/bot.go
36
bot/bot.go
@@ -48,7 +48,7 @@ func New(cfg *config.Config) (*Bot, error) {
|
||||
return bot, nil
|
||||
}
|
||||
|
||||
func (b *Bot) registerSlashCommands() error {
|
||||
func (b *Bot) registerSlashCommands(guildID string) error {
|
||||
commands := []*discordgo.ApplicationCommand{
|
||||
{
|
||||
Name: "ping",
|
||||
@@ -70,10 +70,14 @@ func (b *Bot) registerSlashCommands() error {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "web",
|
||||
Description: "Get a login link to the web interface",
|
||||
},
|
||||
}
|
||||
|
||||
for _, cmd := range commands {
|
||||
_, err := b.session.ApplicationCommandCreate(b.session.State.User.ID, "", cmd)
|
||||
_, err := b.session.ApplicationCommandCreate(b.session.State.User.ID, guildID, cmd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot create command %s: %w", cmd.Name, err)
|
||||
}
|
||||
@@ -82,6 +86,21 @@ func (b *Bot) registerSlashCommands() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bot) clearSlashCommands(guildID string) error {
|
||||
commands, err := b.session.ApplicationCommands(b.session.State.User.ID, guildID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, cmd := range commands {
|
||||
err := b.session.ApplicationCommandDelete(b.session.State.User.ID, guildID, cmd.ID)
|
||||
if err != nil {
|
||||
log.Printf("Failed to delete command %s: %v", cmd.Name, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bot) registerHandlers() {
|
||||
b.session.AddHandler(b.onReady)
|
||||
b.session.AddHandler(b.onMessageCreate)
|
||||
@@ -91,8 +110,17 @@ func (b *Bot) registerHandlers() {
|
||||
func (b *Bot) onReady(s *discordgo.Session, event *discordgo.Ready) {
|
||||
log.Printf("Logged in as: %v#%v", s.State.User.Username, s.State.User.Discriminator)
|
||||
|
||||
// For development: set your guild ID here for instant updates
|
||||
// For production: use "" for global commands
|
||||
guildID := "1377176828833169468" // Replace with your Discord server ID for faster testing
|
||||
|
||||
// clear slash commands
|
||||
if err := b.clearSlashCommands(guildID); err != nil {
|
||||
log.Printf("Error clearing slash commands: %v", err)
|
||||
}
|
||||
|
||||
// Register slash commands
|
||||
if err := b.registerSlashCommands(); err != nil {
|
||||
if err := b.registerSlashCommands(guildID); err != nil {
|
||||
log.Printf("Error registering slash commands: %v", err)
|
||||
}
|
||||
|
||||
@@ -115,6 +143,8 @@ func (b *Bot) onInteractionCreate(s *discordgo.Session, i *discordgo.Interaction
|
||||
b.handleSlashGreet(s, i)
|
||||
case "echo":
|
||||
b.handleSlashEcho(s, i)
|
||||
case "web":
|
||||
b.handleSlashWeb(s, i)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,3 +69,33 @@ func (b *Bot) handleSlashEcho(s *discordgo.Session, i *discordgo.InteractionCrea
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (b *Bot) handleSlashWeb(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
var userID string
|
||||
if i.Member != nil {
|
||||
userID = i.Member.User.ID
|
||||
} else if i.User != nil {
|
||||
userID = i.User.ID
|
||||
}
|
||||
|
||||
// Call backend API
|
||||
loginURL, err := b.apiClient.GenerateLoginURL(userID)
|
||||
if err != nil {
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: "❌ Failed to generate login URL: " + err.Error(),
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: fmt.Sprintf("🔗 **Click here to access the web page:**\n%s\n\n", loginURL),
|
||||
Flags: discordgo.MessageFlagsEphemeral,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user