-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmail_sync.rb
131 lines (107 loc) · 3.64 KB
/
mail_sync.rb
1
2
3
4
5
6
7
8
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
require 'bundler/setup'
Bundler.require
Dotenv.load
Octokit.auto_paginate = true
class MailgunClient
def initialize
@ml_members = {}
end
def conn
@conn ||= Faraday.new('https://api.mailgun.net/v3') do |conn|
conn.basic_auth('api', ENV['MAILGUN_API_KEY'])
conn.request :url_encoded
conn.response :json, :content_type => /\bjson$/
conn.adapter Faraday.default_adapter
end
end
def mailing_lists
@mailing_lists ||= Hash[*(conn.get('lists').body['items'].map { |ml| [ml['address'], ml] }.flatten)]
end
def create_mailing_list(name)
address = "#{name.downcase}@docrystal.org"
mailing_lists[address] ||= conn.post('lists', address: address, name: name, description: 'via GitHub', access_level: 'everyone').body['list']
end
def ml_members(name)
address = "#{name.downcase}@docrystal.org"
@ml_members[address] ||= Hash[*(
conn.get("lists/#{address}/members").body['items'].map { |m| [m['address'], m] }.flatten
)]
end
def add_ml_member(ml_name, name, address)
ml = "#{ml_name.downcase}@docrystal.org"
ml_members(ml_name)[address] ||= conn.post("lists/#{ml}/members", address: "#{name} <#{address}>", name: name, subscribed: 'yes', upsert: 'yes').body['member']
end
def remove_ml_member(ml, address)
ml = "#{ml.downcase}@docrystal.org"
conn.delete("lists/#{ml}/#{address}")
end
def routes
@routes ||= Hash[*(conn.get('routes').body['items'].map { |r| [r['description'], r] }.flatten)]
end
def add_route(id, from, to)
desc = "GitHub: #{id}"
routes[desc] ||= conn.post('routes', priority: 1, description: "GitHub: #{id}", expression: "match_recipient('#{from}')", action: "forward('#{to}')").body['route']
end
def remove_route(id)
conn.delete("routes/#{id}")
end
end
class MailSync
def initialize
@members = {}
end
def github
@github ||= Octokit::Client.new(access_token: ENV['GITHUB_ACCESS_TOKEN'])
end
def mailgun
@mailgun ||= MailgunClient.new
end
def member(id)
@members[id] ||= github.user(id)
end
def teams
@teams ||= Hash[*(
github.org_teams('docrystal').map { |team| team.members = team_members(team.id); [team.slug, team] }.flatten
)]
end
def team_members(id)
github.team_members(id).map { |u| all_members[u.login] }
end
def all_members
@all_members ||= Hash[*(
github.org_members('docrystal').map { |u| member(u.id) }.select { |u| u.email }.map { |u| [u.login, u] }.flatten
)]
end
def sync_teams
teams.each_pair do |slug, team|
mailgun.create_mailing_list(slug)
team.members.each do |member|
mailgun.add_ml_member(slug, member.login, member.email)
end
member_addresses = team.members.map { |m| m.email }
ml_members = mailgun.ml_members(slug).keys
remove_members = ml_members - member_addresses
remove_members.each do |address|
mailgun.remove_ml_member(slug, address)
end
end
end
def sync_info
all_members.values.each do |member|
mailgun.add_ml_member('info', member.login, member.email)
end
remove_members = mailgun.ml_members('info').keys - all_members.values.map { |m| m.email }
remove_members.each do |address|
mailgun.remove_ml_member('info', address)
end
end
def sync_members
all_members.values.each do |member|
mailgun.add_route(member.id, "#{member.login}@docrystal.org", member.email)
end
current_routes = Hash[*(mailgun.routes.values.map { |u| [u['description'].sub('GitHub: ', '').to_i, u['id']] }.flatten)]
(current_routes.keys - all_members.values.map { |m| m.id }).each do |id|
mailgun.remove_route(current_routes[id])
end
end
end