Since we've launched our platform, we're building to enhance our DNSimple experience. We built a Slack application, a Telegram bot, and other fun experiments.
Good news: you can build your own addon too!
This is a step-by-step guide to write it with our Ruby client and Hanami.
Before we start, please make sure to have:
- Ruby (with Bundler)
- A DNSimple Sandbox account
DNSimple OAuth app
Login into your DNSimple Sandbox account, and create an OAuth application by entering
http://localhost:2300 as Homepage URL and
http://localhost:2300/auth/dnsimple/callback as Authorization Callback URL.
Each OAuth app has its own Client ID and Client Secret, please save this information in a safe place, you're going need it soon.
DNSimple test domain
Register a test domain, so you can use it for this tutorial. Please note that this is a testing environment: no money will be charged, and the domain won't resolve for real.
Now we can setup our project. Install Hanami (
gem install hanami) and then run
hanami new hello_domains --test=rspec.
Voilà we have a new skeleton project to work with!
Enter in the newly created directory (
hello_domains) and edit
.env.development, adding the following lines:
DNSIMPLE_CLIENT_ID="..." DNSIMPLE_CLIENT_SECRET="..." DNSIMPLE_BASE_URL="https://api.sandbox.dnsimple.com"
Please replace the dots with the Client ID and the Client Secret from the step above.
Before we start the web server of the project, we need to add a few gems to our
gem 'dnsimple' gem 'omniauth' gem 'omniauth-dnsimple', github: 'dnsimple/omniauth-dnsimple'
We can now run
bundle and then
bundle exec hanami server.
This last command will start the web server and the application will be available at http://localhost:2300.
Implementing the signup
Our project is up and running, but it isn't so useful for now. Let's implement the signup, so we can recognize the DNSimple user that is using our addon.
The authentication is made via OAuth 2 (DNSimple is a provider).
For the purpose of this example we can use
The authentication flow requires HTTP sessions to be enabled, we need to edit
apps/web/application.rb and uncomment the following line:
sessions :cookie, secret: ENV['WEB_SESSIONS_SECRET']
While still in
apps/web/application.rb, we should mount the OmniAuth Rack middleware.
This is a generic stack where we can add support for many providers at once.
For instance, an application may support GitHub and Twitter providers.
In our case, we want just add DNSimple strategy (in OmniAuth terminology).
Please note that this strategy is provided by
middleware.use OmniAuth::Builder do provider :dnsimple, ENV['DNSIMPLE_CLIENT_ID'], ENV['DNSIMPLE_CLIENT_SECRET'], sandbox: true end
These two environment variables (
ENV) are the same we set up before in
With the OAuth setup done, we can now create an action to let the users of the addon sign in. Run the following command:
bundle exec hanami generate action web sessions#create --method=GET --url=/auth/:provider/callback --skip-view
This will create a few files. The most important file is:
module Web::Controllers::Sessions class Create include Web::Action def call(params) data = extract_oauth_params(params.env) user = UserRepository.new.find_or_create_by_uid(data['uid'], data) session[:user_id] = user.id session[:user_email] = user.email redirect_to "/" end private OMNIAUTH_AUTH = 'omniauth.auth'.freeze def extract_oauth_params(env) uid = env.dig(OMNIAUTH_AUTH, 'uid') info = env.dig(OMNIAUTH_AUTH, 'info') token = env.dig(OMNIAUTH_AUTH, 'credentials', 'token') info.merge('uid' => uid, 'token' => token) end end end
The first step is to extract the OAuth data from the Rack environment, then we can retrieve a reference to the user (if it doesn't exist yet), and finally we can store its ID in the session.
Before we try we need to implement a few missing pieces.
First of all, we need the home page:
bundle exec hanami generate action web home#index --url=/
Let's edit the application template (
<!DOCTYPE html> <html> <head> <title>Hello Domains</title> <%= favicon %> </head> <body> Hello <%= session[:user_email] || "Stranger" %>! <%= yield %> </body> </html>
Now we need a model to persist our data.
bundle exec hanami generate model user
This command will generate a bunch of files.
The first to edit is the database migration. It's located under
db/migrations and its file name starts with a timestamp (e.g.
Hanami::Model.migration do change do create_table :users do primary_key :id column :uid, Integer, null: false, unique: true column :type, String, null: false column :email, String, null: false column :token, String, null: false column :created_at, DateTime, null: false column :updated_at, DateTime, null: false end end end
After we edit the migration, we can create the database (if it doesn't exist) and migrate it:
bundle exec hanami db prepare
Now we need to implement the find or create method used by the action above:
# lib/hello_domains/repositories/user_repository.rb class UserRepository < Hanami::Repository def find_or_create_by_uid(uid, data) by_uid(uid) or create(data) end def by_uid(uid) users.where(uid: uid).one end end
Let's see if it works. Start the server (
bundle exec hanami server) and then visit http://localhost:2300/auth/dnsimple.
You should see a DNSimple authorization page: accept and proceed.
Now DNSimple has redirected you back to the addon, where you should see a message like
Great! You've just implemented the authentication process.
Fetch the domains
Now that we have connected our addon with DNSimple, we can use our official Ruby client to fetch our domains.
apps/web/controllers/home/index.rb with the following contents:
module Web::Controllers::Home class Index include Web::Action expose :domains def call(params) @domains =  return if session[:user_id].nil? current_user = UserRepository.new.find(session[:user_id]) client = Dnsimple::Client.new(base_url: ENV['DNSIMPLE_BASE_URL'], access_token: current_user.token) @domains = client.domains.list_domains(current_user.uid).data end end end
At this point we want to show the domains in an HTML table.
For this purpose we need to edit the template:
<% if domains.empty? %> <p>Sorry, there aren't domains. Please <%= link_to "sign in", "/auth/dnsimple" %></p> <% else %> <table> <tr> <th>Name</th> </tr> <% domains.each do |domain| %> <tr> <td><%= domain.name %></td> </tr> <% end %> </table> <% end %>
Start the server again and visit http://localhost:2300, now you should see the domains from DNSimple.
We have built a "quick and dirty" DNSimple addon in a few minutes. The complete (and working) example of this article is available on GitHub: hello-domains-hanami.
If you looking for other frameworks, we built several hello domains apps for Ruby on Rails, Phoenix, and Node.
Our platform is a powerful tool to integrate and enhance the DNSimple experience. You can build addons to monitor your domains, connect them with hosting solutions, run security checks, and even to improve your email deliverability.
The sky is the limit! 🚀