Skip to content

Commit

Permalink
Add subaccounts (#310)
Browse files Browse the repository at this point in the history
* DE-1201 add posibility to manage subaccounts

* DE-1201 add test mockup

* DE-1201 CRUD for subaccounts

* DE-1201 add ability to pass subaccount_id to headers

* DE-1201 fix version
  • Loading branch information
mgrishko authored Dec 4, 2023
1 parent 74f4232 commit 847ff77
Show file tree
Hide file tree
Showing 12 changed files with 501 additions and 4 deletions.
1 change: 1 addition & 0 deletions .ruby-env.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
MAILGUN_APIKEY : '<MAILGUN_APIKEY>'
MAILGUN_PUB_APIKEY : '<MAILGUN_PUBLIC_APIKEY>'
MAILGUN_TESTDOMAIN : '<MAILGUN_SANDBOX_DOMAIN>'

4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

## [1.2.12] - 2023-10-22
## [1.2.13] - 2023-11-25

### Added

- Templates CRUD support (https://github.com/mailgun/mailgun-ruby/pull/300).
- Subaccounts API support (https://github.com/mailgun/mailgun-ruby/pull/300).

### Fixed

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ This SDK includes the following components:
- [Domains](docs/Domains.md)
- [Webhooks](docs/Webhooks.md)
- [Events](docs/Events.md)
- [Snippets](docs/Snippets.md)
- [Subaccounts](docs/Subaccounts.md)
- [Suppressions](docs/Suppressions.md)
- [Templates](docs/Templates.md)
- [EmailValidation](docs/EmailValidation.md)
Expand Down
68 changes: 68 additions & 0 deletions docs/Subaccounts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
Mailgun - [Subaccounts](https://help.mailgun.com/hc/en-us/articles/16380043681435-Subaccounts)
====================

Rails
-----

The library can be initialized with a Rails initializer containing similar:
```ruby
Mailgun.configure do |config|
config.api_key = 'your-secret-api-key'
end
```
Or have the initializer read your environment setting if you prefer.

```ruby
Mailgun.api_key = 'your-secret-api-key'
```

```ruby
mb_obj = Mailgun::Subaccounts.new

# Get subaccounts list
mb_obj.get_subaccounts(limit: 10, skip: 0, sort: 'ask', enabled: true)
=> {"subaccounts"=>[{"id"=>"XYZ", "name"=>"test.subaccount1", "status"=>"open"}, {"id"=>"YYY", "name"=>"test.subaccount2", "status"=>"open"}], "total"=>2}

# Get subaccount information
mb_obj.info(subaccount_id)
=> {"subaccount"=>{"id"=>"XYZ", "name"=>"test.subaccount1", "status"=>"open"}

# Add Subaccount
mb_obj.create(name)
=> {"subaccount"=>{"id"=>"XYZ", "name"=>"test.subaccount1", "status"=>"open"}}

# Disable
mb_obj.disable(subaccount_id)
=> {"subaccount"=>{"id"=>"XYZ", "name"=>"test.subaccount1", "status"=>"disabled"}}

# Enable
mb_obj.enable(subaccount_id)
=> {"subaccount"=>{"id"=>"XYZ", "name"=>"test.subaccount1", "status"=>"open"}}
```

Primary accounts can make API calls on behalf of their subaccounts.
```ruby
# First, instantiate the Mailgun Client with your API key
mg_client = Mailgun::Client.new 'your-api-key'
mg_client.set_subaccount('SUBACCOUNT_ID')

# Define your message parameters
message_params = { from: 'bob@SUBACCOUNT_DOMAIN',
to: '[email protected]',
subject: 'The Ruby SDK is awesome!',
text: 'It is really easy to send a message!'
}

# Send your message through the client
# Note: This will not actually hit the API, and will return a generic OK response.
mg_client.send_message('SUBACCOUNT_DOMAIN', message_params)

# Reset subaccount for primary usage
mg_client.reset_subaccount
```


More Documentation
------------------
See the official [Mailgun Docs](https://documentation.mailgun.com/en/latest/subaccounts.html#subaccounts)
for more information.
1 change: 1 addition & 0 deletions lib/mailgun.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
require 'mailgun/domains/domains'
require 'mailgun/webhooks/webhooks'
require 'mailgun/templates/templates'
require 'mailgun/subaccounts/subaccounts'

# Module for interacting with the sweet Mailgun API.
#
Expand Down
11 changes: 11 additions & 0 deletions lib/mailgun/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module Mailgun
#
# See the Github documentation for full examples.
class Client
SUBACCOUNT_HEADER = 'X-Mailgun-On-Behalf-Of'.freeze

def initialize(api_key = Mailgun.api_key,
api_host = Mailgun.api_host || 'api.mailgun.net',
Expand Down Expand Up @@ -50,6 +51,16 @@ def set_api_key(api_key)
@http_client.options[:password] = api_key
end

# Add subaccount id to headers
def set_subaccount(subaccount_id)
@http_client.options[:headers] = { SUBACCOUNT_HEADER => subaccount_id }
end

# Reset subaccount for primary usage
def reset_subaccount
@http_client.options[:headers].delete(SUBACCOUNT_HEADER)
end

# Client is in test mode?
#
# @return [Boolean] Is the client set in test mode?
Expand Down
84 changes: 84 additions & 0 deletions lib/mailgun/subaccounts/subaccounts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
require 'mailgun/exceptions/exceptions'

module Mailgun

# A Mailgun::Subaccounts object is a simple CRUD interface to Mailgun Subaccounts.
# Uses Mailgun
class Subaccounts
attr_reader :client

# Public: creates a new Mailgun::Subaccounts instance.
# Defaults to Mailgun::Client
def initialize(client = Mailgun::Client.new(Mailgun.api_key, Mailgun.api_host || 'api.mailgun.net', 'v5'))
@client = client
end

# Public: Get subaccounts
# options - [Hash] of
# limit - [Integer] Maximum number of records to return. (10 by default)
# skip [Integer] Number of records to skip
# sort [Array] “asc” or “desc”
# enabled [boolean] (Optional) Returns all enabled/disabled subaccounts, defaults to all if omitted
# headers - [String] (Optional) Key Value json dictionary of headers to be stored with the subaccount.
# ex.('{"Subject": "{{subject}}"}')
#
# Returns [Array] A list of subaccounts (hash)
def list(options = {})
client.get("accounts/subaccounts", options).to_h!
end
alias_method :get_subaccounts, :list

# Public: Get subaccount information
#
# subaccount_id - [String] subaccount name to lookup for
# options - [Hash] of
# headers - [String] (Optional) Key Value json dictionary of headers to be stored with the subaccount.
# ex.('{"Subject": "{{subject}}"}')
#
# Returns [Hash] Information on the requested subaccount.
def info(subaccount_id, options = {})
fail(ParameterError, 'No Id of subaccount specified', caller) unless subaccount_id
client.get("accounts/subaccounts/#{subaccount_id}", options).to_h!
end

# Public: Add Subaccount
#
# name - [String] Name of the subaccount being created
# options - [Hash] of
# name - [String] Name of the subaccount being created.
# headers - [String] (Optional) Key Value json dictionary of headers to be stored with the subaccount.
# ex.('{"Subject": "{{subject}}"}')
#
# Returns [Hash] of created subaccount
def create(name, options = {})
fail(ParameterError, 'No name given to create subaccount', caller) unless name
client.post("accounts/subaccounts", options.merge!(name: name)).to_h!
end

# Public: Disable a subaccount
#
# subaccount_id - [String] subaccount name to disable
# options - [Hash] of
# headers - [String] (Optional) Key Value json dictionary of headers to be stored with the subaccount.
# ex.('{"Subject": "{{subject}}"}')
#
# Returns [Hash] Information on the requested subaccount.
def disable(subaccount_id, options = {})
fail(ParameterError, 'No Id of subaccount specified', caller) unless subaccount_id
client.post("accounts/subaccounts/#{subaccount_id}/disable", options).to_h!
end

# Public: Enable a subaccount
#
# subaccount_id - [String] subaccount name to enable
# options - [Hash] of
# headers - [String] (Optional) Key Value json dictionary of headers to be stored with the subaccount.
# ex.('{"Subject": "{{subject}}"}')
#
# Returns [Hash] Information on the requested subaccount.
def enable(subaccount_id, options = {})
fail(ParameterError, 'No Id of subaccount specified', caller) unless subaccount_id
client.post("accounts/subaccounts/#{subaccount_id}/enable", options).to_h!
end
end
end
2 changes: 1 addition & 1 deletion lib/mailgun/version.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# It's the version. Yeay!
module Mailgun
VERSION = '1.2.12'
VERSION = '1.2.13'
end
2 changes: 2 additions & 0 deletions lib/railgun/mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ def initialize(config)
def deliver!(mail)
@mg_domain = set_mg_domain(mail)
@mg_client.set_api_key(mail[:api_key].value) if mail[:api_key].present?
@mg_client.set_subaccount(mail[:subaccount_id].value) if mail[:subaccount_id].present?

mail[:domain] = nil if mail[:domain].present?
mail[:api_key] = nil if mail[:api_key].present?
mail[:subaccount_id] = nil if mail[:subaccount_id].present?

mg_message = Railgun.transform_for_mailgun(mail)
response = @mg_client.send_message(@mg_domain, mg_message)
Expand Down
2 changes: 1 addition & 1 deletion mailgun.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'bundler', '>= 1.16.2'
spec.add_development_dependency 'rspec', '~> 3.8.0'
spec.add_development_dependency 'rake', '~> 12.3.2'
spec.add_development_dependency 'webmock', '~> 3.4.2'
spec.add_development_dependency 'webmock', '~> 3.7'
spec.add_development_dependency 'pry', '~> 0.11.3'
spec.add_development_dependency 'vcr', '~> 3.0.3'
spec.add_development_dependency 'simplecov', '~> 0.16.1'
Expand Down
58 changes: 58 additions & 0 deletions spec/integration/subaccounts_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
require 'spec_helper'
require 'mailgun'

vcr_opts = { :cassette_name => "subaccounts" }

describe 'For the subaccounts endpoints', vcr: vcr_opts do
let(:name) { 'test.subaccount' }
let(:subaccount_id) { 'xxx' }

before(:all) do
mg_client = Mailgun::Client.new(APIKEY, APIHOST, 'v5')
@mg_obj = Mailgun::Subaccounts.new mg_client
end

describe '#list' do
it 'returns a list of templates' do
result = @mg_obj.list

expect(result).to eq({"subaccounts"=>[{"id"=>"xxx", "name"=>"test-ruby-lib", "status"=>"open"}], "total"=>1})
end
end

describe '#create' do
it 'creates the subaccount' do
result = @mg_obj.create(name)

expect(result).to eq({"subaccount"=>{"id"=>"xxx", "name"=>"test.subaccount", "status"=>"open"}})
end
end


describe '#info' do
it 'gets the templates info' do
result = @mg_obj.info(subaccount_id)

expect(result).to eq({"subaccount"=>{"id"=>"xxx", "name"=>"test-ruby-lib", "status"=>"open"}})
end
end



describe '#enable' do
it 'enables the subaccount' do
result = @mg_obj.enable(subaccount_id)

expect(result).to eq({"subaccount"=>{"id"=>"xxx", "name"=>"test-ruby-lib", "status"=>"open"}})
end
end

describe '#disable' do
it 'disables the subaccount' do
result = @mg_obj.disable(subaccount_id)

expect(result).to eq({"subaccount"=>{"id"=>"xxx", "name"=>"test-ruby-lib", "status"=>"disabled"}})
end
end

end
Loading

0 comments on commit 847ff77

Please sign in to comment.