Search code examples
androidapihttpxamaringoogle-url-shortener

google URL shortener API error (403 forbidden) [update]


So I'm trying to use Google URL Shortener API in my app. Here's the class I wrote to make the HTTP call and retrieve the shortened URL.

public class GoogleUrlShortnerApi
{
    //API Key from Google
    private const string key = "-----------MY_KEY-----------";

    public static string Shorten(string url)
    {
        string post = "{\"longUrl\": \"" + url + "\"}";

        string shortUrl = url;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.googleapis.com/urlshortener/v1/url?key=" + key);

        try {
            request.ServicePoint.Expect100Continue = false;
            request.Method = WebRequestMethods.Http.Post;
            request.ContentLength = post.Length;
            request.ContentType = "application/json";
            request.Headers.Add("Cache-Control", "no-cache");

            using (Stream requestStream = request.GetRequestStream())
            {
                byte[] postBuffer = Encoding.ASCII.GetBytes(post);
                requestStream.Write(postBuffer, 0, postBuffer.Length);
            }

            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                using (Stream responseStream = response.GetResponseStream())
                {
                    using (StreamReader responseReader = new StreamReader(responseStream))
                    {
                        string json = responseReader.ReadToEnd();
                        shortUrl = Regex.Match(json, @"""id"": ?""(?<id>.+)""").Groups["id"].Value;
                    }
                }
            }
        } catch (WebException webEx) {
            System.Diagnostics.Debug.WriteLine (webEx.Message);

            string responseText;
            using(var reader = new StreamReader(webEx.Response.GetResponseStream()))
            {
                responseText = reader.ReadToEnd();
            }
        } catch (Exception ex) {
            System.Diagnostics.Debug.WriteLine (ex.Message);
        }
        return shortUrl;
    }
}

But I keep getting the "The remote server returned an error: (403) Forbidden." error.

I tried to debug and put a breakpoint on the 2nd using in the class..

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())

It never goes inside that using and catches a WebException.
Can anyone give me an idea on what I'm doing wrong here?

Thank you for your time.

========================= UPDATE =========================

This is the value of the responseText from the WebException. I'm allowed to make 1,000,000 request per day. Why am I getting this error?

{
 "error": {
  "errors": [
   {
    "domain": "usageLimits",
    "reason": "ipRefererBlocked",
    "message": "There is a per-IP or per-Referer restriction configured on your API key and the request does not match these restrictions. Please use the Google Developers Console to update your API key configuration if request from this IP or referer should be allowed.",
    "extendedHelp": "https://console.developers.google.com"
   }
  ],
  "code": 403,
  "message": "There is a per-IP or per-Referer restriction configured on your API key and the request does not match these restrictions. Please use the Google Developers Console to update your API key configuration if request from this IP or referer should be allowed."
 }
}

Solution

  • There is a per-IP or per-Referer restriction configured on your API key and the request does not match these restrictions. Please use the Google Developers Console to update your API key configuration if request from this IP or referer should be allowed.

    I read that as your API key is setup to be restricted by IP and your request is coming from an IP that is not registered to use that API key. Keep in mind that requests from the emulator will (most likely) have a different IP than the machine they are running on, because the Android emulator is a separate VM.

    Either figure out the IP that the request is originating from and register it with your API key, or (if possible) switch the restriction to be per-Referer and handle that in your code.