Given a URL how can I figure out the Geo where it is likely to originating from? - facebook

I am working on a certain problem where given a URL I need to map it to a country. Even if I can reliably answer the question "Is this particular URL relevant to United States?" that should be sufficient.
I am happy to have false negatives but never a false positive.
Currently I am considering the following approach.
See if the domain name of the URL is in top 1000 .com domains on Alexa for USA.
Check if the the link was shared by US users on Facebook or twitter.
Has anyone solved this kind of problem before ?

You can use http://dev.maxmind.com/geoip/geoip2/geolite2/ but you need to get the IP address from your URLs domain before you can access the GeoIP database with this address.
There are a lot of interfaces to the GeoIP dataset for different languages: http://dev.maxmind.com/geoip/geoip2/downloadable/#MaxMind_APIs
Have a look at a sample NodeJS project here:
https://github.com/tobilg/GeoLocateURL

You can also try out the userinfo.io API or javascript library which is free and gets its data from a merge of several geolocation databases for more accuracy.
<script type="text/javascript" href="//cdnjs.cloudflare.com/ajax/libs/userinfo/1.0.0/userinfo.min.js"></script>
<script type="text/javascript">
UserInfo.getInfo(function(data) {
// the "data" object contains the info
}, function(err) {
// the "err" object contains useful information in case of an error
});
</script>
The response will look like:
{
request_date: "2014-09-18T04:11:25.154Z",
ip_address: "192.77.237.95",
position: {
latitude: 37.7758,
longitude: -122.4128,
accuracy: 3 // This is the accuracy radius, in kilometers
},
continent: {
name: "North America",
code: "NA",
},
country: {
name: "United States",
code: "US",
},
city: {
name: "San Francisco",
code: "94103"
}
}

Related

Algolia search within scope

I am trying to implement Algolia for a directory. I've created a huge index for listings with data like:
{
"id": 120,
"listing_type": "restaurant",
"location": "In example street, so so area",
"brand":{
"name": "Mc Donald's",
"image":"1130824.jpg",
"description": "Find fastest burgers and fries around. "
},
"neighbourhood":{
"name": "Downtown",
"city":{
"name": "Philadelphia",
"state": "PA"
}
},
"_tags":["burgers","fries","fast food","quick service"],
"has_deals": true,
"images":["file1.jpg","file2.jpg"],
...
}
I want to create separate pages for each city, and would like to restrict searches for that specific city. How can I achieve this?
I can find a parameter that can be added here:
var search = instantsearch({
// Replace with your own values
appId: 'xxxxxx',
apiKey: 'xxxx', // search only API key, no ADMIN key
indexName: 'listings',
urlSync: true,
searchParameters: {
hitsPerPage: 10
}
});
There are two ways to restrict a search, both based on the filters. For that you first need to add some single attribute you can filter on for the city to attributesForFaceting (in the settings, for example with the dashboard). In this case we can use neighbourhood.city.
Then in InstantSearch on your page you can add to searchParameters the value: filters: 'neighbourhood.city:Philadelphia'.
You can also use "secured API keys" to refine on this value before actually launching the page. This will prevent someone from taking that API key and searching themselves. Read more about that in the docs

Prebid.js DFP configuration

