Developer engagement can come from many places. It can be a discussion on Slack, a question raised on Twitter, or an issue opened in a GitHub repository. Each of those represents active participation by a person in a community. Yet, while Twitter, Discord, Slack, and other mediums take prime focus, what often gets overlooked is documentation.
Studies have shown that documentation is the preferred medium for developers seeking answers as they build. Often, the key difference between a positive product experience and a negative one is the state and accuracy of the docs. A clear and ongoing relationship with the developers who use them can significantly improve the feedback loop helping to ensure a more consistently positive experience.
The documentation of an API, product, or service is one of the pivotal meeting places between the people that orbit the community and the product that the community gravitates around. Capturing that engagement is crucial to gaining a more full understanding of a community. Orbit provides a platform and an open API to enable and grow the work of developer engagement.
Creating with the Orbit API
Using the Orbit API, we are going to build a Ruby on Rails service that will automatically connect new documentation feedback to an Orbit workspace. The code is in production and is being used by the team at Vonage as part of their open-source developer portal platform.
(tl;dr You can find the full code for this Rails service on GitHub.)
The Orbit API lets you perform a wide range of activities in your Orbit workspace programmatically. The API reference guide is a good starting point for exploration. For our purposes, we will be using the create a new activity for existing or new member API operation.
API access is included with every account! Try it out by signing up today.
Building the Feedback Notifier Service
Creating the Class
The first thing we are going to do is create a new class in our Rails services folder called OrbitFeedbackNotifier
:
class OrbitFeedbackNotifier
end
This class will be responsible for gathering the data from our documentation's feedback system, and creating a POST
request to the Orbit API with it. The Vonage developer platform utilizes custom-built feedback tooling. However, regardless of the specific feedback tooling you use, you only need to expose the data collected to our new service for it to work.
We will use the #initialize
method in the class definition with the feedback data from our feedback collection tooling:
class OrbitFeedbackNotifier
def initialize(feedback)
@feedback = feedback
end
end
There are several different design options we can use in structuring our service. In this case, we will build a #call
class method that will do the work of instantiating an instance of our class and creating the HTTP request. This allows us to skip the work of instantiation in the actual implementation of our new service:
class OrbitFeedbackNotifier
def self.call(feedback)
new(feedback).post!
end
def initialize(feedback)
@feedback = feedback
end
end
The new class #call
method creates an instance of the OrbitFeedbackNotifier
with the feedback data we passed into it and then invokes a #post
instance method, which we will be building shortly. Before we can build that method though we need to structure our data to create a new activity in our Orbit workspace using the Orbit API. Let's do that next!
Constructing the Data
When we look at the Orbit API documentation, we see that we need to know our workspace ID. We can find that in the URL of our Orbit workspace, it's the end of the website address. For example, the URL might be: https://app.orbit.love/example
, and then your workspace ID would be example
.
The API endpoint gives us a lot of ability to customize the kind of activity and data we want to associate with it. We are going to create a params
object that will contain our data and we'll send that in our API request.
First, let's define the activity. then we'll define the member data after.
def params
@params ||= {
activity: {
activity_type: "docs:feedback",
key: "docs-feedback-#{@feedback.id},
title: "Offered feedback on the docs",
description: @feedback.feedback_body,
occurred_at: @feedback.created_at || Time.zone.now.iso8601
}
}
end
Before we go forward, we'll take a moment to break down the different fields in the code snippet above:
-
activity_type
: This is the reference for the custom activity you are introducing to your Orbit workspace. -
key
: A unique ID for this specific activity. If you do not supply one, Orbit will generate one for you. In the example above, I mock using the data from the feedback. -
title
: The title for the custom activity -
description
: This is the descriptive body of the activity. You can put anything in here, or nothing at all. In the example, I mock a parameter of the actual feedback contents. -
occurred_at
: The date and time when the activity happened. If you do not provide a value, the API defaults to the time when it received the HTTP request.
Now, we'll construct our member identity data:
def params
@params ||= {
activity: {
activity_type: "docs:feedback",
key: "docs-feedback-#{@feedback.id},
title: "Offered feedback on the docs",
description: @feedback.feedback_body],
occurred_at: @feedback.created_at || Time.zone.now.iso8601
},
identity: {
source: "email",
source_host: @feedback.base_url,
email: @feedback.email
}
}
end
Similar to the activity, we can provide a good amount of customization on the member identity. In our case, we are using the following fields:
-
source
: Where the member data is coming from, Orbit recognizes some predefined options (github
,twitter
,discourse
,email
,linkedin
,devto
), and also any custom value. -
source_host
: The URL from where the member data is coming from. -
email
: The email of the member, which is used here as the identifier. You can also replace this withusername
oruid
for a user ID, if either of those are more appropriate for your context.
There are other possible fields you can supply for your activity and identity constructs. I recommend checking out the API reference guide for a description of each of them. The API reference guide lets you also supply some sample data inline with the guide and get a fully formed code snippet you can copy and paste into your code.
Preparing to Make the HTTP Request
One last step before we create the #post!
method, which will connect to the Orbit API and pass the data to our workspace. We need to create a small method to create a URI for the request, we'll call this #uri
:
def uri
@uri ||= URI("https://app.orbit.love/api/v1/#{ENV['ORBIT_WORKSPACE_ID']}/activities")
end
Now we're ready to put it all together in our #post!
method:
def post!
return unless ENV['ORBIT_WORKSPACE_ID']
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req['Accept'] = 'application/json'
req['Content-Type'] = 'application/json'
req['Authorization'] = "Bearer #{ENV['ORBIT_API_KEY']}"
req.body = params
req.body = req.body.to_json
http.request(req)
end
That's it! You now have a fully working Rails service to introduce feedback on your docs as an integral component of the understanding of your community through Orbit. How you use it in your codebase will depend on the architecture of your feedback implementation. You might want to invoke it when a new feedback item is posted to your database, for example.
Feedback, perhaps especially the negative or constructive kind, is an invaluable act of community expression. It demonstrates engagement on behalf of a person with your API, product, or service, and adding that data to your Orbit workspace will only enhance your overall picture of your community.
Further Exploration
Do you want to explore further the things you can do with the Orbit API? Check out the following resources:
Top comments (0)