plugins

package
v0.0.0-...-eaa097e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 26, 2020 License: MIT Imports: 24 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var CurrencyHandler = base.Handler{
	Name:        "Currency",
	Description: "Currency converter.",
	Event:       irc.Message,
	Run: func(bot *base.Bot, msg *msg.Message) (bool, error) {

		config := bot.Config()

		client := http.Client{}

		returnData := "Currency error, usage: !c <amount> <from> <to>"

		if msg.Params[0] == config.Identification.Nick || msg.Prefix.Name == "nibbler" || msg.Prefix.Name == "geoffrey-bot" {
			return false, nil
		}

		go func(bot *base.Bot, channel string) {
			if strings.HasPrefix(msg.Trailing, "!c") {
				if len(msg.Trailing) > 2 {
					cData := strings.Split(msg.Trailing, " ")

					if len(cData) == 4 {
						url := fmt.Sprintf("https://api.exchangerate.host/latest?base=%s&amount=%s", cData[2], cData[1])

						request, reqErr := http.NewRequest(http.MethodGet, url, nil)
						if reqErr != nil {
							log.Errorf("[currency] Failed NewRequest: %s", reqErr)
						}

						resp, respErr := client.Do(request)
						if respErr != nil {
							log.Errorf("[currency] Failed client.Do: %s", respErr)
						}

						cConvertTo := fmt.Sprintf("rates.%s", strings.ToUpper(cData[3]))

						body, bodyErr := ioutil.ReadAll(resp.Body)
						if bodyErr != nil {
							log.Errorf("[currency] Failed ReadAll: %s", bodyErr)
						}

						cValue := gjson.GetBytes(body, cConvertTo)

						returnData = fmt.Sprintf("%s %s in %s: %v", cData[1], cData[2], cData[3], cValue)
					}
				}
				bot.Send(channel, returnData)
			}
		}(bot, msg.Params[0])
		return true, nil
	},
}

CurrencyHandler extracts title from posted links and sends them to the channel.

View Source
var GitHubHandler = base.Handler{
	Name:        "GitHub",
	Description: "Extracts information from GitHub when a link is posted.",
	Event:       irc.Message,
	Init: func(bot *base.Bot) (bool, error) {

		config := bot.Config()

		if settings, ok := config.Settings["github"]; ok {
			if authentication, ok := settings.(map[interface{}]interface{})["authentication"]; ok {
				if key, ok := authentication.(string); ok {
					ctx := context.Background()
					ts := oauth2.StaticTokenSource(
						&oauth2.Token{AccessToken: key},
					)
					tc := oauth2.NewClient(ctx, ts)
					client = github.NewClient(tc)
				}
			}
		}

		if client == nil {
			log.Warnf("[github] Could not get authentication details.")
			client = github.NewClient(nil)
		}

		return true, nil
	},
	Run: func(bot *base.Bot, msg *msg.Message) (bool, error) {

		config := bot.Config()

		if msg.Params[0] == config.Identification.Nick {
			return false, nil
		}

		urls := xurls.Relaxed.FindAllString(msg.Trailing, -1)

		wg.Add(len(urls))

		if len(urls) < 1 {
			return false, nil
		}

		db := bot.Db()

		if client == nil {
			log.Warnf("[github] Could not get authentication details.")
			client = github.NewClient(nil)
		}

		db.View(func(txn *badger.Txn) error {

			for _, text := range urls {
				match := matcher.FindStringSubmatch(text)
				if len(match) > 0 {
					if _, err := url.Parse(text); err != nil {
						log.Errorf("[github] Could not parse url '%s': %v", text, err)
					} else {

						value, err := txn.Get([]byte(text))

						if err != nil {
							if err != badger.ErrKeyNotFound {
								log.Errorf("[github] Could not query the database: %v", err)
							} else {
								log.Infof("[github] Fetching GitHub information for url '%s'", text)

								if match[3] != "" {
									repo, _, err := client.Repositories.Get(context.Background(), match[1], match[3])
									if err != nil {
										log.Errorf("[github] GitHub returned an error response for URL '%s': %v", text, err)
									} else {

										sendMsg := fmt.Sprintf("[%s]", irc.Foreground("GitHub", irc.Green))
										sendMsg += fmt.Sprintf("[%s] %s ", irc.Foreground(repo.GetOrganization().GetLogin(), irc.Blue), repo.GetName())

										commits, _, err := client.Repositories.ListCommits(context.Background(), match[1], match[3], &github.CommitsListOptions{})

										if err != nil {
											log.Errorf("[github] Could not fetch commits for '%s/%s': %v", match[1], match[2], err)
										} else {
											commitMessage := commits[0].GetCommit().GetMessage()
											if len(commitMessage) > 50 {
												commitMessage = commitMessage[0:47]
												commitMessage += "..."
											}
											sendMsg += fmt.Sprintf("(%s) ", irc.Foreground(commitMessage, irc.Orange))
											sendMsg += fmt.Sprintf("(%s) ", irc.Foreground(humanize.Time(repo.GetUpdatedAt().Time), irc.Blue))
											sendMsg += fmt.Sprintf("(%s ⭐) ", irc.Foreground(strconv.Itoa(repo.GetStargazersCount()), irc.Brown))
											sendMsg += fmt.Sprintf("(%s 🍴) ", irc.Foreground(strconv.Itoa(repo.GetForksCount()), irc.Brown))

											bot.Send(msg.Params[0], sendMsg)
										}
									}
								} else {
									user, _, err := client.Users.Get(context.Background(), match[1])

									if err != nil {
										log.Errorf("[github] GitHub returned an error response for URL '%s': %v", text, err)
									} else {
										sendMsg := fmt.Sprintf("[%s]", irc.Foreground("GitHub", irc.Green))
										sendMsg += fmt.Sprintf("[%s] %s ", irc.Foreground(user.GetType(), irc.Blue), user.GetName())
										if user.GetPublicRepos() > 0 {
											sendMsg += fmt.Sprintf("(repositories: %s) ", irc.Foreground(strconv.Itoa(user.GetPublicRepos()), irc.Purple))
										}
										if user.GetPublicGists() > 0 {
											sendMsg += fmt.Sprintf("(gists: %s) ", irc.Foreground(strconv.Itoa(user.GetPublicGists()), irc.Purple))
										}
										if user.GetType() == "User" && user.Company != nil {
											sendMsg += fmt.Sprintf("company: %s)", irc.Foreground(strings.TrimSpace(user.GetCompany()), irc.Teal))
										}
										bot.Send(msg.Params[0], sendMsg)
									}
								}
							}
						} else {
							value.Value(func(val []byte) error {
								bot.Send(msg.Params[0], fmt.Sprintf("[%s] %s",
									irc.Foreground("GitHub", irc.Blue),
									irc.Bold(
										string(val),
									),
								))
								return nil
							})
						}
					}
				}
			}

			return nil
		})

		ghWg.Wait()

		return true, nil
	},
}

