ipstack

package module
v0.0.0-...-4f32e54 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 19, 2020 License: MIT Imports: 8 Imported by: 0

README

Locate and identify website visitors by IP ipstack offers one of the leading IP to geolocation APIs and global IP database services worldwide.

(from https://ipstack.com/) Unofficial Golang ipstack library.

GoDoc Go Report Card


Take it

go get github.com/qioalice/ipstack

Initialize the package

Just call Init function and pass API token as string

ipstack.Init("token")

Init may return an error if you pass an invalid API token or if it can perform first test query (get info about your IP address).

You can handle it, of course, or disable performing first test query (for diff reasons) using constructor parameter ParamDisableFirstMeCall (read about it below).

if err := ipstack.Init("token"); err != nil { 
    panic(err) 
}

Want to get info about one IP?

Just call IP function and pass IP address info about you want to know as string to the that call.

if res, err := ipstack.IP("8.8.8.8"); err == nil { ... }

Response? Output data? IP info?

When you calling ipstack.IP or ipstack.Me you will get *Response and error objects, when ipstack.IPs - []*Response and error.

Anyway, Response contains an info about one requested IP address. This class don't have any methods and just have all public fields that you can check to get all desired info

But some info can be represented as pointers to the some internal auxiliary response instances: tResponseCurrency for Currency field, for example, or tResponseTimeZone for TimeZone field. It was made 'cause sometimes ipstack willn't provide you the whole information about IP - the all that he's can provide: may be you have limitiations on your account, or requested only 2 or 3 fields instead all.

if res, err := ipstack.IP("8.8.8.8"); err == nil {
    fmt.Printf("My IP: %s, My country: %s (%s)\n", res.IP, res.CountryName, res.CountryCode)
}

Bulk queries?

First, be sure that your account supports the bulk queries (starts from professional tariff). You can read check it and read about it here

So, just call IPs function and pass as many IP addresses as you want but not more than 50 (ipstack limitation).

if ress, err := ipstack.IPs("1.2.3.4", "8.8.8.8", ...); err == nil {
    for _, res := range ress {
        // do smth with each response
    }
}

Your IP address?

When you initialize package or create Client object (read about it below) if you don't disable first test query, you already can get instant info about your IP address. It already stored in the Client object.

So, you have Me function. If Client object already have info about your IP, Me just return it. Want a fresh info and overwrite cache? Me takes unnecessary bool argument, which makes the Me function delete cached info and request the fresh if it will be true.

me, err := ipstack.Me() // get cached info
me, err = ipstack.Me(true) // fetch the fresh info and save it to the cache

What is Client? And what's diff between New and Init

  1. There is no functions. Only methods. When you writing ipstack.IP(...) it means ipstack.DefaultClient.IP(...), and as you can guess, Init just initializes (calls New and stores the result) DefaultClient variable. Yes, each package level function (except New and Init of course) just an alias to the some method of DefaultClient object that has Client type.

  2. What is Client? Almost wrapper over http.Client object. To be more precision, the flexible way to perform the diff requests with one token (diff fields, diff checking error, diff allocating memory, etc).

  3. First New call includes the Init call. New creates a new Client instance with specified parameters. And if ipstack.DefaultClient object is nil, also store it to that.

So. Wanna use a few Clients with the diff tokens? I'm not against.

cli1, err1 := ipstack.New("token1") // 'cli1' also will be stored to the 'ipstack.DefaultClient'
cli2, err2 := ipstack.New("token2")
// ipstack.IP(...) call is the same as cli1.IP(...) (cause 'cli1' created by first calling of 'New')

Constructor (New, Init) arguments (tClientParam)

When you create a Client object using New function or initialize package level default client using Init method, you can pass arguments to the that functions.

I called them "constructors". So, for example you can pass API token as string directly or wrap it to the tClientParam object using ParamToken function.

They allows you to specify behaviour what you want.

ipstack.Init(ipstack.ParamToken("token"))

tClientParam arguments always overwrite arguments that has been passed as not tClientParam. Thus, in the example below, default client will be initialized with "token1"

ipstack.Init(ipstack.ParamToken("token1"), "token2")

Find your favorite parametrizers:

Parametrizer
Arguments
Description
ParamToken
string
The ipstack API token, Client will be created with. And each request from this Client will perform with.
ParamDisableFirstMeCall
none
Disables the first test query while creating the Client object. First test query is the request info about your IP address. If this request will be successfull, it means that Client instance created and initialized successfully. And result of that request stores to the internal cache and will be available using Me method instantly.
ParamUseHTTPS
bool
Switches the schema of Web API requests. true means "use HTTPS" and false means "use HTTP" respectively.
Warning! You can use HTTPS only on a non-free tariffs! You can check it and read about it here.
ParamFields
string...
Specify what kinds of IP's info you want to get from ipstack. You can use predefined constants which starts from Field word and pass constants only of that fields, what kind info you want know.
Warning! Some fields requires diff tariff plans. You can check it and read about it here.

And, for example, it looks like:

cli, err := ipstack.New(
    ipstack.ParamToken("token"), // specify token
    ipstack.ParamDisableFirstMeCall(), // disable first test query
    ipstack.ParamUseHTTPS(true), // force use HTTPS instead HTTP
    ipstack.ParamFields(ipstack.FieldCountryName, ipstack.FieldCurrency) // get only country name and currency info
)

Errors and API errors (tError)

Each IP, IPs or Me (or New/Init with enabled first test query) may return an error object (as only return argument or as a second, depends by method) (only if you're not calling tRequest methods directly, but more about that below).

In Golang, each error object represents by error interface, and error object will be represented by that type.

But you can get API error.

API error is the special error type which signals that technically request will be successfully sent and response will be successfully received and decoded. But contains not an info about requested IP(s) but error message.

In that case you must handle that error as you want. That error represents by tError class, that as you guess, implements the error interface.

At your disposal APIError function that takes an argument of error type and returns the *tError not nil object if error is tError object, and nil if error isn't (and it doesn't matter error is nil or not).

So, now you have tError object. Just check "code", "type", "info" entities to know what kind of error is occur. Use Code, Type and Info methods for that.

And at your service, you can call any of these methods from nil tError object. It means, that if APIError will return nil, you can chain directly Code or Type or Info, w/o checking whether returned object is nil or not.

If tError object is nil, Code will return 0, and Type and Info an empty "" string.

res, err := ipstack.IP("8.8.8.8")
if err := ipstack.APIError(err); err.Code() != 0 {
    // API error is occurred
    panic(err.Type() + " " + err.Info())
}
if err != nil {
    // Unknown error is occurred
    panic(err)
}

R method and tRequest, tResponse classes

Want more flexibility? Get it!
Worry about each allocated byte? Save it!
Want another JSON decoder or/and API error checker? Use it!

Each request to the ipstack Web API represents by tRequest object. Each response by tResponse. No exceptions.

Moreover, Client doesn't contain any behaviour definitions but contains the default request object (tReqeust type), and each call 'IP', 'IPs' or 'Me' method of 'Client' class it's just calling the same methods of default tRequest object. But it can be modified! Even already! Constructor parametrizers have the almost same logic.

What you should know?
  1. tRequest methods return tResponse objects. Always. This is a lower level. The price for more flexibility. tResponse objects contains RAW not decoded JSON data by default (RawData field) and error object (Error field) that represents some request or response error. But it guarantees, that if RawData is nil, Error isn't and vice versa.

  2. When you get tRequest object, all what you've done with it, willn't apply to the Client object from which you got tRequest object. You can request some different fields for one request, or made it with HTTPS instead HTTP, why not? And any change of behaviour don't saved anywhere except tReqeust object you're working with. But by default this is just a copy of default request of Client.

  3. Don't forgot whether response contains API error. As you know, tResponse object contains not decoded JSON RAW data as RawData field. But API may return encoded JSON error. You must check it. Or use internal function CheckError. So, Client methods IP, IPs, Me, if you'd see, just calling the same methods of tRequest and then checks error using CheckError method of tResponse and decode JSON using DecodeTo method (of tResponse too). You can use CheckError method, or do it the way you want.

  4. How to decode JSON? This is the finish step. May be checking error and decoding JSON in your logic is the one step, but I prefer to split these steps.
    So, you can use DecodeTo method, that receives only one argument - the destination object. By default it just calls the json.Unmarshal function with tResponse.RawData and received destination argument. But you can decode as you want - by custom JSON decoder, with the saving each unneccessary byte, with writing a very RAM-efficiency algorithm.

How use it?
  1. Call R method of some Client object or call R package function. You'll get tRequest object (copy of base client's request object) with which you can do the next steps.

  2. Change behaviour of tRequest. You can use any of described below tRequest method to change its behaviour.

  3. Perform request. Call IP, IPs or Me method, save the result (tResponse instance).

  4. Check error and decode JSON response. Use CheckError, DecodeTo methods of tResponse or use your personal way.

