├── .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 | --------------------------------------------------------------------------------