Use Case - Looking Up Phone Numbers via Search.ch API

Submit an API request to search.ch in order to look up unknown phone numbers.

Local.ch and search.ch are services of the Swisscom Directories (https://www.localsearch.ch/). The platform’s core product is basically Switzerland’s phone directory and services range from presence & marketing services to online service tools (such as online booking & reservation, online payment, website builder, comparison platform.) search.ch provides contact information in form of a classical phone book directory. One can use their API to query the directory.

As of  the terms of service states: “The monthly usage quota per customer and API-Key is 1000 requests. A maximum of 20 results are provided per request.” Therefore, we can freely use the API, but should limit the requests. This means that we need to store it in our local CRM system to avoid re-querying it each time. Storage is allowed, but we need to comply to the terms of use (“Permitted types of use“). When storing information, source reference must be provided with all forms of API usage: “Swisscom Directories AG“.


☝ Please note that the terms of use can change any time! Before implementing this flow, please check Phone directory - API Terms of Use - search.ch.

 

PRECONDITIONS

  • Search.ch API key. You can request a key here: https://tel.search.ch/api/getkey 🔍 Note that keys might be limited to one per company.
  • Power Automate Premium licence (required to make use of "HTTP requests")
  • A CRM connected to Power Automate
 

How-to Steps

Initialize the variables

✅ In our example we need to initialize two variables to handle throughout the flow:

  1. APIKey (String) as container for your Search.ch API request
  2. searchQuery (String) - in our example we use the phone number which is stored in Nimbus as “MicrosoftCallerID”  

First internal CRM check

✅ Ensure that your service's workflow has a "Accept ConversationWorkflow Activity which starts the "GetOnNewTasksTrigger Event.

  1. Add a "GetOnNewTasks" Nimbus activity to your flow.
  2. Retrieve the "MicrosoftCallerID and check in your CRM if the caller is known.   
    ☝ Since we have limited API calls it makes sense to check internally first and limit the external requests.
  3. ONLY when the caller is not found in your CRM we want to make a request on Search.ch → See next step.

Make API Request

✅ Here we assume your internal CRM did yield no results.

  1. Add a HTTP request to Search.ch with your previously created variables.  
    1. OPTIONALLY you can also check if the request has been successful status=200 and react accordingly. Note that Nimbus will not wait for any flow results while a call is handled, so you might want to skip out of the flow early with a token error to keep response times short.  
      💡 Related Tip: You can also store return values in Nimbus parameters in case you want to react to a status or redirect "unknown" callers. See our Use Case - Storing external CRM data in custom parameters.
  2. Store the response "Body" from the HTTP request in a "Compose" element  

Here is an example API return body: https://tel.search.ch/examples/api-response.xml

Show an example Luware-Response

<?xml version="1.0" encoding="utf-8" ?>
                                <feed xml:lang="de" xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:tel="http://tel.search.ch/api/spec/result/1.0/">
                                 <id>https://tel.search.ch/api/d89734ad31b70f1f7487ce6630088d3c/dadc4ed1ae337c00ef6cbb4a6d6afd38</id>
                                 <title type="text">tel.search.ch API Search Results</title>
                                 <generator version="1.0" uri="https://tel.search.ch">tel.search.ch</generator>
                                 <updated>2022-03-03T13:16:49+01:00</updated>
                                 <link href="https://tel.search.ch/result?was=05840428" rel="alternate" type="text/html" />
                                 <link href="http://tel.search.ch/api/?was=+41+58+404+28&key=d89734ad31b70f1f7487ce6630088d3c" type="application/atom+xml" rel="self" />
                                 <openSearch:totalResults>1</openSearch:totalResults>
                                 <openSearch:startIndex>1</openSearch:startIndex>
                                 <openSearch:itemsPerPage>10</openSearch:itemsPerPage>
                                 <openSearch:Query role="request" searchTerms="05840428 " startPage="1"></openSearch:Query>
                                 <openSearch:Image height="1" width="1" type="image/gif">https://www.search.ch/audit/CP/tel/de/api</openSearch:Image>
                                 <entry>
                                 <id>urn:uuid:107b409c0e772820</id>
                                 <updated>2020-12-15T17:54:42+01:00</updated>
                                 <published>2020-12-15T17:54:42+01:00</published>
                                 <title type="text">Luware AG</title>
                                 <content type="text">Luware AG
                                 Hardturmstrasse 127
                                 8005 Zürich ZH
                                 *058 404 28 00</content>
                                 <tel:nopromo>*</tel:nopromo>
                                 <author>
                                 <name>tel.search.ch</name>
                                 </author>
                                 <link href="https://tel.search.ch/zuerich/hardturmstrasse-127/luware-ag" title="Details" rel="alternate" type="text/html" />
                                 <link href="https://tel.search.ch/vcard/Luware-AG.vcf?key=107b409c0e772820" type="text/x-vcard" title="VCard Download" rel="alternate" />
                                 <link href="https://tel.search.ch/edit/?id=107b409c0e772820" rel="edit" type="text/html" />
                                 <tel:pos>1</tel:pos>
                                 <tel:id>107b409c0e772820</tel:id>
                                 <tel:type>Organisation</tel:type>
                                 <tel:name>Luware AG</tel:name>
                                 <tel:street>Hardturmstrasse</tel:street>
                                 <tel:streetno>127</tel:streetno>
                                 <tel:zip>8005</tel:zip>
                                 <tel:city>Zürich</tel:city>
                                 <tel:canton>ZH</tel:canton>
                                 <tel:country>ch</tel:country>
                                 <tel:phone>+41584042800</tel:phone>
                                 <tel:copyright>Daten: Swisscom Directories AG</tel:copyright>
                                 </entry>
                                </feed> 
 
 

Check the response data

✅ If no entries are found, then the response data 

1. Create a second "Compose" Element and rename it to “HasRecords”.

2. Store the totalResults value by setting Inputs to this expression

xpath(xml(outputs('Compose')), '/*[name()="feed" and namespace-uri()="http://www.w3.org/2005/Atom"]//*[name()="openSearch:totalResults"][1]/text()')

3. Add a condition and check on the Outputs of “HasRecords”. It should not be 0.

💡 If they are "false", then there are not entries in the response and we can leave the flow.

→ In the next step we retrieve the interesting parts from that message.

Retrieve missing data from the response

✅ The search.ch response will not quite match what we need. To get the missing data from the response (DisplayName) we need to filter out the necessary details using Xpath queries.

1. Set a new variable (e.g. DisplayName)

2. Query the value from the response body with an Xpath expression on the "compose" object from the previous step:

xpath(xml(outputs('Compose')), '/*[name()="feed" and namespace-uri()=http://www.w3.org/2005/Atom]//*[name()="content"][1]/text()')

💡 You can generate your own Xpath expression according to your needs. You can test the expression with a tool like http://xpather.com/ 

Some examples to get data from the reponse XML

Xpath

Matches

Output from example xml

Usage

normalize-space((/*[name()="feed" and namespace-uri()="http://www.w3.org/2005/Atom"]//*[name()="content"])[1]/text())) Content node text without line breaks Luware AG
Hardturmstrasse 127
8005 Zürich ZH
*058 404 28 00

Update Nimbus parameter

Customer.DisplayName

/*[name()="feed" and namespace-uri()="http://www.w3.org/2005/Atom"]//*[name()="tel:type" and namespace-uri()="http://tel.search.ch/api/spec/result/1.0/"][1]

Tel:type node

Value is either Organisation or Person

Organisation

N/A

Use for conditional checks in the workflow

/*[name()="feed" and namespace-uri()="http://www.w3.org/2005/Atom"]//*[name()="tel:name” and namespace-uri()="http://tel.search.ch/api/spec/result/1.0/"][1] Tel:name node Luware AG

Update Nimbus parameter

Customer.DisplayName

/*[name()="feed" and namespace-uri()="http://www.w3.org/2005/Atom"]//*[name()="tel:copyright" and namespace-uri()="http://tel.search.ch/api/spec/result/1.0/"][1] Tel:copyright node Daten: Swisscom Directories AG

N/A

Use for update the source field in your CRM system

/*[name()="feed" and namespace-uri()="http://www.w3.org/2005/Atom"]//*[name()="tel:country" and namespace-uri()="http://tel.search.ch/api/spec/result/1.0/"][1] Tel:country node ch

Update Nimbus parameter

Customer.Country

 
 

When done you can store the output into one - or several variables - and update Nimbus with the retrieved information → See next step.

Update the Nimbus Task

✅ Assuming that your previous data retrieval was successful it's now time to let Nimbus know about it so the caller info is also shown in the UI.

  1. Store the "Xpath" query results in your previously initialized variables.
  2. Add an Nimbus "UpdateTask" action to the end of your flow.
  3. Map the variables (e.g. DisplayName) to the corresponding Nimbus parameters.  
     

Table of Contents