GitHubHandler extracts information from GitHub when a link is posted.

View Source
var JoinHandler = bot.Handler{
	Name:        "Join",
	Description: "Joins all pre-defined channels after registration",
	Event:       irc.Welcome,
	Run: func(bot *bot.Bot, msg *msg.Message) (bool, error) {

		config := bot.Config()

		for _, channel := range config.Channels {
			bot.Join(channel)
		}

		return true, nil
	},
}

JoinHandler will join all configured channels after bot has been registered.

View Source
var PingHandler = bot.Handler{
	Name:        "Ping",
	Description: "Handles ping requests from the server",
	Event:       irc.Ping,
	Run: func(bot *bot.Bot, msg *msg.Message) (bool, error) {
		bot.Pong(msg.Trailing)
		return true, nil
	},
}

PingHandler will respond to ping requests

View Source
var PongHandler = bot.Handler{
	Name:        "Pong",
	Description: "Handles pong responses from the server",
	Event:       "PONG",
	Run: func(bot *bot.Bot, msg *msg.Message) (bool, error) {
		if num, err := strconv.ParseInt(msg.Trailing, 10, 64); err == nil {

			sent := time.Unix(0, num)

			log.Infof("[pong] Latency is %s", time.Since(sent))
		}

		return true, nil
	},
}

PongHandler will handle pong responses

View Source
var RegistrationHandler = bot.Handler{
	Name:        "Registration",
	Description: "Registers the bot to the IRC server",
	Event:       irc.Notice,
	Run: func(bot *bot.Bot, msg *msg.Message) (bool, error) {
		if msg.Trailing == "*** Looking up your hostname..." {

			config := bot.Config()

			bot.Nick(config.Identification.Nick)
			bot.User(config.Identification.User, config.Identification.Name)

			return true, nil
		}

		return false, nil
	},
}

RegistrationHandler will register the bot to the server

View Source
var TitleHandler = base.Handler{
	Name:        "Title",
	Description: "Extracts title and website information upon detecting URLs",
	Event:       irc.Message,
	Init: func(bot *base.Bot) (bool, error) {

		config := bot.Config()

		if settings, ok := config.Settings["title"]; ok {
			if list, ok := settings.(map[interface{}]interface{})["blacklist"]; ok {
				for _, matcher := range list.([]interface{}) {
					if regex, err := regexp.Compile(matcher.(string)); err != nil {
						log.Errorf("[title] Could not compile regex '%s'", matcher)
					} else {
						blacklist = append(blacklist, regex)
					}
				}
			}
		}

		return true, nil
	},
	Run: func(bot *base.Bot, msg *msg.Message) (bool, error) {

		config := bot.Config()

		if msg.Params[0] == config.Identification.Nick || msg.Prefix.Name == "nibbler" || msg.Prefix.Name == "geoffrey-bot" {
			return false, nil
		}

		urls := xurls.Relaxed.FindAllString(msg.Trailing, -1)

		wg.Add(len(urls))

		if len(urls) < 1 {
			return false, nil
		}

		db := bot.Db()

		db.View(func(txn *badger.Txn) error {

			for _, text := range urls {

				skip := false

				for _, matcher := range blacklist {
					if matcher.MatchString(text) {
						log.Infof("[title] Skipped link '%s' due to blacklist.", text)
						skip = true
						break
					}
				}

				if !skip {
					if uri, err := url.Parse(text); err != nil {
						log.Errorf("[title] Could not parse url '%s': %v", text, err)
					} else {

						value, err := txn.Get([]byte(text))

						if err != nil {
							if err != badger.ErrKeyNotFound {
								log.Errorf("[title] Could not query the database: %v", err)
							} else {
								log.Infof("[title] Fetching title for url '%s'", text)

								go fetchTitle(bot, uri, msg.Params[0], text)
							}
						} else {
							value.Value(func(val []byte) error {
								bot.Send(msg.Params[0], fmt.Sprintf("[%s] %s",
									irc.Foreground("LINK", irc.Green),
									irc.Bold(
										string(val),
									),
								))
								return nil
							})
						}
					}
				}
			}

			return nil
		})

		wg.Wait()

		return true, nil
	},
}

TitleHandler extracts title from posted links and sends them to the channel.

View Source
var YouTubeHandler = base.Handler{
	Name:        "YouTube",
	Description: "YouTube parser that extracts title and duration.",
	Event:       irc.Message,
	Run: func(bot *base.Bot, msg *msg.Message) (bool, error) {

		config := bot.Config()

		if settings, ok := config.Settings["youtube"]; ok {
			if key, ok := settings.(map[interface{}]interface{})["key"]; ok {
				if authenticationKey, ok := key.(string); ok {
					developerKey = authenticationKey
				}
			}
		}

		service, err := youtube.NewService(context.Background(), option.WithAPIKey(developerKey))

		if err != nil {
			log.Errorf("Error creating new YouTube client: %v", err)
			return false, err
		}

		if msg.Params[0] == config.Identification.Nick || msg.Prefix.Name == "nibbler" || msg.Prefix.Name == "geoffrey-bot" {
			return false, nil
		}

		urls := xurls.Relaxed.FindAllString(msg.Trailing, -1)

		wg.Add(len(urls))

		if len(urls) < 1 {
			return false, nil
		}

		for _, text := range urls {
			if uri, err := url.Parse(text); err != nil {
				log.Errorf("[title] Could not parse url '%s': %v", text, err)
			} else {
				go func(bot *base.Bot, uri *url.URL, channel string) {

					if uri.Scheme == "" {
						uri.Scheme = "http"
					}

					if !strings.Contains(uri.Host, "youtube") && !strings.Contains(uri.Host, "youtu.be") {
						return
					}

					URL := uri.String()
					var videoID string

					if strings.Contains(uri.Host, "youtube") {
						var tempID string

						tempID = strings.Split(URL, "=")[1]
						tempID = strings.Split(tempID, "&")[0]

						videoID = tempID
					}

					if strings.Contains(uri.Host, "youtu.be") {
						videoID = strings.Split(URL, "https://youtu.be/")[1]
					}

					call := service.Videos.List("snippet,contentDetails").Id(videoID)

					response, err := call.Do()

					if err != nil {
						log.Errorf("[title] Could not fetch website '%s': %v", uri.String(), err)
					} else {
						for _, video := range response.Items {
							if video.ContentDetails.Duration == "P0D" {

								bot.Send(channel, fmt.Sprintf("[%v] %v (%s)", irc.Foreground("YouTube", irc.Green), irc.Bold(video.Snippet.Title), irc.Foreground("LIVE", irc.Orange)))
							} else {
								parsedDur := strings.ToLower(video.ContentDetails.Duration[2:])
								duration, durationErr := durafmt.ParseString(parsedDur)

								if durationErr != nil {
									fmt.Println("Error duration:", durationErr)
								}

								bot.Send(channel, fmt.Sprintf("[%v] %v (duration: %v)", irc.Foreground("YouTube", irc.Green), irc.Bold(video.Snippet.Title), duration))
							}
						}
					}

					wg.Done()
				}(bot, uri, msg.Params[0])
			}
		}

		wg.Wait()

		return true, nil
	},
}

YouTubeHandler extracts title from posted links and sends them to the channel.

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL