Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -354,3 +354,4 @@ healthchecksdb
*.DS_Store
*.dmg
*.env
/Tests.ClickUp/appsettings.json
15 changes: 13 additions & 2 deletions ClickUp.sln
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.33414.496
# Visual Studio Version 18
VisualStudioVersion = 18.3.11304.161 d18.3
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apps.ClickUp", "ClickUp\Apps.ClickUp.csproj", "{1EA52DCB-451F-4722-9949-635F21C3B086}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.ClickUp", "Tests.ClickUp\Tests.ClickUp.csproj", "{ABE6BE7D-96C0-6036-4532-550F2AA40CE1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E1008505-4655-43D9-970A-D9A118CBB131}"
ProjectSection(SolutionItems) = preProject
README.md = README.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -15,6 +22,10 @@ Global
{1EA52DCB-451F-4722-9949-635F21C3B086}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1EA52DCB-451F-4722-9949-635F21C3B086}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1EA52DCB-451F-4722-9949-635F21C3B086}.Release|Any CPU.Build.0 = Release|Any CPU
{ABE6BE7D-96C0-6036-4532-550F2AA40CE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ABE6BE7D-96C0-6036-4532-550F2AA40CE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ABE6BE7D-96C0-6036-4532-550F2AA40CE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ABE6BE7D-96C0-6036-4532-550F2AA40CE1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
2 changes: 1 addition & 1 deletion ClickUp/Actions/CustomFieldActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public CustomFieldActions(InvocationContext invocationContext) : base(invocation
{
}

[Action("List custom fields", Description = "List all accessible custom fields")]
[Action("Search custom fields", Description = "List all accessible custom fields")]
public Task<ListCustomFieldsResponse> ListCustomFields([ActionParameter] ListRequest list)
{
var endpoint = $"{ApiEndpoints.Lists}/{list.ListId}{ApiEndpoints.CustomFields}";
Expand Down
2 changes: 1 addition & 1 deletion ClickUp/Actions/FolderActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public FolderActions(InvocationContext invocationContext) : base(invocationConte
{
}

[Action("Get folders", Description = "Get all folders given a specific space")]
[Action("Search folders", Description = "Get all folders given a specific space")]
public Task<ListFoldersResponse> GetFolders(
[ActionParameter] SpaceRequest space,
[ActionParameter] ListQuery query)
Expand Down
2 changes: 1 addition & 1 deletion ClickUp/Actions/GoalActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public GoalActions(InvocationContext invocationContext) : base(invocationContext
{
}

[Action("Get goals", Description = "Get all goals")]
[Action("Search goals", Description = "Get all goals")]
public Task<ListGoalsResponse> GetGoals(
[ActionParameter] TeamRequest team,
[ActionParameter] ListGoalsQuery query)
Expand Down
2 changes: 1 addition & 1 deletion ClickUp/Actions/SpaceActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public SpaceActions(InvocationContext invocationContext) : base(invocationContex
{
}

[Action("Get spaces", Description = "Get all spaces given a specific team")]
[Action("Search spaces", Description = "Get all spaces given a specific team")]
public Task<ListSpacesResponse> GetSpaces(
[ActionParameter] TeamRequest team,
[ActionParameter] ListQuery query)
Expand Down
2 changes: 1 addition & 1 deletion ClickUp/Actions/TagActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public TagActions(InvocationContext invocationContext) : base(invocationContext)
{
}

[Action("Get tags", Description = "Get all space tags")]
[Action("Search tags", Description = "Get all space tags")]
public Task<ListTagsResponse> GetTags([ActionParameter] SpaceRequest space)
{
var endpoint = $"{ApiEndpoints.Spaces}/{space.SpaceId}{ApiEndpoints.Tags}";
Expand Down
2 changes: 1 addition & 1 deletion ClickUp/Actions/TaskActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public TaskActions(InvocationContext invocationContext) : base(invocationContext
{
}

[Action("Get tasks", Description = "Get all tasks given a specific list")]
[Action("Search tasks", Description = "Get all tasks given a specific list")]
public Task<ListTasksResponse> GetTasksFromList([ActionParameter] ListRequest list)
{
var endpoint = $"{ApiEndpoints.Lists}/{list.ListId}{ApiEndpoints.Tasks}";
Expand Down
2 changes: 1 addition & 1 deletion ClickUp/Actions/TeamActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public TeamActions(InvocationContext invocationContext) : base(invocationContext
{
}

[Action("Get teams", Description = "Get all teams for this user connection")]
[Action("Search teams", Description = "Get all teams for this user connection")]
public Task<ListTeamsResponse> GetTeams()
{
var request = new ClickUpRequest(ApiEndpoints.Teams, Method.Get, Creds);
Expand Down
2 changes: 1 addition & 1 deletion ClickUp/Actions/UserGroupActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public UserGroupActions(InvocationContext invocationContext) : base(invocationCo
{
}

[Action("Get user groups", Description = "Get all user groups")]
[Action("Search user groups", Description = "Get all user groups")]
public Task<ListGroupsResponse> GetGroups([ActionParameter] ListGroupsQuery query)
{
var endpoint = ApiEndpoints.Groups;
Expand Down
31 changes: 23 additions & 8 deletions ClickUp/Api/ClickUpClient.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Apps.ClickUp.Constants;
using Apps.ClickUp.Models.Response;
using Blackbird.Applications.Sdk.Common.Exceptions;
using Blackbird.Applications.Sdk.Utils.Extensions.String;
using Blackbird.Applications.Sdk.Utils.RestSharp;
using Newtonsoft.Json;
Expand All @@ -15,19 +16,33 @@ public ClickUpClient() : base(new RestClientOptions()
})
{
}

public new async Task<T> ExecuteWithErrorHandling<T>(RestRequest request)

public async Task<T> ExecuteWithErrorHandling<T>(RestRequest request)
{
string content = (await ExecuteWithErrorHandling(request)).Content;
T val = JsonConvert.DeserializeObject<T>(content);
if (val == null)
{
throw new Exception($"Could not parse {content} to {typeof(T)}");
}

return val;
}

public async Task<RestResponse> ExecuteWithErrorHandling(RestRequest request)
{
var response = await ExecuteWithErrorHandling(request);
var json = response.Content!;
RestResponse restResponse = await ExecuteAsync(request);
if (!restResponse.IsSuccessStatusCode)
{
throw ConfigureErrorException(restResponse);
}

return JsonConvert.DeserializeObject<T>(json, JsonConfig.Settings) ??
throw new($"Could not parse {json} to {typeof(T)}");
return restResponse;
}

protected override Exception ConfigureErrorException(RestResponse response)
{
var error = JsonConvert.DeserializeObject<Error>(response.Content);
return new(error.Err);
var error = JsonConvert.DeserializeObject(response.Content);
throw new PluginApplicationException($"{error}");
}
}
2 changes: 1 addition & 1 deletion ClickUp/Apps.ClickUp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<Nullable>enable</Nullable>
<Product>ClickUp</Product>
<Description>Customizable workplace productivity platform</Description>
<Version>1.0.7</Version>
<Version>1.0.8</Version>
<AssemblyName>Apps.ClickUp</AssemblyName>
</PropertyGroup>
<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion ClickUp/Connections/ConnectionDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class ConnectionDefinition : IConnectionDefinition
ConnectionUsage = ConnectionUsage.Actions,
ConnectionProperties = new List<ConnectionProperty>()
{
new(CredsNames.Token) { DisplayName = "Token" }
new(CredsNames.Token) { DisplayName = "Token", Sensitive=true }
}
}
};
Expand Down
51 changes: 45 additions & 6 deletions ClickUp/Webhooks/Handlers/BaseWebhookHandler.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Apps.ClickUp.Api;
using Apps.ClickUp.Constants;
using Apps.ClickUp.Models.Request.Team;
using Apps.ClickUp.Webhooks.Models.Payloads.Additional;
using Apps.ClickUp.Webhooks.Models.Request;
using Blackbird.Applications.Sdk.Common.Authentication;
Expand All @@ -14,12 +13,14 @@ public abstract class BaseWebhookHandler : IWebhookEventHandler
{
protected abstract string EventType { get; }
private string TeamId { get; }

protected WebhookScopeRequest Scope { get; }

private ClickUpClient Client { get; }

public BaseWebhookHandler([WebhookParameter] TeamRequest input)
public BaseWebhookHandler([WebhookParameter] WebhookScopeRequest input)
{
TeamId = input.TeamId;
Scope = input;
Client = new();
}

Expand All @@ -31,6 +32,8 @@ public Task SubscribeAsync(IEnumerable<AuthenticationCredentialsProvider> creds,
Events = new List<string> { EventType }
};

ApplyScope(payload, Scope);

var endpoint = $"{ApiEndpoints.Teams}/{TeamId}{ApiEndpoints.Webhooks}";
var request = new ClickUpRequest(endpoint, Method.Post, creds)
.WithJsonBody(payload, JsonConfig.Settings);
Expand All @@ -43,21 +46,57 @@ public async Task UnsubscribeAsync(IEnumerable<AuthenticationCredentialsProvider
var allWebhooks = await GetAllWebhooks(creds);
var currentHook = allWebhooks.Webhooks
.FirstOrDefault(x => x.Endpoint == values["payloadUrl"]);

if (currentHook == null)
return;

var endpoint = $"{ApiEndpoints.Webhooks}/{currentHook.Id}";
var request = new ClickUpRequest(endpoint, Method.Delete, creds);

await Client.ExecuteWithErrorHandling(request);
}

private Task<WebhooksResponse> GetAllWebhooks(IEnumerable<AuthenticationCredentialsProvider> creds)
{
var endpoint = $"{ApiEndpoints.Teams}/{TeamId}{ApiEndpoints.Webhooks}";
var request = new ClickUpRequest(endpoint, Method.Get, creds);

return Client.ExecuteWithErrorHandling<WebhooksResponse>(request);
}

private static void ApplyScope(AddWebhookRequest payload, WebhookScopeRequest scope)
{
var taskId = Normalize(scope.TaskId);
if (!string.IsNullOrWhiteSpace(taskId))
{
payload.TaskId = taskId;
return;
}

var listId = TryParseLong(scope.ListId);
if (listId.HasValue)
{
payload.ListId = listId.Value;
return;
}

var folderId = TryParseLong(scope.FolderId);
if (folderId.HasValue)
{
payload.FolderId = folderId.Value;
return;
}

var spaceId = TryParseLong(scope.SpaceId);
if (spaceId.HasValue)
{
payload.SpaceId = spaceId.Value;
}
}

private static long? TryParseLong(string? value)
=> long.TryParse(value?.Trim(), out var v) ? v : null;

private static string? Normalize(string? value)
=> string.IsNullOrWhiteSpace(value) ? null : value.Trim();
}
2 changes: 1 addition & 1 deletion ClickUp/Webhooks/Handlers/Folder/FolderCreatedHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class FolderCreatedHandler : BaseWebhookHandler
{
protected override string EventType => "folderCreated";

public FolderCreatedHandler([WebhookParameter] TeamRequest team) : base(team)
public FolderCreatedHandler([WebhookParameter] WebhookScopeRequest team) : base(team)
{
}
}
2 changes: 1 addition & 1 deletion ClickUp/Webhooks/Handlers/Folder/FolderDeletedHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class FolderDeletedHandler : BaseWebhookHandler
{
protected override string EventType => "folderDeleted";

public FolderDeletedHandler([WebhookParameter] TeamRequest team) : base(team)
public FolderDeletedHandler([WebhookParameter] WebhookScopeRequest team) : base(team)
{
}
}
2 changes: 1 addition & 1 deletion ClickUp/Webhooks/Handlers/Folder/FolderUpdatedHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class FolderUpdatedHandler : BaseWebhookHandler
{
protected override string EventType => "folderUpdated";

public FolderUpdatedHandler([WebhookParameter] TeamRequest team) : base(team)
public FolderUpdatedHandler([WebhookParameter] WebhookScopeRequest team) : base(team)
{
}
}
2 changes: 1 addition & 1 deletion ClickUp/Webhooks/Handlers/Goal/GoalCreatedHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class GoalCreatedHandler : BaseWebhookHandler
{
protected override string EventType => "goalCreated";

public GoalCreatedHandler([WebhookParameter] TeamRequest team) : base(team)
public GoalCreatedHandler([WebhookParameter] WebhookScopeRequest team) : base(team)
{
}
}
2 changes: 1 addition & 1 deletion ClickUp/Webhooks/Handlers/Goal/GoalDeletedHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class GoalDeletedHandler : BaseWebhookHandler
{
protected override string EventType => "goalDeleted";

public GoalDeletedHandler([WebhookParameter] TeamRequest team) : base(team)
public GoalDeletedHandler([WebhookParameter] WebhookScopeRequest team) : base(team)
{
}
}
2 changes: 1 addition & 1 deletion ClickUp/Webhooks/Handlers/Goal/GoalUpdatedHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class GoalUpdatedHandler : BaseWebhookHandler
{
protected override string EventType => "goalUpdated";

public GoalUpdatedHandler([WebhookParameter] TeamRequest team) : base(team)
public GoalUpdatedHandler([WebhookParameter] WebhookScopeRequest team) : base(team)
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class KeyResultCreatedHandler : BaseWebhookHandler
{
protected override string EventType => "keyResultCreated";

public KeyResultCreatedHandler([WebhookParameter] TeamRequest team) : base(team)
public KeyResultCreatedHandler([WebhookParameter] WebhookScopeRequest team) : base(team)
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class KeyResultDeletedHandler : BaseWebhookHandler
{
protected override string EventType => "keyResultDeleted";

public KeyResultDeletedHandler([WebhookParameter] TeamRequest team) : base(team)
public KeyResultDeletedHandler([WebhookParameter] WebhookScopeRequest team) : base(team)
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class KeyResultUpdatedHandler : BaseWebhookHandler
{
protected override string EventType => "keyResultUpdated";

public KeyResultUpdatedHandler([WebhookParameter] TeamRequest team) : base(team)
public KeyResultUpdatedHandler([WebhookParameter] WebhookScopeRequest team) : base(team)
{
}
}
2 changes: 1 addition & 1 deletion ClickUp/Webhooks/Handlers/List/ListCreatedHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class ListCreatedHandler : BaseWebhookHandler
{
protected override string EventType => "listCreated";

public ListCreatedHandler([WebhookParameter] TeamRequest team) : base(team)
public ListCreatedHandler([WebhookParameter] WebhookScopeRequest team) : base(team)
{
}
}
2 changes: 1 addition & 1 deletion ClickUp/Webhooks/Handlers/List/ListDeletedHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class ListDeletedHandler : BaseWebhookHandler
{
protected override string EventType => "listDeleted";

public ListDeletedHandler([WebhookParameter] TeamRequest team) : base(team)
public ListDeletedHandler([WebhookParameter] WebhookScopeRequest team) : base(team)
{
}
}
2 changes: 1 addition & 1 deletion ClickUp/Webhooks/Handlers/List/ListUpdatedHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class ListUpdatedHandler : BaseWebhookHandler
{
protected override string EventType => "listUpdated";

public ListUpdatedHandler([WebhookParameter] TeamRequest team) : base(team)
public ListUpdatedHandler([WebhookParameter] WebhookScopeRequest team) : base(team)
{
}
}
Loading