Scopes guides - keywords

So you have written a scope? Great! Now how do you get your scope noticed? Although “CoolScope” is a pretty awesome name, often simply giving something a name is not good enough to describe what it is.

Let's say your scope is a “cooking lessons” scope. Wouldn’t it be awesome if users could see results from your scope in the Food aggregator? What if your scope included instructional videos on cooking, these could show up in the Videos scope. What you want is for your scope to be easily identifiable and discoverable, both to aggregators and to the user. To achieve this, your scope needs to describe its content in some way. What you also want is a way of telling what content an aggregator is interested in when it calls your scope (e.g. returning video results when queried by the Videos scope).

Here is where scope keywords come in...

What are scope keywords?

You could think of scope keywords like you would keywords for a website. On the web, keywords are used by search engines to find relevant web pages. In the context of scopes there are at least two “search engines” that are interested in your content: users searching for scopes on the store, and aggregators looking for child scopes. You need to add keywords to your scope in order to improve its discoverability in these searches.

In the case of our “cooking lessons” example, we could add the keywords “food” and “video”. This way, aggregators looking for scopes with “food” (e.g. the Food scope) or “video” (e.g. the Videos scope) content can find our scope and aggregate its results accordingly. We can also add some conditional logic to our scope to return only the results relevant to the keyword(s) used by an aggregator. Returning results about the latest cookbooks to the Videos scope is not a great user experience (lets try not have our scope uninstalled by unhappy users).

How do I use keywords?

Step 1: add keywords to your scope

Adding keywords to your scope is really easy. All you need to do is add a “Keywords” key to the [ScopeConfig] group of your scope’s .ini file. The value of the “Keywords” key must be a semicolon separated list of keywords that identify your scope. For example: a scope with one keyword looks like this:

[ScopeConfig]
DisplayName = human readable name of scope
Description = description of scope
Author = author
Keywords = music

A scope with multiple keywords looks like this:

[ScopeConfig]
DisplayName = human readable name of scope
Description = description of scope
Author = author
Keywords = music;video;news

Step 2: return results according to the keywords requested

In order for your scope to return results relevant to the keyword(s) used by an aggregator, you need a way of telling what keywords were used to discover your scope. Your scope’s ScopeBase::search() method is called once for each search query. This method receives two arguments: a CannedQuery object, and a SearchMetadata object. SearchMetadata contains a bunch of additional information about the search requests you receive, including the methods:

  • is_aggregated() - true if the request was initiated by an aggregator,
  • aggregated_keywords() - the list of keywords used to discover your scope.

ScopeBase::search() is a factory method, so be sure to store the SearchMetadata object into the instance of SearchQueryBase you return for later use:

class MyQuery : public SearchQueryBase { ... };
SearchQueryBase::UPtr MyScope::search(CannedQuery const& query, SearchMetadata const& metadata)
{
    SearchQueryBase::UPtr q(new MyQuery(query, metadata));
    return q;
}

Now that you have instantiated a SearchQueryBase object containing the request’s SearchMetadata, you can use the is_aggregated() and aggregated_keywords() methods from within SearchQueryBase::run() to return the appropriate results:

void MyQuery::run(SearchReplyProxy const& reply)
{
    if (metadata_.is_aggregated())
    {
        auto keywords = metadata_.aggregated_keywords();
        if (keywords.find("food") != keywords.end())
        {
            auto category = reply->register_category("food",
                                                     "CoolScope Food",
                                                     food_icon);
            do_food_search(reply, category);
        }
        else if (keywords.find("video") != keywords.end())
        {
            auto category = reply->register_category("video",
                                                     "CoolScope Videos",
                                                     videos_icon);
            do_video_search(reply, category);
        }
    }
    else
    {
        do_normal_search(reply);
    }
}

You may notice in the code snippet above that for each keyword-related search we receive, we register a specific results category. Although aggregators may be willing to accept more than one category from its child scopes, they are only required to accept the first.

Thereafter, an aggregator may choose to ignore any additional categories the child scope registers. It is therefore recommended that scope authors follow the above method of handling aggregated searches. It is also recommended that your scope provide a decent category title (e.g. “CoolScope Food” / “CoolScope Videos”). An aggregator is likely to display this category title as is within its result set, so try to keep it clean and descriptive.

Returning the right components

To fit in well, a child scope should take care return the result components expected by aggregators for that keyword. Please see the aggregator scopes integration guide.

What keywords should I use?

Namespaced keywords

In some cases, a list of keywords is not specific enough. For example, if a scope has "sports" and "news" keywords, does that mean it includes only sports news? or does it mean it includes some news and some sports. Also, what components should the returned results contain: those appropriate to sports or to news?

Some scopes use namespaced keywords to clarify this. This allows scope developers to pick the right keywords and to understand what is expected of results under that keyword.

For example, the "news.sports" keyword clearly indicates its a news item about sports. There could also be a "videos.sports" keyword that clearly indicates that the scope returns sports videos.

For details about specific aggregator scopes, the keywords they listen for, and their expectations for results, please see the aggregator scopesintegration guide.

General keywords

Below is a table of general keywords to use. Obviously this table doesn’t aim to cover every type of scope imaginable, nor are scopes limited to using only the keywords listed here, however it is best to try stick to these as much as possible in order for your scope to be visible to aggregators.

