cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
gudstrand Frequent Visitor
Frequent Visitor

OAuth and IBM Watson Campaign Automation Custom Connector

Hey all,

 

I am trying to write a custom connector into the IBM Watson Campaign Automation XMLAPI (see docs here). It has so far proven to be slightly difficult based on the quality of the documentation for the API, but I have successfully gotten a test query in my custom connector to run in Visual Studio. 

 

Despite the strange XML-based return data structures and less-than-kind syntax for actually invoking the API, the biggest challenge I have hit with this is getting authorization to work within Power BI. The preferred method from IBM is OAuth 2.0, which is handy since it is a supported credential in Power BI. However, I am not sure that what IBM has going on is exactly OAuth (see OAuth page here) as Power BI sees it. If you look at the document, you will see that IBMs OAuth is done entirely in a single REST call to their service which then returns a a model like this:

 

Request:

POST /oauth/token HTTP/1.1
Host: apiX.ibmmarketingcloud.com
Content-Type: application/x-www-form-urlencoded
Accept: application/json

grant_type=refresh_token&client_id=<obfuscated>&client_secret=<obfuscated>&refresh_token=<obfuscated>

Response:
{
    "access_token": "obfuscated",
    "token_type": "obfuscated",
    "refresh_token": "obfuscated",
    "expires_in": 12345
}

Right now, I have this authorization crudely working by setting the credential to be "Implicit = []" and then performing the call for a token before each call to the API. This seems to work in the test queries in Visual Studio, but will not work in Power BI. Here is a screenshot of the error I get when attempting to connect anonymously to the connector:

 

2017-07-19_9-57-45.pngIt seems to me that Power BI wants to actually manage the credentials for the service, but armed with only a URL to directly receive a token, I am not sure how to work that into Power BI's understanding of OAuth without an authorize URL which will take users to a login page for IBM (working from this sample). Anyone have any insight? 

 

Also some context: I am very new to OAuth AND to Power BI custom connectors AND to IBMs API - it won't hurt my feelings if someone tells me I'm barking up the completely wrong tree. Thanks everyone!

4 REPLIES 4
gudstrand Frequent Visitor
Frequent Visitor

Re: OAuth and IBM Watson Campaign Automation Custom Connector

I am back to share some positive news that perhaps people can think about and bounce ideas back to me: I've gotten it to work using a workaround. I was reading through the aforelinked GitHub sample and was trying to draw parallels betweent the Github OAuth login flow and the IBM OAuth login flow. The key difference is that IBM just returns the JSON object Power BI needs straight away without any login page/redirect URL stuff. This is exactly where I was getting hung up before because Power BI requires the OAuth Authentication provider to use two methods: StartLogin and FinishLogin. Both have required method signatures for inputs, but also have required signatures for the outputs. One specific attribute of the required record output for StartLogin is "LoginUri" which points an embedded browser to the authorization endpoint/login page of whatever service you are trying to authenticate with. 

 

Since IBM does not have such a thing to point to, my first thought was to write one myself and host it in AWS or something like that, but that would be more involved than I'd like. My next thought was to just put "null" in that field, but that crashes Visual Studio (same goes for empty string: ""). So it needs it, clearly. 

 

Another observation I made is that you are required to use a specific URL as the redirect url when using OAuth: "https://oauth.powerbi.com/views/oauthredirect.html". When you try and navigate to that page, it immediately closes. Not sure what's going on there, but I thought I could use the fact it immediately closes to my advantage. I made this URL both the LoginUri and the CallbackUri:

 

redirect_uri = "https://oauth.powerbi.com/views/oauthredirect.html";
StartLogin = (resourceUrl, state, display) =>
    let
        WindowHeight = 10,
        WindowWidth = 10
    in
        [
            LoginUri = redirect_uri,
            CallbackUri = redirect_uri,
            WindowHeight=WindowHeight,
            WindowWidth=WindowWidth,
            Context=null 
        ];

Once this was set, it was super easy to take the logic I had already written to make the web service call to IBM and get the OAuth token info and simply dump it into the FinishLogin action:

 

FinishLogin = (context, callbackUri, state) => 
    let
        AccessToken = TokenMethod()
    in
        AccessToken;

This has made the whole thing work, and I actually now have data from IBM Watson Campaign Automation flowing into Microsoft Power BI. I am going to write to Microsoft support and see if there is a better way to do this before accepting it as a potential answer, but it is a good workaround for now that will keep me moving on in the project. Full OAuth Harness:

 

redirect_uri = "https://oauth.powerbi.com/views/oauthredirect.html";

TokenMethod = () =>
    let
        grant_type = "refresh_token",
        client_id = client_id,
        token_uri = token_uri,
        client_secret = client_secret,
        refresh_token = refresh_token,
        response = Json.Document(Web.Contents(token_uri, [
            Headers = [#"Content-Type"="application/x-www-form-urlencoded",#"Accept"="application/json"],
            Content = Text.ToBinary(
                "grant_type="&grant_type&
                "&client_id="&client_id&
                "&client_secret="&client_secret&
                "&refresh_token="&refresh_token)
        ]))
    in
        response;

StartLogin = (resourceUrl, state, display) =>
    let
        WindowHeight = 10,
        WindowWidth = 10
    in
        [
            LoginUri = redirect_uri,
            CallbackUri = redirect_uri,
            WindowHeight=WindowHeight,
            WindowWidth=WindowWidth,
            Context=null 
        ];

FinishLogin = (context, callbackUri, state) => 
    let
        AccessToken = TokenMethod()
    in
        AccessToken;

// Data Source Kind description
WatsonCampaignAutomationConnector = [
    Authentication = [
        OAuth = [
            StartLogin=StartLogin,
            FinishLogin=FinishLogin
        ]
    ],
    Label = Extension.LoadString("DataSourceLabel")
];
v-huizhn-msft Super Contributor
Super Contributor

Re: OAuth and IBM Watson Campaign Automation Custom Connector

Hi @gudstrand,

Thanks for your sharing.

gudstrand Frequent Visitor
Frequent Visitor

Re: OAuth and IBM Watson Campaign Automation Custom Connector

No problem. It is very much a workaround at this point so I am wondering if anyone else has encountered something like this before and how they handled it.

suzannek Frequent Visitor
Frequent Visitor

Re: OAuth and IBM Watson Campaign Automation Custom Connector

Would you be a kind-hearted soul to walk through all the steps you took to connect IBM Watson campaign automation to Power BI as if you were speaking to a beginner?

 

I would really love to be able to connect my reports to Power BI - but I would rank myself as beginner with high aspirations to crack this thing.

 

Thank you!