我正在为 Clio 构建自定义 Power Query 连接器。这是我的第一个 PQ 定制连接器,所以我需要知道两件事:
- 如何在令牌处理部分的令牌处理中工作?
- 一旦我开始工作,如何使客户端 ID 和机密成为对单独文件的动态引用?我不喜欢将其硬编码成某种东西的想法。
这是我的代码:
section Clio;
[DataSource.Kind="Clio", Publish="Clio.Publish"]
shared Clio.Contents = (optional message as text) =>
let
_message = if (message <> null) then message else "(no message)",
a = "Hello from Clio: " & _message
in
a;
OAuthBaseUrl = "https://app.clio.com/api/v4";
// Data Source Kind description
Clio = [
Authentication = [
OAuth = [
StartLogin = StartLogin,
FinishLogin = FinishLogin
]
],
Label = Extension.LoadString("DataSourceLabel")
];
// Data Source UI publishing description
Clio.Publish = [
Beta = true,
Category = "Other",
ButtonText = { Extension.LoadString("ButtonTitle"), Extension.LoadString("ButtonHelp") },
LearnMoreUrl = "https://powerbi.microsoft.com/",
SourceImage = Clio.Icons,
SourceTypeImage = Clio.Icons
];
StartLogin = (resourceUrl, state, display) =>
let
AuthorizeUrl = OAuthBaseUrl & "/oauth/authorize?" & Uri.BuildQueryString([
response_type = "code",
client_id = client_id_code,
redirect_uri = "https://app.clio.com/oauth/approval",
state = state
])
in
[
LoginUri = "https://app.clio.com",
CallbackUri = "https://app.clio.com/oauth/approval",
WindowHeight = 1080,
WindowWidth = 720
];
FinishLogin = (context, callbackUri, state) =>
let
Parts = Uri.Parts(callbackUri)[Query]
in
TokenMethod(Parts[code], "authorization_code", context);
//Token Handling
TokenMethod = (grant_type, optional verifier) =>
let
query = [
client_id = client_id_code,
client_secret = client_secret_code,
grant_type = "refresh_token",
refresh_token = I_don't_know_what_to_put_here
],
ManualHandlingStatusCodes= {400,403},
Response = Web.Contents(OAuthBaseUrl & "/token", [
Content = Text.ToBinary(Uri.BuildQueryString(query)),
Headers = [
#"Content-type" = "application/x-www-form-urlencoded",
#"Accept" = "application/json"
],
ManualStatusHandling = ManualHandlingStatusCodes
]),
Parts = Json.Document(Response)
in
// check for error in response
if (Parts[error]? <> null) then
error Error.Record(Parts[error], Parts[message]?)
else
Parts;
Refresh = (resourceUrl, refresh_token) => TokenMethod(refresh_token, "refresh_token");
Clio.Icons = [
Icon16 = { Extension.Contents("Clio16.png"), Extension.Contents("Clio20.png"), Extension.Contents("Clio24.png"), Extension.Contents("Clio32.png") },
Icon32 = { Extension.Contents("Clio32.png"), Extension.Contents("Clio40.png"), Extension.Contents("Clio48.png"), Extension.Contents("Clio64.png") }
];