Can somebody help me with integration Prebid.js to existing DFP. I have DFP and Units are live.
I created Order-Line-items with price-priority (from 0.2 to 1.5). I also did key-values hb_pb and hb_bidder (in hb_bidder I add just "rubicon").
I also dowloaded prebid.js.
My question is what else I need to do to get it live? Where I need to add setup for ex. "rubicon id", "site id", zone and unit-id? Do I need to modify code of prebid.js script, or modify DFP code from header of my site, or I can do all from DFP?
I tried this on my site, The Goldens Club but after a while i switched to AD network that give me complete solution.
Prebid.js provides a collection of adapters for various bidders and operates in the browser hence it should be configured on your pages via javascript. You would need to configure prebid.js settings and slightly change you GPT tags
Here's a detailed annotated example of how DFP could be used in combination with Appnexus
http://prebid.github.io/dev-docs/examples/basic-example.html
This is an excerpt from that page containing prebid.js configuration section:
var PREBID_TIMEOUT = 700;
var adUnits = [{
code: 'div-gpt-ad-1460505748561-0',
sizes: [[300, 250], [300,600]],
bids: [{
bidder: 'appnexus',
params: {
placementId: '4799418'
}
}]
},{
code: 'div-gpt-ad-1460505661639-0',
sizes: [[728, 90], [970, 90]],
bids: [{
bidder: 'appnexus',
params: {
placementId: '4799418'
}
}]
}];
var pbjs = pbjs || {};
pbjs.que = pbjs.que || [];
You can also play with it on jsfiddle http://jsfiddle.net/prebid/bhn3xk2j/4/?utm_source=website&utm_medium=embed&utm_campaign=bhn3xk2j
And of course you don't need to modify prebid.js library code

Here geocoder API: retrieve route number based on coordinates

I noticed that I can retrieve route number based on coordinates using geocoding service. If coordinates are located outside the city, instead of street name geocoder returns route number (which is very useful).
Sometimes however route has multiple numbers - eg. "A4/E65/5". Unfortunately geocoder returns only one number - eg. "5". Is there any chance that geocoder can return full number?
Goeocder might not work here, have you tried getLinkinfo ?
e.g
http://route.st.nlp.nokia.com/routing/6.2/getlinkinfo.xml?app_id=DemoAppId01082013GAL&app_code=AJKnXv84fjrb0KIHawS0Tg&waypoint=45.79728,16.13712&linkattributes=all
With Geocoding use "locationattributes=addressNames". That will return many name variants including several languages and road numbers, e.g.
street: [
{
value: "A5",
language: "de"
},
{
value: "E451",
language: "de"
}
]

How to get a Facebook user's current country?

The Facebook Graph API provides a user's current location in two formats: name and ID. ID can be something like 104022926303756. Name can be something like Palo Alto, California or Beijing, China. From these two fields, how do I extract the country? All American locations are in the form [City], [State] whereas all non-American locations are in the form [City], [Country]. Can I code something less hacky than:
$states = array(
'Alabama'
'Alaska',
'Arizona',
// ...
);
$country = 'USA';
if (!in_array($locationName, $states)) {
preg_match('#, ([a-z]+$)#i', $locationName, $match);
$country = $match[1];
}
How about using this: http://developers.facebook.com/tools/explorer/?method=GET&path=fql%3Fq%3DSELECT%20current_location%20FROM%20user%20WHERE%20uid%3Dme()
?
As you can see, using FQL on user table, the JSON you'll receive is something like:
{
"data": [
{
"current_location": {
"city": "Turin",
"state": "Piemonte",
"country": "Italy",
"zip": "",
"id": 115351801811432,
"name": "Turin, Italy"
}
}
]
}
There you have the field country, much more readable :-)
EDIT: The link is broken because brakets are missing at the end of query, anyway the FQL query is:
SELECT current_location FROM user WHERE uid=me()
"me()" can be any user ID.
If you want more information you could use the latitude and longitude from https://graph.facebook.com/104022926303756 and feed them into a reverse geocoder.
http://maps.googleapis.com/maps/api/geocode/json?latlng=37.4293,-122.138&sensor=false
The Google API gives a lot of information, but it can be quite useful.
The country code may be a better idenfifier than the country name for example.
There's also the possibility to select output language. Adding &lang=sv gives you "Kalifornien" as the name of the state instead of "California".
It comes inside the signed request when they hit your app. It comes even when they still didn't approve your app.

How to implement geoip in node.js and mongodb

I have seen few examples of using geoip in node.js such as https://github.com/kuno/GeoIP.git and https://github.com/wadey/node-geoip. However what i want is to display the map showing geoip for the particular loged in user.How can it be implemented.
You can get a geolocation database (such as from http://www.maxmind.com) and store it in mongo. Each record contains an IP range (start/end) and the latitude/longitude associated with that IP range. IPs are represented as integers. You could create an index on the start field, and do a query on mongo to find the record with the largest value of start which is smaller than the IP of your client user, and look up the corresponding lat/lon.
As for plotting a map with this lat/lon, it's very easy to create a google map which is centered on a particular location: (View source at: http://code.google.com/apis/maps/documentation/javascript/v2/examples/map-simple.html)
There are a lot of different ways of storing/querying geolocation data, but this is just one possible approach using mongo that might work. Hope this helps.
The best module for GeoIP is https://github.com/kuno/GeoIP in my opinion (I actually used this module for a project and it worked perfectly for me). You have to download the database from Maxmind and also install some OS specific libraries and then compile the module.
There is no need to put the database into MongoDB unless you want to replicate easily across multiple servers. You can just put your database into a file and provide the path in the Node.js module.
Here is an example:
// Open the GeoLiteCity.dat file first.
var City = geoip.City;
var city = new City('/path/to/GeoLiteCity.dat');
console.log(city); // this contains country, city, lat, long, continent, postal code etc
I've just published an NPM module for the IPLocate.io API which I created, which lets you find the location (city, country and coordinates) based on an IP address.
Super easy, no databases to download, and 1,500 free requests per day.
Install
npm install node-iplocate
Usage
const iplocate = require("node-iplocate");
iplocate("8.8.8.8").then(function(results) {
console.log("IP Address: " + results.ip);
// IP Address: 8.8.8.8
console.log("Country: " + results.country + " (" + results.country_code + ")");
// Country: United States (US)
console.log("Continent: " + results.continent);
// Continent: North America
console.log("Organisation: " + results.org + " (" + results.asn + ")");
// Organisation: Google LLC (AS15169)
console.log(JSON.stringify(results, null, 2));
/*
{
"ip": "8.8.8.8",
"country": "United States",
"country_code": "US",
"city": null,
"continent": "North America",
"latitude": 37.751,
"longitude": -97.822,
"time_zone": null,
"postal_code": null,
"org": "Google LLC",
"asn": "AS15169"
}
*/
});
// Or with callbacks
iplocate("8.8.8.8", null, function(err, results) {
// ...
console.log(JSON.stringify(results, null, 2));
});
// Provide an API key from IPLocate.io
iplocate("8.8.8.8", { api_key: "abcdef" }).then(function(results) {
// ...
});
Python Implementation:
#!/usr/bin/python
#coding: utf-8
import os
import pygeoip
gi = pygeoip.GeoIP('GeoIP.dat')
gic = pygeoip.GeoIP('GeoIPCity.dat')
fl = file(r'apache-unique.log')
lines = fl.readlines()
for line in lines:
print gi.country_code_by_addr(line)
print gic.record_by_addr(line)
os.system('pause')
extending mpobrien's answer-
I found this to be easier and faster approach.
Download the binary db at maxmind
http://dev.maxmind.com/geoip/geoip2/geolite2/
http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz
Use node-maxmind-db
https://github.com/PaddeK/node-maxmind-db
var mmdbreader = require('maxmind-db-reader');
// open database
var countries = mmdbreader.openSync('./countries.mmdb');
// get geodata
app.get('/api/v1/ip/', function(req, res) {
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
countries.getGeoData(ip, function(err, geodata) {
if(!err && geodata.location) return res.json({success: true, location: geodata.location});
return res.json({success: false, location: null, error: err});
});
});
Then you will have user location based on his ip address which you can display on map.
Benefits-
The bindary data file is small and easy to update. No db import export.
Just swap the file and reload the data. ie- mmdbreader.openSync()