// 'cli' will always perform requests over HTTPS and with default set of fields
cli, err := ipstack.New("token", ipstack.ParamUseHTTPS(true)) 
// but we want perform a few queries over HTTP and with only one field - ip's country name

// we can save cretated 'tRequest' object and then perform queries
req := cli.R().UseHTTPS(false).Fields(ipstack.FieldCountryName) // 'req' type is '*tRequest'
resp1 := req.IP("8.8.8.8") // 'resp' type is '*tResponse', query over HTTP and with only one field
resp2 := req.IP("1.2.3.4") // the same as above
resp3 := cli.IP("1.2.3.5") // will be over HTTPS and with default fields

// or don't save 'tRequest' object and perform query right away
// but in this way we should change behaviour to the desired each time
resp1 = cli.R().UseHTTPS(false).Fields(ipstack.FieldCountryName).IP("8.8.8.8")
resp2 = cli.R().UseHTTPS(false).Fields(ipstack.FieldCountryName).IP("1.2.3.4")
resp3 = cli.IP("1.2.3.5") // will be over HTTPS and with default fields

// then we must check errors
if err := resp1.CheckError(); err != nil {
    if err := ipstack.APIError(err); err.Code != 0 {
        // Some API error, check 'err.Code(), err.Type(), err.Info()'
    } else {
        // Some another error
    }
}
// and decode JSON (for example to the map)
mresp := map[string]interface{}{}
if err := resp1.DecodeTo(&mresp); err != nil {
    // Decode error
}

