├── .gitignore
├── .gitmodules
├── code-examples
├── perl.pl
├── php.php
├── python.py
└── ruby.rb
├── docs
├── Response-Codes.md
├── code-examples
│ └── perl.md
└── Anatomy-of-a-Social-Authority-API-Call.md
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | _site
2 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "client-libraries/p5-Webservice-Followerwonk-SocialAuthority"]
2 | path = client-libraries/p5-Webservice-Followerwonk-SocialAuthority
3 | url = git@github.com:seomoz/p5-Webservice-Followerwonk-SocialAuthority.git
4 | [submodule "client-libraries/KnowEm-php"]
5 | path = client-libraries/KnowEm-php
6 | url = https://github.com/KnowEm/seomozfollowerwonkapi.git
7 |
--------------------------------------------------------------------------------
/code-examples/perl.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env perl
2 | use 5.12.1;
3 | use warnings;
4 | use HTTP::Thin::UserAgent;
5 | use Getopt::Long;
6 | use Digest::HMAC_SHA1 qw(hmac_sha1_hex);
7 |
8 | my $uri = 'https://api.followerwonk.com/social-authority/';
9 |
10 | GetOptions(
11 | 'uri=s' => \$uri,
12 | 'id=s' => \my $id,
13 | 'key=s' => \my $key,
14 | ) or die;
15 |
16 | die "Must supply --id and --key" unless $id && $key;
17 |
18 | my $time = time + 500;
19 | my $signature = hmac_sha1_hex( "$id\n$time", $key );
20 | my $auth = "AccessID=$id;Timestamp=$time;Signature=$signature";
21 |
22 | while ( my $names = join ',', splice @ARGV, 0, 99 ) {
23 | say http( GET "$uri?screen_name=$names",
24 | Authorization => "MozSigned $auth" )->as_json->response->dump;
25 | }
26 |
--------------------------------------------------------------------------------
/docs/Response-Codes.md:
--------------------------------------------------------------------------------
1 | # API Response Codes
2 |
3 | ## 200 OK
4 |
5 | Your request has completed successfully. The Request body will contain the data you were looking for.
6 |
7 | ## 201 CREATED
8 |
9 | Creating the resource was successful. There will be a Location header pointing to the newly created Resource.
10 |
11 | ## 401 AUTHORIZATION REQUIRED
12 |
13 | You need to supply authentication credentials. See the [[Anatomy of a Social Authority API Call]] for more information on how to make a valid request.
14 |
15 | ## 403 FORBIDDEN
16 |
17 | The authentication credentials you supplied weren't valid. You'll need to check that you are using the right credentials and supply the appropriate ones.
18 |
19 | ## 404 NOT FOUND
20 |
21 | The server couldn't find the data you were looking for. Possibly it was removed (either by twitter, or by another request).
22 |
23 | ## 420 CALM DOWN
24 |
25 | You're requests are coming in too quickly and have triggered throttle controls. Please slow down your requests to under the throttle limits.
26 |
27 | ## 429 LIMITS EXCEEDED
28 |
29 | You've made too many requests for the current time period (hour or day). Please wait until your throttle limits have reset (when the current period ends) and try again.
30 |
--------------------------------------------------------------------------------
/code-examples/php.php:
--------------------------------------------------------------------------------
1 | ';
25 | // print_r($response);
26 | // echo '';
27 |
28 | // Below is an example of how to pull data out of the response array
29 | $screen_name = $response['_embedded'][0]['screen_name'];
30 | $user_id = $response['_embedded'][0]['user_id'];
31 | $social_authority = $response['_embedded'][0]['social_authority'];
32 |
33 | echo $screen_name .'
';
34 | echo $user_id . '
';
35 | echo $social_authority . '
';
36 | }
37 | ?>
--------------------------------------------------------------------------------
/code-examples/python.py:
--------------------------------------------------------------------------------
1 | """
2 | author: Evan Duffield
3 | Thank you to iAcquire for sponsoring development of this module.
4 |
5 | Updated by Bryan Minor, Ph.D.
6 | --> Now works for Python 3
7 | Supported by envision.ai
8 | """
9 |
10 | # External libraries
11 | from hashlib import sha1
12 | from time import time
13 | import base64
14 | import json
15 | import hmac
16 | import os
17 |
18 | try:
19 | from urllib2 import (Request, urlopen)
20 | except ImportError:
21 | from urllib.request import (Request, urlopen)
22 |
23 | try:
24 | from urllib import quote_plus
25 | except ImportError:
26 | from urllib.parse import quote_plus
27 |
28 | #Initializations
29 | follower_wonk_access_id_str = os.environ['SOCIAL_AUTHORITY_ACCESS_ID']
30 | follower_wonk_secret_key_str = os.environ['SOCIAL_AUTHORITY_SECRET_KEY']
31 |
32 | #Class for access FollowerWonk API
33 | class FollowerWonk(object):
34 | @staticmethod
35 | def social_authority(username):
36 | uri = 'https://api.followerwonk.com/social-authority'
37 |
38 | datime = int(time() + 500)
39 |
40 | keyBin = follower_wonk_secret_key_str.encode('UTF-8')
41 | messageStr = "%s\n%s" % (follower_wonk_access_id_str, datime)
42 | messageBin = messageStr.encode('UTF-8')
43 |
44 | s = hmac.new(keyBin, messageBin, sha1).digest()
45 | b64 = base64.b64encode(s)
46 | signature = quote_plus(b64)
47 |
48 | auth = "AccessID=%s;Timestamp=%s;Signature=%s;" % (follower_wonk_access_id_str, datime, signature)
49 |
50 | req = Request("%s?screen_name=%s;%s" % (uri, username, auth))
51 | r = urlopen(req)
52 |
53 | responseStr = r.read().decode("utf-8")
54 | response_Json = json.loads(responseStr)
55 |
56 | r.close()
57 |
58 | if '_embedded' not in response_Json:
59 | return -1
60 |
61 | return float(response_Json['_embedded'][0]['social_authority'])
62 |
63 | # Usage examples:
64 | #
65 | # FollowerWonk.social_authority("bryanminorphd")
66 | # FollowerWonk.social_authority("envision_ai")
67 | # FollowerWonk.social_authority("google")
68 |
--------------------------------------------------------------------------------
/code-examples/ruby.rb:
--------------------------------------------------------------------------------
1 | # Author: Rustam A. Gasanov
2 | # To get this functionality wrapped in gem, check https://github.com/rustamagasanov/social_authority
3 |
4 | require 'net/http'
5 | require 'openssl'
6 | require 'base64'
7 | require 'cgi'
8 | require 'json'
9 |
10 | module SocialAuthority
11 | class ResponseError < StandardError; end
12 |
13 | class Api
14 | attr_reader :options
15 |
16 | def initialize(options)
17 | @options = { screen_names: [], user_ids: [] }.merge(options)
18 | end
19 |
20 | def fetch
21 | uri = URI(generate_request_url)
22 | http = Net::HTTP.new(uri.host, uri.port)
23 | http.use_ssl = uri.scheme == 'https'
24 | request = Net::HTTP::Get.new(uri.request_uri)
25 | response = http.request(request)
26 |
27 | if response.code == '200'
28 | JSON.parse(response.body)['_embedded']
29 | else
30 | raise ResponseError, response.body
31 | end
32 | end
33 |
34 | private
35 | def generate_request_url
36 | timestamp = Time.now.to_i + 500
37 |
38 | url = 'https://api.followerwonk.com/social-authority'
39 | url << '?'
40 | url << "user_id=#{ options[:user_ids].join(',') };"
41 | url << "screen_name=#{ options[:screen_names].join(',') };"
42 | url << "AccessID=#{ options[:access_id] };"
43 | url << "Timestamp=#{ timestamp };"
44 | url << "Signature=#{ generate_signature(timestamp) }"
45 | url
46 | end
47 |
48 | def generate_signature(timestamp)
49 | key = options[:secret_key]
50 | data = "#{ options[:access_id] }\n#{ timestamp }"
51 | digest = OpenSSL::Digest.new('sha1')
52 | CGI::escape(Base64.strict_encode64(OpenSSL::HMAC.digest(digest, key, data)))
53 | end
54 | end
55 |
56 | def self.fetch(options)
57 | Api.new(options).fetch
58 | end
59 | end
60 |
61 | p SocialAuthority.fetch({
62 | access_id: 'YOUR_ACCESS_ID',
63 | secret_key: 'YOUR_SECRET_KEY',
64 | user_ids: ['74594552', '10671602'],
65 | screen_names: ['Porsche', 'Toyota']
66 | })
67 | # => [{"_links"=>{"self"=>{"href"=>"/?user_id=14219877"}}, "social_authority"=>"79.55774090527403", "user_id"=>"14219877", "screen_name"=>"Toyota"}, {"_links"=>{"self"=>{"href"=>"/?user_id=57016932"}}, "social_authority"=>"74.10208291651085", "user_id"=>"57016932", "screen_name"=>"Porsche"}, {"_links"=>{"self"=>{"href"=>"/?user_id=10671602"}}, "social_authority"=>"87.26883910802435", "user_id"=>"10671602", "screen_name"=>"PlayStation"}, {"_links"=>{"self"=>{"href"=>"/?user_id=74594552"}}, "social_authority"=>"78.04014172151778", "user_id"=>"74594552", "screen_name"=>"AppStore"}]
68 |
--------------------------------------------------------------------------------
/docs/code-examples/perl.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Perl Example Code
3 | layout: default
4 | ---
5 | # Perl Example Code
6 |
7 | Querying the Social Authority API is really quite simple. Here's an expanded example using the `HTTP::Thin::UserAgent` client from CPAN.
8 |
9 | #!/usr/bin/env perl
10 | use 5.12.1;
11 | use warnings;
12 | use HTTP::Thin::UserAgent;
13 | use Getopt::Long;
14 | use Digest::HMAC_SHA1 qw(hmac_sha1_hex);
15 |
16 | my $uri = 'https://api.followerwonk.com/social-authority/';
17 |
18 | GetOptions(
19 | 'uri=s' => \$uri,
20 | 'id=s' => \my $id,
21 | 'key=s' => \my $key,
22 | ) or die;
23 |
24 | die "Must supply --id and --key" unless $id && $key;
25 |
26 | my $time = time + 500;
27 | my $signature = hmac_sha1_hex("$id\n$time", $key);
28 | my $auth = "AccessID=$id;Timestamp=$time;Signature=$signature";
29 |
30 | while ( my $names = join ',', splice @ARGV, 0,99 ) {
31 | say http(
32 | GET "$uri?screen_name=$names",
33 | Authorization => "MozSigned $auth"
34 | )->as_json->response->dump;
35 | }
36 |
37 | Let's step through this a little bit. First we start off with a standard modern Perl preamble:
38 |
39 | #!/usr/bin/env perl
40 | use 5.12.1;
41 | use warnings;
42 |
43 | We're stating that we'd like to use Perl 5.12.1. This version of Perl is the first to start with better defaults for helping us catch typos and other errors. If you're using a version before 5.12.1, we recommend replacing this line with:
44 |
45 | use strict;
46 | use feature qw(say);
47 |
48 | Next we bring in the external libraries we would like to use. There are three:
49 |
50 | use HTTP::Thin::UserAgent;
51 | use Getopt::Long;
52 | use Digest::HMAC_SHA1 qw(hmac_sha1_hex);
53 |
54 |
55 | [`HTTP::Thin::UserAgent`][1] is a small HTTP client that makes doing API style requests easier. [`Getopt::Long`][2] is a standard command line argument parser, and it ships with the core Perl distribution. Finally [`Digest::HMAC_SHA1`][3] is what we'll use to sign our requests.
56 |
57 | Continuing on:
58 |
59 | die "Must supply --id and --key" unless $id && $key;
60 |
61 | If we don't have the information we need to sign the requests we throw an exception telling the user that they need to supply the required arguments.
62 |
63 | Next we set up our authentication credentials:
64 |
65 | my $time = time + 500;
66 | my $signature = hmac_sha1_hex("$id\n$time", $key);
67 | my $auth = "AccessID=$id;Timestamp=$time;Signature=$signature";
68 |
69 | Then for batches of 100 names provided on the command line, we make the API request:
70 |
71 | while ( my $names = join ',', splice @ARGV, 0,99 ) {
72 | say http(
73 | GET "$uri?screen_name=$names",
74 | Authorization => "MozSigned $auth"
75 | )->as_json->response->dump;
76 | }
77 |
78 | And that's basically all there is to it.
79 |
80 | [1]: http://metacpan.org/module/HTTP::Thin::UserAgent
81 | [2]: http://metacpan.org/module/Getopt::Long
82 | [3]: http://metacpan.org/module/Digest::HMAC_SHA1
83 |
--------------------------------------------------------------------------------
/docs/Anatomy-of-a-Social-Authority-API-Call.md:
--------------------------------------------------------------------------------
1 | # Anatomy of a Social Authority API Call
2 |
3 | Every request to the Social Authority API follows the same basic format:
4 |
5 | http://api.followerwonk.com/social-authority?{screen_name};{user_id};{AccessID};{Timestamp};{Signature}
6 |
7 | Here's what each of these parts of this request do:
8 |
9 | * `http://api.followerwonk.com`
10 | Access the API by calling the hostname of the service `api.followerwonk.com` and the Resource you’re making the request to `/social-authority`.
11 |
12 | * {screen_name} & {user_id}
13 | These are query parameters for which accounts you want to look up Social Authority scores for. You can provide either a Twitter screen name, `screen_name=peterbray` or a Twitter user id, `user_id=24496399` or both. You can provide multiple of either by separating the IDs with commas, `screen_name=peterbray,randfish,aplusk`.
14 |
15 | * {AccessID}, {Timestamp} & {Signature}
16 | These are query parameters that provide your credentials. For example:
17 |
18 | `AccessID=member-MDczMjM1NGUtN2Y3Ny01OGI0LThkOGUtYzhlYWVlYjcxMTZk;Timestamp=1225138898;Signature=LmXYcPqc%2BkapNKzHzYz2BI4SXfC%3D`
19 |
20 | ## Signed Authentication
21 |
22 | To use signed authentication, append the following three query string parameters:
23 |
24 | The AccessID parameter identifies the client in question. The value of this parameter must be your access ID, obtained when you generate yourAPI credentials.
25 | The Timestamp parameter is a Unix timestamp that indicates for how long this request is valid. This should be a time in the future, usually no more than several minutes later than the moment your client code initiates the transfer. Values that expire excessively far in the future will not be honored by the Mozscape API. Authentication timestamps must be in UTC in order to work properly.
26 | The Signature parameter is an HMAC-SHA1 hash of your Access ID (as it appears in the AccessID parameter), followed by a new line, followed by the Timestamp parameter, using your Secret Key. This hash must be base64 and URL-encoded before being placed in the request query string.
27 | Once combined, a valid query string should look like the following:
28 |
29 | `AccessID=member-MDczMjM1NGUtN2Y3Ny01OGI0LThkOGUtYzhlYWVlYjcxMTZk;Timestamp=1225138899;Signature=LmXYcPqc%2BkapNKzHzYz2BI4SXfC%3D`
30 |
31 | For example, the example request above should compute the HMAC-SHA1 of the following two lines (including a single linefeed character between the AccessID and the timestamp, and ignoring any whitespace below):
32 |
33 | `member-MDczMjM1NGUtN2Y3Ny01OGI0LThkOGUtYzhlYWVlYjcxMTZk 1225138899`
34 |
35 | Once the HMAC-SHA1 of this string is created, the binary form must be base64 encoded. The result of the base64 encoding must be URL-encoded. This method of authentication is complicated, but you can find helpful examples in several languages in our Sample Code.
36 |
37 | ## ? and ;
38 |
39 | These little characters are important, so don’t miss them. The ? separates the main URL from the query parameters, and the ; goes between multiple parameters. You’ll see the ; used in the example for authentication, which is just 3 parameters required by the service.
40 | All of these elements together give you a valid request:
41 |
42 | http://api.followerwonk.com/social-authority?screen_name=randfish;AccessID=member-MDczMjM1NGUtN2Y3Ny01OGI0LThkOGUtYzhlYWVlYjcxMTZk;Timestamp=1225138898;Signature=LmXYcPqc%2BkapNKzHzYz2BI4SXfC%3D
43 |
44 | ## Creating Valid Requests in Code
45 | While you can enter a valid request in your browser for quick queries, if you’re doing a lot of work with the service, you’ll want to create a program that generates the requests for you. To get started, see our sample code and applications.
46 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Social Authority SDK
2 | ====================
3 |
4 | Followerwonk moved. The canonical version of this project is at [followerwonk/Social-Authority-SDK](https://github.com/followerwonk/Social-Authority-SDK).
5 |
6 | Social Authority helps you find, optimize, and engage your Twitter audience. It's a 1 to 100 point scale that measures a user's influential content on Twitter.
7 | More than just another self-focused metric, Social Authority helps you discover other influential tweeters with high engagement. You can read more about it at [https://followerwonk.com/social-authority](https://followerwonk.com/social-authority)
8 |
9 | * [Code Examples](https://github.com/seomoz/Social-Authority-SDK/tree/master/code-examples)
10 | * [Language Libraries](https://github.com/seomoz/Social-Authority-SDK/tree/master/client-libraries)
11 |
12 | ## Getting Started with the Social Authority API
13 |
14 | The Social Authority API gives access to a select piece of the Followerwonk infrastructure. It uses standard HTTP Verbs and Hypermedia documents to make exploring and learning as easy as possible. This guide will use curl for all our examples, you're welcome to translate them into whatever language you prefer.
15 |
16 | ### A Quick Note about the Response Data Format
17 |
18 | By default, the Social Authority API uses [Hypertext Application Language](http://stateless.co/hal_specification.html) for the JSON serialization format. This means we can (and do!) embed Hypermedia Controls into the documents. Every response from the API has a key (`_links`) pointing to more information. Simply generate requests for those URLs to obtain the additional information. This is useful when you exceed the limits for scores returned in a single request. The server will automatically generate the URLs needed for subsequent requests to obtain the remaining data.
19 |
20 | ### Setting up Access Controls
21 |
22 | The Social Authority API uses an access control system. To gain access the first step is to fetch your Social Authority API AccessID and SecretKey.
23 |
24 | You can do this by logging into Followerwonk and following the directions from the [Social Authority](https://followerwonk.com/social-authority) page there.
25 |
26 | The current default freemium request limits are 250 SAs per day & 7500 SAs per month:
27 |
28 | 25 IDs per request
29 | 5 Requests Per Second (ie concurrently)
30 | 10 requests per hour
31 | 10 requests per day
32 |
33 | Please contact us (help@moz.com) for paid subscription access for larger volumes.
34 |
35 | ### Querying the Social Authority API
36 |
37 | Once you have an AccessID you can make a call to the Social Authority resource. The Social Authority resource takes a list of screen names or user ids and returns Social Authority scores for all of the accounts it can find. Currently we limit the number of screen names and user ids in a single request to 25 combined.
38 |
39 | You will need to perform a signed request as described in [Anatomy of a Social Authority Call](https://github.com/seomoz/Social-Authority-SDK/blob/master/docs/Anatomy-of-a-Social-Authority-API-Call.md).
40 |
41 | curl -v https://api.followerwonk.com/social-authority?screen_name=randfish;AccessID=ACCESS_ID;Timestamp=TIMESTAMP;Signature=SIGNATURE_HMAC
42 |
43 | You'll get back a JSON packet with the Social Authority score and some metrics.
44 |
45 | {
46 | "_embedded" : [
47 | {
48 | "_links" : {
49 | "self" : {
50 | "href" : "/?user_id=6527972"
51 | }
52 | },
53 | "user_id" : "6527972",
54 | "social-authority" : "54.90157176971435",
55 | "screen_name" : "randfish"
56 | }
57 | ],
58 | "_links" : {
59 | "search" : [
60 | {
61 | "templated" : "yes",
62 | "href" : "/{?screen_name}",
63 | "name" : "screen_name"
64 | },
65 | {
66 | "templated" : "yes",
67 | "href" : "/{?user_id}",
68 | "name" : "user_id"
69 | }
70 | ],
71 | "self" : {
72 | "href" : "/social-authority?screen_name=randfish"
73 | }
74 | }
75 | }
76 |
77 | ## Attribution and Licensing
78 |
79 | By using the Social Authority API, you agree to our [General Terms of Use](http://www.seomoz.org/users/terms), our [Privacy Policy](http://www.seomoz.org/pages/privacy) and the restrictions contained on this page. You do not have to be a paying member to use our API. Access to the Social Authority API may be suspended or terminated at any time and for any reason, with or without cause. If your access to the API is cancelled, you are not to be entitled to a refund of any kind. SEOmoz may discontinue providing service at any time and for any reason. We simply ask that if you re-use our data you give us attribution and follow our branding guidelines.
80 |
81 | ## Help
82 |
83 | Problems? Concerns? Questions? [Contact us!](http://www.seomoz.org/help)
84 |
85 |
--------------------------------------------------------------------------------