Keyword Description Example scopes Other example sources
apps A resource for finding and installing applications Ubuntu Store -
audio Any audio that isn't "music", such as podcasts or audio sample libraries Jupiter Broadcasting TWiT, podcasts
books Either a digital or hard copy provider of books Amazon, OpenLibrary AbeBooks, The Book Depository
business A directory for finding local or international businesses Google Places, Kickstarter, Yahoo Finance, Yelp Glassdoor, YellowPages
career Any source that provides career opportunities or listings Ars Technica, Kickstarter, Techfunder SimplyHired, Linkedin
comics Anything comic-related from online comics to comic-based films Evert Kwok, Marvel Entertainment, XKCD comiXology, DC Comics
data Referring to any local or remote storage of data such as file-sharing, email, etc. GMail Google Drive
design Any visual design that doesn’t fall under “art”, such as architecture, logos, etc. Free CAD Videos 99designs
developer Resources specific to software development Jupiter Broadcasting, NoobsLab, Softpedia Linux AskUbuntu, DevHelp
diy General do-it-yourself guides that don’t fall under “developer” or
“educational” - Lifehacker, Instructables
drink Any info about drinks, general or specific, alcoholic or nonalcoholic 8coupons, Google Places, TimeOut, Untappd Mixology
educational A provider of learning materials to furthering one’s education Free CAD Videos, NoobsLab, OpenLibrary Coursera
finance Money related info such as banking, investments, stocks, etc. Yahoo Finance Bloomberg, Forbes
fitness A resource that promotes, details, or assists in one’s physical fitness My Activity, Runkeeper Fitbit, Jawbone
food Anything to do with food, be it preparation, consumption, or nutrition facts 8coupons, Google Places, Nutritionix, TimeOut AllRecipes, theKitchn
gaming Video game info, news, reviews, previews, trailers, cheats, etc. Jupiter Broadcasting IGN, Zynga
health A resource that promotes healthy living that isn’t necessarily "fitness" related My Activity, Nutritionix, Runkeeper WebMD, WeightWatchers
humor Anything funny in any format, be it books, comics, audio, video, etc. Evert Kwok, The Shovel, XKCD 9GAG
info The type of factual information you’d find in an encyclopaedia Stellar, Wikipedia Britannica
interests Any general and special interests that don’t quite fit into a common category 8coupons, OpenLibrary, Stellar, TimeOut, uBrick Autoblog, CyclingWeekly, Pinterest
kids Kid friendly resources such as toys, cartoons, media, games, etc. uBrick Yahoo! Kids, Nickelodeon
lifestyle Info or advice on home and garden, outdoor living, fashion, beauty, etc. InStyle houzz, GoodHousekeeping
magazines Either a digital or hard copy provider of magazines OpenLibrary Time, WIRED
movies Referring to full length films, either on cinema or personal media formats Cinema, Films, Hot New Trailers, TimeOut, YouTube IMDB, TMDB, Netflix, Hulu
music Anything music-related such as songs, artists, interviews, etc. 7digital, Grooveshark, SoundCloud, YouTube LastFM, Spotify
nearby Any service that utilises the user’s location in order to show nearby results Google Places, Meetup, The Weather Channel, Yelp Bandsintown, Yahoo Local
news A provider of information about recent events or happenings BBC News, euronews, Hacker News, Ubuntu News Google News, CNN
personal Referencing the user’s personal data such as files, messages, online profiles, etc. GMail, Kodi, My Music, My Videos, Tasks, Telegram Calls, Contacts, Notes
photos Referring to a resource of still photographs Flickr, Imgur, Instagram, Kodi, Your Shot Picasa
reference The type of reference information you’d find in a dictionary or atlas Dictionary, Stellar, Urban Dictionary, Wikipedia Google Maps
science Any resource on science and / or mathematics that doesn’t fall under “tech”. Ars Technica, Stellar, XKCD PopSci
shopping A store (online or physical) from which users can buy merchandise Amazon, eBay, Etsy Orange
social Any service that allows users to interact and share with each other Flickr, Meetup, Reddit, Telegram, Twitter Trending Facebook, Google+
sports Any sports-related resources about any type of sport BBC Sport, Formula One, La Liga, Premier League ESPN, FOX Sports
tech Any resource on technology that doesn't fall under “developer” or “science” Ars Technica, CNET, engadget, Triple Tremelo TechCrunch
traffic A resource for providing details on local or international road traffic conditions Boston MBTA INRIX
travel Information on any form of travelling, whether by foot, car, train, aircraft, etc. 8coupons, Boston MBTA, London Tube, TimeOut TripAdvisor, trivago
trending A resource for what is currently popular in fashion, media, news, etc. InStyle, Twitter Trending E!, TrendHunter
tv Referring to TV in general not “movies”, such as TV series, live broadcasts, etc. EZTV, Hot New Trailers, PBS Video, TimeOut Netflix, Hulu
video Any video resource that doesn’t necessarily fall under “movies” or “tv” Evert Kwok, Free CAD Videos, Kodi, Vimeo, YouTube Dailymotion, Vevo
weather A resource for providing details on local or international weather conditions The Weather Channel OpenWeatherMap
web General web services such as search engines, crawlers, scrapers, etc. Discerning Duck Google, Bing