// or may be you want check error and decode JSON manually over each byte?
for _, b := range resp1.RawData { ... } // 'resp1.RawData' type is '[]byte'

To Do

The current version of this library is beta.

  • There is no tests (they're exists, but I don't commit them now, I'll do it later, when I'll documented them and make them more cute).
  • Also, there is no examples. I tried to write as much code examples as I can, but anyway, there's no complex example. One or more.
  • And, of course, may be I'll add some another functional to the libarary, but atm I dunno what else I can add.
    But. I definitely won't break the package API.

License

qioalice@gmail.com, Alice Qio, 2019.
MIT

Documentation

Index

Constants

View Source
const (
	// Returns the requested IP address.
	FieldIp string = "ip"
	// Returns the hostname the requested IP resolves to,
	// only returned if Hostname Lookup is enabled.
	FieldHostname string = "hostname"
	// Returns the IP address type IPv4 or IPv6.
	FieldType string = "type"
	// Returns the 2-letter continent code associated with the IP.
	FieldContinentCode string = "continent_code"
	// Returns the name of the continent associated with the IP.
	FieldContinentName string = "continent_name"
	// Returns the 2-letter country code associated with the IP.
	FieldCountryCode string = "country_code"
	// Returns the name of the country associated with the IP.
	FieldCountryName string = "country_name"
	// Returns the region code of the region associated with the IP
	// (e.g. CA for California).
	FieldRegionCode string = "region_code"
	// Returns the name of the region associated with the IP.
	FieldRegionName string = "region_name"
	// Returns the name of the city associated with the IP.
	FieldCity string = "city"
	// Returns the ZIP code associated with the IP.
	FieldZip string = "zip"
	// Returns the latitude value associated with the IP.
	FieldLatitude string = "latitude"
	// Returns the longitude value associated with the IP.
	FieldLongitude string = "longitude"
	// Returns multiple location-related objects
	FieldLocation string = "location"
	// Returns the unique geoname identifier
	// in accordance with the Geonames Registry.z
	FieldLocationGeonameId string = "location.geoname_id"
	// Returns the capital city of the country associated with the IP.
	FieldLocationCapital string = "location.capital"
	// Returns an object containing one or multiple
	// sub-objects per language spoken in the country associated with the IP.
	FieldLocationLanguages string = "location.languages"
	// Returns the 2-letter language code for the given language.
	FieldLocationLanguagesCode string = "location.languages.code"
	// Returns the name (in the API request's main language)
	// of the given language. (e.g. Portuguese)
	FieldLocationLanguagesName string = "location.languages.name"
	// Returns the native name of the given language. (e.g. Português)
	FieldLocationLanguagesNative string = "location.languages.native"
	// Returns an HTTP URL leading to an SVG-flag icon for the country
	// associated with the IP.
	FieldLocationCountryFlag string = "location.country_flag"
	// Returns the emoji icon for the flag of the country associated with the IP.
	FieldLocationCountryFlagEmoji string = "location.country_flag_emoji"
	// Returns the unicode value of the emoji icon for the flag of the country
	// associated with the IP. (e.g. U+1F1F5 U+1F1F9 for the Portuguese flag)
	FieldLocationCountryFlagEmojiUnicode string = "location.country_flag_emoji_unicode"
	// Returns the calling/dial code of the country associated with the IP.
	// (e.g. 351) for Portugal.
	FieldLocationCallingCode string = "location.calling_code"
	// Returns true or false depending on whether or not the county
	// associated with the IP is in the European Union.
	FieldLocationIsEu string = "location.is_eu"
	// Returns an object containing timezone-related data.
	FieldTimeZone string = "timezone"
	// Returns the ID of the time zone associated with the IP.
	// (e.g. America/LosAngeles for PST)
	FieldTimeZoneId string = "timezone.id"
	// Returns the current date and time in the location
	// associated with the IP. (e.g. 2018-03-29T22:31:27-07:00)
	FieldTimeZoneCurrentTime string = "timezone.current_time"
	// Returns the GMT offset of the given time zone in seconds.
	// (e.g. -25200 for PST's -7h GMT offset)
	FieldTimeZoneGmtOffset string = "timezone.gmt_offset"
	// Returns the universal code of the given time zone.
	FieldTimeZoneCode string = "timezone.code"
	// Returns true or false depending on whether or not the given time zone
	// is considered daylight saving time.
	FieldTimeZoneIsDaylightSaving string = "timezone.is_daylight_saving"
	// Returns an object containing currency-related data.
	FieldCurrency string = "currency"
	// Returns the 3-letter code of the main currency associated with the IP.
	FieldCurrencyCode string = "currency.code"
	// Returns the name of the given currency.
	FieldCurrencyName string = "currency.mame"
	// Returns the plural name of the given currency.
	FieldCurrencyPlural string = "currency.plural"
	// Returns the symbol letter of the given currency.
	FieldCurrencySymbol string = "currency.symbol"
	// Returns the native symbol letter of the given currency.
	FieldCurrencySymbolNative string = "currency.symbol_native"
	// Returns an object containing connection-related data.
	FieldConnection string = "connection"
	// Returns the Autonomous System Number associated with the IP.
	FieldConnectionAsn string = "connection.asn"
	// Returns the name of the ISP associated with the IP.
	FieldConnectionIsp string = "connection.isp"
	// Returns an object containing security-related data.
	FieldSecurity string = "security"
	// Returns true or false depending on whether or not the given IP
	// is associated with a proxy.
	FieldSecurityIsProxy string = "security.is_proxy"
	// Returns the type of proxy the IP is associated with.
	FieldSecurityProxyType string = "security.proxy_type"
	// Returns true or false depending on whether or not the given IP
	// is associated with a crawler.
	FieldSecurityIsCrawler string = "security.is_crawler"
	// Returns the name of the crawler the IP is associated with.
	FieldSecurityCrawlerName string = "security.crawler_name"
	// Returns the type of crawler the IP is associated with.
	FieldSecurityCrawlerType string = "security.crawler_type"
	// Returns true or false depending on whether or not the given IP
	// is associated with the anonymous Tor system.
	FieldSecurityIsTor string = "security.is_tor"
	// Returns the type of threat level the IP is associated with.
	FieldSecurityThreatLevel string = "security.threat_level"
	// Returns an object containing all threat types associated with the IP.
	FieldSecurityThreatTypes string = "security.threat_types"
)

Predefined consts each of that represents some field in JSON response from ipstack on the some request.

So, you can read on https://ipstack.com/documentation that you can specify what fields should be returned as response. Using that consts and 'Fields' method of 'Client' or 'tRequest' classes you can do it.

Variables

This section is empty.

Functions

func APIError

func APIError(e error) *tError

'APIError' tries to cast 'e' object to the 'tError' object. 'tError' is the internal private class, represents the some Web API error. If 'e' is the object of 'tError' class, it will be returned by pointer, otherwise nil is returned.

Because all methods that returns an error object, return object of 'error' interface, not an 'tError' instance, in golang you must check if some object that implements 'error' interface is really 'tError' instance. You can use this function for it and then, for example, if you want to check the error code, just call 'Code' method. Even if this method will return nil as '*tError' object, method 'Code' willn't panic and 0 will be returned by 'Code'. Check methods 'Code', 'Type' and 'Info' for details.

func Init

func Init(params ...interface{}) error

'Init' initializes 'DefaultClient' variable. This variable represents default client that used by package functions 'IP', 'IPs' and 'UpdateMe'.

Thus, you can just once call 'Init' function (initialize default client) and then in any place just call 'IP', 'IPs', 'UpdateMe' package level functions and accessing to the 'DefaultClient' variable. Thus you will have only one 'Client' instance in all your app, and if it's enough for you, you do not need to call 'New' directly for creting other 'Client' object, and most importantly do not need to worry about where to store 'Client' object, or about how to provide access to storing object and other architecture solutions. Just call 'Init' and then call package level functions. It's so easy and simple.

NOTE! You can call this function as much as you want. I can't imagine for what you might need this feature, but it's possible. In that case, the behaviour is predictable - the previous version of default client will be overwritten by new. BUT! If any error occurred while trying to reinitialize default client (create new object of default client) the previous default client willn't be overwritten by nil object and also will be available.

NOTE! See 'New' docs to understand what you must or can pass as arguments.

func ParamDisableFirstMeCall

func ParamDisableFirstMeCall() tClientParam

'ParamDisableFirstMeCall' creates a parameter for 'Client' constructors that skips the first internal calling 'Me' method when 'Client' object will be created successfully.

NOTE! Yes, when you create a 'Client' object by default it tries to perform first test query, and if it was successfull, the 'Client' object treates as succeessfully created (and response object is decoded and stored as info of the current IP address and will be available by calling 'Me' method w/o force fetch).

func ParamFields

func ParamFields(fields ...string) tClientParam

'ParamFields' creates a parameter for 'Client' constructors that allows you to specifiy what kinds of response you want to get from ipstack Web API.

You can pass as many fields as you want. You can write field names manually or using predefined consts started with 'Field...' prefix and described above.

func ParamToken

func ParamToken(token string) tClientParam

'ParamToken' creates a parameter for 'Client' constructors that specifies the API token, 'Client' object must be created with.

func ParamUseHTTPS

func ParamUseHTTPS(is bool) tClientParam

'ParamUseHTTPS' creates a parameter for 'Client' constructors that obliges to always use HTTPS schema instead HTTP.

WARNING! You can use HTTPS schema only if you have non-free ipstack account.

func R

func R() *tRequest

'R' is the same as 'R' of any 'Client' instance but only for default client. See docs for 'Client.R' method and 'DefaultClient' variable for details.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

'Client' is the class that represents golang point to make Web API requests to ipstack.

WARNING! Do not create this object directly! This class has important private fields that must be initialized only by constructor. Use 'New' function to create a new 'Client' object.

