Class: FindGithubEmail::Finder

Inherits:
Object
  • Object
show all
Defined in:
lib/find_github_email/finder.rb

Overview

Finds a user’s GitHub email addres by their username using GitHub’s GrapQL API

Class Method Summary collapse

Class Method Details

.find(username) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/find_github_email/finder.rb', line 9

def self.find(username)
  response = Client.query(
    EmailQuery,
    variables: { username: username },
    context: { bearer: GithubAccessToken.github_access_token }
  )

  raise Errors::InvalidAccessToken if response.errors.any?

  data = response.data.user&.data

  raise Errors::NoGithubUser.new(username: username) unless data

  # See spec/find_github_email/finder_spec.rb for examples of what the data
  # format looks like
  found_emails =
    ([data["email"]] +
     find_emails(data["repositories"], username) +
     find_emails(data["repositoriesContributedTo"], username) +
     find_emails(data["topRepositories"], username)).
    uniq.
    compact.
    reject { |s| s == "" || s =~ /noreply.github.com/ }

  raise Errors::NoEmailData.new(username: username) if found_emails.empty?

  found_emails
end

.find_emails(data, username) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/find_github_email/finder.rb', line 38

def self.find_emails(data, username)
  username = username.downcase
  data["nodes"].compact.flat_map do |node|
    node["refs"]["nodes"].flat_map do |sub_node|
      author = sub_node["target"]["author"]
       = author["user"]&.[]"login"
      if [, author["name"]].compact.map(&:downcase).include?(username)
        author["email"]
      end
    end
  end
end