📜 ⬆️ ⬇️

StackExchange API Basics


Sometimes there are situations when you need to write a script or application that interacts with a service. Many large sites offer developers their API, which they can use in their projects. However, each service has its own functions and ways of working with the API. Because it is often difficult to start using third-party APIs in their projects.

Using the example of a small application that authorizes a user and receives his latest notifications with profile data, we will look at how to use the Stack Exchange API.


1. Register a new application

')
Before creating your application, you must register it with StackApps. This is necessary to get access keys for it. Follow this link stackapps.com/apps/oauth/register and fill in all the fields that are not marked with optional . For my tutorial, I filled in the fields like this:


Do not forget to tick the “Enable Client Side OAuth Flow”. This is necessary for OAuth - otherwise the user simply will not be able to log in using the application. When everything is filled, click the appropriate button, and go to the application management page. There we will get several keys (Client Id, Client Secret, Key). Of these, for the application itself only ClientId and Key are needed. We save them and on this we complete the registration process and proceed directly to writing the application itself.

2. Getting started


Create a new clean HTML file and immediately include a script in it:
<script type='text/javascript' src='https://api.stackexchange.com/js/2.0/all.js'></script> 

Now we can use the basic functions of initialization and authorization for further work. In addition to key and clientId, for initialization we need to pass two additional parameters:
 SE.init({ clientId: 1, //      clientId key: 'YoUrAweSomeKey', //    key channelUrl: 'http://example.com/', //      .    ,       complete: function (data) { alert(" !"); } //     ,       }); 

If you did everything right, then an alert should pop up when the page loads :) Otherwise, check the console output - is there anything like that on the Uncaught channelUrl ? If there is, double check channelUrl. Otherwise, you should check the application settings in the control panel on the site.

3. Authorization


Let's change the previous code, namely: create a prototype of the auth (data) function and specify it in SE.init as a function, called upon successful initialization:
 function auth(data) {} ... SE.init({ ... complete: auth }); 

Now is the time to write authorization. Here, too, everything is simple:
 SE.authenticate({ success: function(data) { alert('  !'); }, //    error: function(data) { alert('    :('); }, //     }); 

I put this code in the body auth (data) . Now, when you first load the page, a pop-up window should appear. In it you will be offered two buttons - to allow and deny access for the application:


However, for the time being we simply log in and do nothing with the received data. But if successful, we will be given client tokens for further work. Let's save them somewhere. For example, let's create a global variable that will store these same tokens:
 var tokens = null; ... SE.authenticate({ success: function(data) { alert('  !'); tokens = data; }, ... ... 

Now, when we are able to authorize the user, you can go to work directly with the API.

4. Retrieving profile data


The API returns the response to requests in JSON format. This means that the data loaded via JS will be easily converted from a string format to some structure. Requests will be cross-domain, and therefore I will use jQuery.
We will receive user data here:
 https://api.stackexchange.com/2.2/me?site=[ ] 

Some user data (for example, rating or icons) depends on which site of the Stack Exchange network the profile is requested. Data obtained with StackOverflow and with MathOverflow may vary. The name of the site can be viewed in the system itself. Okay. If you just request data by reference, we will get something like this json'a:
 {"error_id":401,"error_message":"This method requires an access_token","error_name":"access_token_required"} 

All possible errors can be found here: api.stackexchange.com/docs/error-handling

But we need to specify access tokens! To do this, we will attach these same tokens to our address above:
 https://api.stackexchange.com/2.2/me?site=[ ]&key=[  key]&access_token=[tokens.accessToken]&callback=[method] 

Here tokens.accessToken is the user key previously obtained during the authorization process, and method is the callback that will be called at the end of the download. The answer will be something like this:
 { "items": [ { "badge_counts": { "bronze": 5, "silver": 0, "gold": 0 }, "account_id": 2760756, "is_employee": false, "last_modified_date": 1396214504, "last_access_date": 1396268249, "reputation_change_year": 62, "reputation_change_quarter": 62, "reputation_change_month": 62, "reputation_change_week": 55, "reputation_change_day": 10, "reputation": 63, "creation_date": 1368447422, "user_type": "registered", "user_id": 2377708, "age": 18, "location": "Belarus", "link": "http://stackoverflow.com/users/2377708/alex-saskevich", "display_name": "Alex Saskevich", "profile_image": "http://i.stack.imgur.com/0Vz5q.jpg?s=128&g=1" } ], "has_more": false, "quota_max": 10000, "quota_remaining": 9905 } 

It is visually difficult to work with such data, and therefore I will create a callback function that will render the received information into a small table:
 function renderProfileData(data) { var items = data.items[0]; $("#reputation").text(items.reputation); $("#login").text(items.display_name); $("#bronze_badges").text(items.badge_counts.bronze); $("#silver_badges").text(items.badge_counts.silver); $("#gold_badges").text(items.badge_counts.gold); $("#profile_image").attr("src", items.profile_image); } 

I received the information itself via GET requests like this:
 $.get("https://api.stackexchange.com/2.2/me?site=stackoverflow&key=YoUrAwEsOmEKey&access_token=YoUrSecretToKEn&callback=profile"); 

In the end, I got this result:


5. Latest notifications


In order for our application to receive information about unread messages, notifications, it needs to be granted certain access rights. In the case of notifications, this is read_inbox . We put it in the application authorization block:
 SE.authenticate({ scope: ['read_inbox'], ... }); 

Information about the notifications we get here:
 https://api.stackexchange.com//2.2/notifications?pagesize=[  ]&key=[ ]&access_token=[  ]&callback=[callback-] 

We may not specify the number of recent notifications, but then we will receive all notifications at once. The request is executed in the same way as the previous one, the response will be something like this:
 { "items": [ "site": { "styling": { "tag_background_color": "#FFF", "tag_foreground_color": "#000", "link_color": "#0077CC" }, "related_sites": [ { "relation": "meta", "api_site_parameter": "meta.reverseengineering", "site_url": "http://meta.reverseengineering.stackexchange.com", "name": "Reverse Engineering Meta Stack Exchange" }, { "relation": "chat", "site_url": "http://chat.stackexchange.com", "name": "Chat Stack Exchange" } ], "open_beta_date": 1364774400, "closed_beta_date": 1363651200, "site_state": "open_beta", "twitter_account": "StackReverseEng", "favicon_url": "http://cdn.sstatic.net/reverseengineering/img/favicon.ico", "icon_url": "http://cdn.sstatic.net/reverseengineering/img/apple-touch-icon.png", "audience": "researchers and developers who explore the principles of a system through analysis of its structure, function, and operation", "site_url": "http://reverseengineering.stackexchange.com", "api_site_parameter": "reverseengineering", "logo_url": "http://cdn.sstatic.net/reverseengineering/img/logo.png", "name": "Reverse Engineering", "site_type": "main_site" }, "is_unread": false, "creation_date": 1396197666, "notification_type": "badge_earned", "body": "You've earned the "Autobiographer" badge." } ], "has_more": true, "quota_max": 10000, "quota_remaining": 9994 } 

As you can see, in this case, the system immediately gives us an array of notifications. And it’s quite simple to work with them:
 function renderNotifications(data) { var items = data.items; var html = "<center> </center><br/>"; for (var i = 0; i < items.length; i ++) { var site = items[i].site.name; var icon = items[i].site.icon_url; var body = items[i].body; var str = "<div class = 'item'><img src = '" + icon + "' height = '14px' /> " + site + ": " + body + "</div>"; html += str; } $("#notifications").html(html); } 


As a result, the page of my small application has acquired the following final form:


6. And now what?


The Stack Exchange Network API allows us to not only receive notifications or profile data. We can also get questions, comments, tags, and we can also interact with them (add questions, edit our comments). We can work with user profile, events and statistics.

Speaking of statistics - in the control panel of the application, you can view the statistics of authorizations and requests as graphs. And yes, it is worth bearing in mind that the number of requests that an application can make to a single function is limited to ten thousand. The remaining number of requests is sent to us along with the JSON response in the "quota_remaining" field.

The documentation can also experiment with queries. For this, StackExchange offers a console, which can be found under the description of each function.

Relevant links:

Source: https://habr.com/ru/post/217753/


All Articles