After 'Client' object created, (and if you don't disable first check) you already have an information about your IP.

var DefaultClient *Client

Default client. It will be initialized directly by calling 'Init' function, or when you will call 'New' function first time and that call will be successfull, the 'New' function will also tagged the created client as default client (will store pointer to the 'DefaultClient').

func New

func New(params ...interface{}) (*Client, error)

'New' creates a new 'Client' instance with specified 'params'. When object created and all required prechecks are completed and passed, constructor tries to perform test request: Checking IP address of machine request made from. If it will be successfull, the result will be saved as 'Me' field in 'Client' object, and current timestamp will be saved as 'MeTimestamp'.

NOTE: If any error will be occur at the some step, the not nil error object will be returned as second return argument.

NOTE: If the second return argument (error object) isn't nil, the first argument ('Client' object by pointer) is nil! Always! No exceptions!

Arguments: You can pass arguments of some different types in the order you want. Arguments will be identified by its type. If you will pass argument of unsupported type, it will be ignored. if you will pass more than one params of the same type, the all previous values will be shadowed by the last value. [*] - means that this argument is required.

-- Table of supported argument's types and how they treated are --

[*] {string, []byte} Token. API token that will be used as accessing token to perform each request to the ipstack Web API. If this argument willn't pass, error will return immediately.

[ ] {http.Client, *http.Client} Golang HTTP client. This object will be used to perform each request to the ipstack Web API. If this argument willn't pass, the HTTP client with default params will be used (see docs for 'http.Client' golang package).

func (*Client) IP

func (c *Client) IP(ip string) (*Response, error)

'IP' returns the info about 'ip' as 'Response' object. If any error occur, the second return argument will contain error object.

func (*Client) IPs

func (c *Client) IPs(ips ...string) ([]*Response, error)

'IPs' returns the info about each requested IP addresses (you can pass more than one IP address as arguments) as slice of 'Response' objects. You can pass up to 50 IP addresses to the this method. If any error occur, the second argument will contain error object.

func (*Client) Me

func (c *Client) Me(forceFetch ...bool) (*Response, error)

'Me' fetches the fresh info about your IP address and if this operation was successfull, store it as 'Me' field of the current object. todo: fix comment

func (*Client) R

func (c *Client) R() *tRequest

'R' is the way to the improve your flexibility! 'R' returns the 'tRequest' object - object of special type, that contains in itself all important data to perform Web API request, and, that most importantly, have some methods to change its behaviour! See docs for 'tRequest' object and see 'tRequest' methods.

NOTE! Yes, it's very simple. You can just call 'R' method of your client object, or call 'R' package level function to get package level default client request object, then call all methods to configure request sentence and then just call 'IP' or 'IPs' methods and you'll get result you want w/o changes behaviour of your 'Client' object!

For example: c, err := ipstack.New(...) resp, err := c.R().<some_configure_method>(...).IP(1.2.3.4)

And, of course, you can chain all configure methods!

For example: _, _ := c.R().<method1>(...).<method2>(...).<method3>(...).IP(1.2.3.4)

WARNING! All finishers of 'tRequest' object returns 'tRawResponse' object! It means, that you need manually check if any error is occur and manually decode the raw JSON response. BUT! You can use 'CheckError' and 'DecodeTo' methods of 'tRawResponse' class. In truth, the 'IP', 'IPs' and 'UpdateMe' methods of 'Client' works that way.

type Response

type Response struct {
	IP            string               `json:"ip"`
	Hostname      string               `json:"hostname"`
	Type          string               `json:"type"`
	ContinentCode string               `json:"continent_code"`
	ContinentName string               `json:"continent_name"`
	CountryCode   string               `json:"country_code"`
	CountryName   string               `json:"country_name"`
	RegionCode    string               `json:"region_code"`
	RegionName    string               `json:"region_name"`
	City          string               `json:"city"`
	Zip           string               `json:"zip"`
	Latitide      float32              `json:"latitude"`
	Longitude     float32              `json:"longitude"`
	Location      *tResponseLoc        `json:"location"`
	Timezone      *tResponseTimeZone   `json:"time_zone"`
	Currency      *tResponseCurrency   `json:"currency"`
	Connection    *tResponseConnection `json:"connection"`
	Security      *tResponseSecurity   `json:"security"`
}

'Response' represents the golang view of Web API response. Fields 'Location', 'Timezone', 'Currency', 'Connection', 'Security' might be nil, if you didn't request it earlier using 'Fields' method of 'Client' or 'tRequest' classes, or 'ParamFields' parameter of 'Client' constructor ('New' function).

NOTE! If you do not understand what data stored in field, read the docs of the consts 'Field...' (above).

func IP

func IP(ip string) (*Response, error)

'IP' is the same as 'IP' of any 'Client' instance but only for default client. See docs for 'Client.IP' method and 'DefaultClient' variable for details.

func IPs

func IPs(ips ...string) ([]*Response, error)

'IPs' is the same as 'IPs' of any 'Client' instance but only for default client. See docs for 'Client.IPs' method and 'DefaultClient' variable for details.

func Me

func Me(forceFetch ...bool) (*Response, error)

'Me' is the same as 'Me' of any 'Client' instance but only for default client. See docs for 'Client.Me' method and 'DefaultClient' variable for details.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL