From d98d9093928227f100d66fdb9e42d5d06c07cf28 Mon Sep 17 00:00:00 2001 From: Ben Lawson Date: Thu, 12 Mar 2020 15:48:20 -0400 Subject: [PATCH 01/54] Add thread_ts parameter to PostMessageAsync to match PostMessage --- SlackAPI/SlackTaskClient.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 8051f6a4..cd14fcae 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -499,7 +499,8 @@ public Task PostMessageAsync( bool? unfurl_links = null, string icon_url = null, string icon_emoji = null, - bool as_user = false) + bool as_user = false, + string thread_ts = null) { List> parameters = new List>(); @@ -540,6 +541,9 @@ public Task PostMessageAsync( if (as_user) parameters.Add(new Tuple("as_user", true.ToString())); + + if (!string.IsNullOrEmpty(thread_ts)) + parameters.Add(new Tuple("thread_ts", thread_ts)); return APIRequestWithTokenAsync(parameters.ToArray()); } From 03f1f8dfea6b2751b2297cde1d4ad8960290aa9c Mon Sep 17 00:00:00 2001 From: Gregoire Pailler Date: Wed, 18 Mar 2020 22:48:24 +0800 Subject: [PATCH 02/54] Added muted_channels to the preferences --- SlackAPI/Preferences.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/SlackAPI/Preferences.cs b/SlackAPI/Preferences.cs index 528f8c1d..f0931eec 100644 --- a/SlackAPI/Preferences.cs +++ b/SlackAPI/Preferences.cs @@ -73,5 +73,6 @@ public class Preferences public string mac_ssb_bounce; public string last_snippet_type; public int display_real_names_override; + public string muted_channels; } } \ No newline at end of file From 344bbee26ed0bf431ba531e070e89f15797c722c Mon Sep 17 00:00:00 2001 From: Gabriel Milani Date: Sun, 22 Mar 2020 12:31:04 -0300 Subject: [PATCH 03/54] Adding users.lookupByEmail request method --- SlackAPI/RPCMessages/UserEmailLookupResponse.cs | 8 ++++++++ SlackAPI/SlackClient.cs | 7 ++++++- SlackAPI/SlackTaskClient.cs | 5 +++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 SlackAPI/RPCMessages/UserEmailLookupResponse.cs diff --git a/SlackAPI/RPCMessages/UserEmailLookupResponse.cs b/SlackAPI/RPCMessages/UserEmailLookupResponse.cs new file mode 100644 index 00000000..487adcda --- /dev/null +++ b/SlackAPI/RPCMessages/UserEmailLookupResponse.cs @@ -0,0 +1,8 @@ +namespace SlackAPI.RPCMessages +{ + [RequestPath("users.lookupByEmail")] + public class UserEmailLookupResponse : Response + { + public User user; + } +} \ No newline at end of file diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index 7340cb71..d0fbcbcc 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -128,7 +128,12 @@ public void GetUserList(Action callback) APIRequestWithToken(callback); } - public void ChannelsCreate(Action callback, string name) { + public void GetUserByEmail(Action callback, string email) + { + APIRequestWithToken(callback, new Tuple("email", email)); + } + + public void ChannelsCreate(Action callback, string name) { APIRequestWithToken(callback, new Tuple("name", name)); } diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 8051f6a4..86441f0b 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -108,6 +108,11 @@ public Task GetUserListAsync() return APIRequestWithTokenAsync(); } + public Task GetUserByEmailAsync(string email) + { + return APIRequestWithTokenAsync(new Tuple("email", email)); + } + public Task ChannelsCreateAsync(string name) { return APIRequestWithTokenAsync(new Tuple("name", name)); } From 67896ec1e9c549a0eb9a65518764e6aac676d2c4 Mon Sep 17 00:00:00 2001 From: taks <857tn859@gmail.com> Date: Sat, 25 Apr 2020 20:40:03 +0900 Subject: [PATCH 04/54] Remove unused type parameters --- SlackAPI/SlackSocketClient.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SlackAPI/SlackSocketClient.cs b/SlackAPI/SlackSocketClient.cs index e067acc0..b71e2f40 100644 --- a/SlackAPI/SlackSocketClient.cs +++ b/SlackAPI/SlackSocketClient.cs @@ -52,17 +52,17 @@ public void ConnectSocket(Action onSocketConnected){ underlyingSocket = new SlackSocket(loginDetails, this, onSocketConnected, this.proxySettings); } - public void ErrorReceiving(Action callback) + public void ErrorReceiving(Action callback) { if (callback != null) underlyingSocket.ErrorReceiving += callback; } - public void ErrorReceivingDesiralization(Action callback) + public void ErrorReceivingDesiralization(Action callback) { if (callback != null) underlyingSocket.ErrorReceivingDesiralization += callback; } - public void ErrorHandlingMessage(Action callback) + public void ErrorHandlingMessage(Action callback) { if (callback != null) underlyingSocket.ErrorHandlingMessage += callback; } From ae93177ca8361755f9ac7f557e66907f56a366c7 Mon Sep 17 00:00:00 2001 From: nadjibnet <39797899+nadjibnet@users.noreply.github.com> Date: Sun, 17 May 2020 08:05:29 +0100 Subject: [PATCH 05/54] Add event for ConnectionLost When the api stay running and there is for some reason a connection failure. The SlackSocketClient is disconnected. What I added is: An event to be notified when the connection is lost. So, After that we can retry to connect again :). --- SlackAPI/SlackSocketClient.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/SlackAPI/SlackSocketClient.cs b/SlackAPI/SlackSocketClient.cs index e067acc0..bba8cf02 100644 --- a/SlackAPI/SlackSocketClient.cs +++ b/SlackAPI/SlackSocketClient.cs @@ -15,6 +15,7 @@ public class SlackSocketClient : SlackClient public event Action OnReactionAdded; public event Action OnPongReceived; public event Action OnPresenceChanged; + public event Action OnConnectionLost; bool HelloReceived; public const int PingInterval = 3000; @@ -50,6 +51,12 @@ protected override void Connected(LoginResponse loginDetails) public void ConnectSocket(Action onSocketConnected){ underlyingSocket = new SlackSocket(loginDetails, this, onSocketConnected, this.proxySettings); + underlyingSocket.ConnectionClosed += UnderlyingSocket_ConnectionClosed; + } + + private void UnderlyingSocket_ConnectionClosed() + { + OnConnectionLost?.Invoke(); } public void ErrorReceiving(Action callback) From a967a89aaa2cf5a8cbe191dcfb0aa4f78b5d8549 Mon Sep 17 00:00:00 2001 From: nadjibnet <39797899+nadjibnet@users.noreply.github.com> Date: Sun, 17 May 2020 08:12:15 +0100 Subject: [PATCH 06/54] Add the attribute needed, provided Some time when we have a connection failure, the error message need some information, ex: missing_scope So we need to know what are the "needed" scope to add them. with provided we can see what are the permission that we already provided to app. --- SlackAPI/Response.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SlackAPI/Response.cs b/SlackAPI/Response.cs index 6c60a0dc..cff403b0 100644 --- a/SlackAPI/Response.cs +++ b/SlackAPI/Response.cs @@ -17,6 +17,8 @@ public abstract class Response /// if ok is false, then this is the reason-code /// public string error; + public string needed; + public string provided; public void AssertOk() { From 61a94bb56dad6c65365bdcb3ce8d27618e258c87 Mon Sep 17 00:00:00 2001 From: "bezik.wredny" Date: Tue, 2 Jun 2020 16:31:07 +0200 Subject: [PATCH 07/54] Add missing URL property in AttachmentAction --- SlackAPI/Attachment.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/SlackAPI/Attachment.cs b/SlackAPI/Attachment.cs index b9e9582f..64b28e1d 100644 --- a/SlackAPI/Attachment.cs +++ b/SlackAPI/Attachment.cs @@ -45,6 +45,7 @@ public AttachmentAction(string name, string text) public string type = "button"; public string value; public ActionConfirm confirm; + public string url; } //see: https://api.slack.com/docs/message-buttons#confirmation_fields From 4009805617bf5c322efd92abadf483fcc9cf15b8 Mon Sep 17 00:00:00 2001 From: Harry Rose Date: Tue, 18 Aug 2020 12:50:26 +0100 Subject: [PATCH 08/54] Make stats_only_admins a nullable bool, we're seeing this cause json deserialization exceptions when calling SlackClient.ConnectAsync() --- SlackAPI/TeamPreferences.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SlackAPI/TeamPreferences.cs b/SlackAPI/TeamPreferences.cs index c7da5453..e157d951 100644 --- a/SlackAPI/TeamPreferences.cs +++ b/SlackAPI/TeamPreferences.cs @@ -17,7 +17,7 @@ public class TeamPreferences public bool hide_referers; public int msg_edit_window_mins; public bool srvices_only_admins; - public bool stats_only_admins; + public bool? stats_only_admins; public enum AuthMode { From c99cb74a020e1c69d3edcfd9e15c5a63aaee1d11 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 24 Aug 2020 11:50:18 -0400 Subject: [PATCH 09/54] Update SlackSocketClient.cs Fixing indentation --- SlackAPI/SlackSocketClient.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SlackAPI/SlackSocketClient.cs b/SlackAPI/SlackSocketClient.cs index bba8cf02..11bd27f8 100644 --- a/SlackAPI/SlackSocketClient.cs +++ b/SlackAPI/SlackSocketClient.cs @@ -15,7 +15,7 @@ public class SlackSocketClient : SlackClient public event Action OnReactionAdded; public event Action OnPongReceived; public event Action OnPresenceChanged; - public event Action OnConnectionLost; + public event Action OnConnectionLost; bool HelloReceived; public const int PingInterval = 3000; @@ -51,10 +51,10 @@ protected override void Connected(LoginResponse loginDetails) public void ConnectSocket(Action onSocketConnected){ underlyingSocket = new SlackSocket(loginDetails, this, onSocketConnected, this.proxySettings); - underlyingSocket.ConnectionClosed += UnderlyingSocket_ConnectionClosed; + underlyingSocket.ConnectionClosed += UnderlyingSocket_ConnectionClosed; } - - private void UnderlyingSocket_ConnectionClosed() + + private void UnderlyingSocket_ConnectionClosed() { OnConnectionLost?.Invoke(); } From 06f268945a3b2892054fc8906c195365ecbfd856 Mon Sep 17 00:00:00 2001 From: Jason Proulx Date: Thu, 10 Sep 2020 11:47:39 -0400 Subject: [PATCH 10/54] Added conversations.list endpoint functionality and cursor request parameter functionality in base response class. --- SlackAPI.sln | 18 +++++++++--------- .../RPCMessages/ConversationsListResponse.cs | 14 ++++++++++++++ SlackAPI/Response.cs | 7 +++++++ SlackAPI/SlackClient.cs | 16 ++++++++++++++++ SlackAPI/SlackTaskClient.cs | 16 ++++++++++++++++ 5 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 SlackAPI/RPCMessages/ConversationsListResponse.cs diff --git a/SlackAPI.sln b/SlackAPI.sln index f3b012b7..f3f74ac0 100644 --- a/SlackAPI.sln +++ b/SlackAPI.sln @@ -1,20 +1,20 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26228.4 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30320.27 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlackAPI", "SlackAPI\SlackAPI.csproj", "{7EED3D9B-9B7A-49A4-AFBF-599153A47DDA}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlackAPI.Tests", "SlackAPI.Tests\SlackAPI.Tests.csproj", "{DEFA9559-0F8F-4C38-9644-67A080EDC46D}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution items", "Solution items", "{532C9828-A2CC-4281-950A-248B06D42E9C}" -ProjectSection(SolutionItems) = preProject - appveyor.yml = appveyor.yml - build.cake = build.cake - Directory.Build.props = Directory.Build.props - GlobalAssemblyInfo.cs = GlobalAssemblyInfo.cs - README.md = README.md -EndProjectSection + ProjectSection(SolutionItems) = preProject + appveyor.yml = appveyor.yml + build.cake = build.cake + Directory.Build.props = Directory.Build.props + GlobalAssemblyInfo.cs = GlobalAssemblyInfo.cs + README.md = README.md + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/SlackAPI/RPCMessages/ConversationsListResponse.cs b/SlackAPI/RPCMessages/ConversationsListResponse.cs new file mode 100644 index 00000000..005938f6 --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsListResponse.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SlackAPI.RPCMessages +{ + [RequestPath("conversations.list")] + public class ConversationsListResponse : Response + { + public Channel[] channels; + } +} diff --git a/SlackAPI/Response.cs b/SlackAPI/Response.cs index cff403b0..339bc0b8 100644 --- a/SlackAPI/Response.cs +++ b/SlackAPI/Response.cs @@ -25,5 +25,12 @@ public void AssertOk() if (!(ok)) throw new InvalidOperationException(string.Format("An error occurred: {0}", this.error)); } + + public ResponseMetaData response_metadata; + } + + public class ResponseMetaData + { + public string next_cursor; } } diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index d0fbcbcc..5d7d865d 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -147,6 +147,22 @@ public void ChannelsInvite(Action callback, string userId APIRequestWithToken(callback, parameters.ToArray()); } + public void GetConversationsList(Action callback, string cursor = "", bool ExcludeArchived = true, int limit = 100, string[] types = null) + { + List> parameters = new List>() + { + Tuple.Create("exclude_archived", ExcludeArchived ? "1" : "0") + }; + if (limit > 0) + Tuple.Create("limit", limit.ToString()); + if (types.Any()) + Tuple.Create("types", string.Join(",", types)); + if (!string.IsNullOrEmpty(cursor)) + parameters.Add(new Tuple("cursor", cursor)); + + APIRequestWithToken(callback, parameters.ToArray()); + } + public void GetChannelList(Action callback, bool ExcludeArchived = true) { APIRequestWithToken(callback, new Tuple("exclude_archived", ExcludeArchived ? "1" : "0")); diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 4b19cab1..d85eb54e 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -127,6 +127,22 @@ public Task ChannelsInviteAsync(string userId, string cha return APIRequestWithTokenAsync(parameters.ToArray()); } + public Task GetConversationsListAsync(string cursor = "", bool ExcludeArchived = true, int limit = 100, string[] types = null) + { + List> parameters = new List>() + { + Tuple.Create("exclude_archived", ExcludeArchived ? "1" : "0") + }; + if (limit > 0) + parameters.Add(Tuple.Create("limit", limit.ToString())); + if (types != null && types.Any()) + parameters.Add(Tuple.Create("types", string.Join(",", types))); + if (!string.IsNullOrEmpty(cursor)) + parameters.Add(new Tuple("cursor", cursor)); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + public Task GetChannelListAsync(bool ExcludeArchived = true) { return APIRequestWithTokenAsync(new Tuple("exclude_archived", ExcludeArchived ? "1" : "0")); From 9c92538540520ee6b8ee729cc8c2b49da43648a5 Mon Sep 17 00:00:00 2001 From: Jason Proulx Date: Fri, 11 Sep 2020 10:31:22 -0400 Subject: [PATCH 11/54] Added the HeaderBlock type --- SlackAPI/Block.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/SlackAPI/Block.cs b/SlackAPI/Block.cs index d2aa0403..893696c5 100644 --- a/SlackAPI/Block.cs +++ b/SlackAPI/Block.cs @@ -46,6 +46,12 @@ public class ContextBlock : IBlock public string block_id { get; set; } public IElement[] elements { get; set; } } + public class HeaderBlock : IBlock + { + public string type { get; } = BlockTypes.Header; + public string text { get; set; } + public string block_id { get; set; } + } public class Text : IElement { public string type { get; set; } = TextTypes.PlainText; @@ -189,6 +195,7 @@ public static class BlockTypes public const string Actions = "actions"; public const string Context = "context"; public const string Image = "image"; + public const string Header = "header"; } public static class TextTypes From fd2473bc9264fa5ce76b2293a381018d60b2ce34 Mon Sep 17 00:00:00 2001 From: Jason Proulx Date: Fri, 11 Sep 2020 10:40:56 -0400 Subject: [PATCH 12/54] Changed text field to Text type --- SlackAPI/Block.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SlackAPI/Block.cs b/SlackAPI/Block.cs index 893696c5..aae02e34 100644 --- a/SlackAPI/Block.cs +++ b/SlackAPI/Block.cs @@ -49,7 +49,7 @@ public class ContextBlock : IBlock public class HeaderBlock : IBlock { public string type { get; } = BlockTypes.Header; - public string text { get; set; } + public Text text { get; set; } public string block_id { get; set; } } public class Text : IElement From ebe39058f754c3c19e1ef4f5e45fab748fc33593 Mon Sep 17 00:00:00 2001 From: Jason Proulx Date: Mon, 14 Sep 2020 10:02:02 -0400 Subject: [PATCH 13/54] Fixed indentation? --- SlackAPI/SlackClient.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index 5d7d865d..ac13416e 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -154,8 +154,8 @@ public void GetConversationsList(Action callback, str Tuple.Create("exclude_archived", ExcludeArchived ? "1" : "0") }; if (limit > 0) - Tuple.Create("limit", limit.ToString()); - if (types.Any()) + Tuple.Create("limit", limit.ToString()); + if (types.Any()) Tuple.Create("types", string.Join(",", types)); if (!string.IsNullOrEmpty(cursor)) parameters.Add(new Tuple("cursor", cursor)); From 7155e34cb651a626b05e1115e89c72a122377d25 Mon Sep 17 00:00:00 2001 From: Jason Proulx Date: Tue, 29 Sep 2020 09:37:18 -0400 Subject: [PATCH 14/54] Fixed missing "parameters.add" code in GetConversationsList() --- SlackAPI/SlackClient.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index ac13416e..eae70331 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -154,11 +154,11 @@ public void GetConversationsList(Action callback, str Tuple.Create("exclude_archived", ExcludeArchived ? "1" : "0") }; if (limit > 0) - Tuple.Create("limit", limit.ToString()); + parameters.Add(Tuple.Create("limit", limit.ToString())); if (types.Any()) - Tuple.Create("types", string.Join(",", types)); + parameters.Add(Tuple.Create("types", string.Join(",", types))); if (!string.IsNullOrEmpty(cursor)) - parameters.Add(new Tuple("cursor", cursor)); + parameters.Add(Tuple.Create("cursor", cursor)); APIRequestWithToken(callback, parameters.ToArray()); } From f322eb5441de06591f7165268a639ec9414669e2 Mon Sep 17 00:00:00 2001 From: Jason Proulx Date: Tue, 29 Sep 2020 10:23:04 -0400 Subject: [PATCH 15/54] Fixed indentation? --- SlackAPI/Block.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SlackAPI/Block.cs b/SlackAPI/Block.cs index aae02e34..a9e8221a 100644 --- a/SlackAPI/Block.cs +++ b/SlackAPI/Block.cs @@ -48,8 +48,8 @@ public class ContextBlock : IBlock } public class HeaderBlock : IBlock { - public string type { get; } = BlockTypes.Header; - public Text text { get; set; } + public string type { get; } = BlockTypes.Header; + public Text text { get; set; } public string block_id { get; set; } } public class Text : IElement From db82e33e219320e9c0dc055650720c0f73dc9d2f Mon Sep 17 00:00:00 2001 From: Jason Proulx Date: Tue, 29 Sep 2020 10:25:14 -0400 Subject: [PATCH 16/54] Fixed indentation, maybe? --- SlackAPI/Block.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SlackAPI/Block.cs b/SlackAPI/Block.cs index a9e8221a..7a53873b 100644 --- a/SlackAPI/Block.cs +++ b/SlackAPI/Block.cs @@ -48,7 +48,7 @@ public class ContextBlock : IBlock } public class HeaderBlock : IBlock { - public string type { get; } = BlockTypes.Header; + public string type { get; } = BlockTypes.Header; public Text text { get; set; } public string block_id { get; set; } } From db77b88d52e895386f83ef725f4cc9c0e2eef938 Mon Sep 17 00:00:00 2001 From: Jason Proulx Date: Tue, 29 Sep 2020 10:40:03 -0400 Subject: [PATCH 17/54] Please work, indentations? --- SlackAPI/Block.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SlackAPI/Block.cs b/SlackAPI/Block.cs index 7a53873b..4fd670fc 100644 --- a/SlackAPI/Block.cs +++ b/SlackAPI/Block.cs @@ -50,7 +50,7 @@ public class HeaderBlock : IBlock { public string type { get; } = BlockTypes.Header; public Text text { get; set; } - public string block_id { get; set; } + public string block_id { get; set; } } public class Text : IElement { From 35008fbe8f6b4d07774c77fc0c7ba85dbfb878aa Mon Sep 17 00:00:00 2001 From: GMIKE Date: Thu, 1 Oct 2020 23:02:58 +0300 Subject: [PATCH 18/54] Fix for lock async methods on framework --- SlackAPI/RequestStateForTask.cs | 8 ++++---- SlackAPI/SlackSocket.cs | 2 +- SlackAPI/SlackTaskClient.cs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/SlackAPI/RequestStateForTask.cs b/SlackAPI/RequestStateForTask.cs index 63075b73..f535f5a4 100644 --- a/SlackAPI/RequestStateForTask.cs +++ b/SlackAPI/RequestStateForTask.cs @@ -40,7 +40,7 @@ private async Task ExecuteResult() HttpWebResponse response = null; try { - response = (HttpWebResponse)await this.request.GetResponseAsync(); + response = (HttpWebResponse)await this.request.GetResponseAsync().ConfigureAwait(false); Success = true; } catch (WebException we) @@ -68,7 +68,7 @@ private async Task ExecutePost() { request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; - using (Stream requestStream = await request.GetRequestStreamAsync()) + using (Stream requestStream = await request.GetRequestStreamAsync().ConfigureAwait(false)) { if (Post.Length > 0) { @@ -80,7 +80,7 @@ private async Task ExecutePost() if (!first) writer.Write('&'); - await writer.WriteAsync(string.Format("{0}={1}", Uri.EscapeDataString(postEntry.Item1), Uri.EscapeDataString(postEntry.Item2))); + await writer.WriteAsync(string.Format("{0}={1}", Uri.EscapeDataString(postEntry.Item1), Uri.EscapeDataString(postEntry.Item2))).ConfigureAwait(false); first = false; } @@ -88,7 +88,7 @@ private async Task ExecutePost() } } - return await this.ExecuteResult(); + return await this.ExecuteResult().ConfigureAwait(false); } } } diff --git a/SlackAPI/SlackSocket.cs b/SlackAPI/SlackSocket.cs index 42b6e9ac..75903825 100644 --- a/SlackAPI/SlackSocket.cs +++ b/SlackAPI/SlackSocket.cs @@ -214,7 +214,7 @@ void SetupReceiving() WebSocketReceiveResult result = null; try { - result = await socket.ReceiveAsync(buffer, cts.Token); + result = await socket.ReceiveAsync(buffer, cts.Token).ConfigureAwait(false); } catch (WebSocketException wex) { diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 4b19cab1..1f38c4d2 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -44,7 +44,7 @@ public SlackTaskClient(string token, IWebProxy proxySettings) public virtual async Task ConnectAsync() { - var loginDetails = await EmitLoginAsync(); + var loginDetails = await EmitLoginAsync().ConfigureAwait(false); if(loginDetails.ok) Connected(loginDetails); @@ -651,7 +651,7 @@ public async Task UploadFileAsync(byte[] fileData, string fi { form.Add(new ByteArrayContent(fileData), "file", fileName); HttpResponseMessage response = PostRequest(string.Format("{0}?{1}", target, string.Join("&", parameters.ToArray())), form); - string result = await response.Content.ReadAsStringAsync(); + string result = await response.Content.ReadAsStringAsync().ConfigureAwait(false); return result.Deserialize(); } } From d5bd9361a5ce4f96b84950651095fd2c771c476b Mon Sep 17 00:00:00 2001 From: avuorine Date: Wed, 14 Oct 2020 09:39:13 +0100 Subject: [PATCH 19/54] scheduled message support --- SlackAPI/SlackClient.cs | 67 +++++++++++++++++++++++++++++++++++++ SlackAPI/SlackTaskClient.cs | 63 ++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index eae70331..4e2a2f33 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -662,6 +662,73 @@ public void PostEphemeralMessage( APIRequestWithToken(callback, parameters.ToArray()); } + + + public void ScheduleMessage( + Action callback, + string channelId, + string text, + DateTimeOffset post_at, + string botName = null, + string parse = null, + bool linkNames = false, + IBlock[] blocks = null, + Attachment[] attachments = null, + bool? unfurl_links = null, + string icon_url = null, + string icon_emoji = null, + bool? as_user = null, + string thread_ts = null) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("text", text)); + parameters.Add(new Tuple("post_at", post_at.ToUnixTimeSeconds().ToString())); + + if (!string.IsNullOrEmpty(botName)) + parameters.Add(new Tuple("username", botName)); + + if (!string.IsNullOrEmpty(parse)) + parameters.Add(new Tuple("parse", parse)); + + if (linkNames) + parameters.Add(new Tuple("link_names", "1")); + + if (blocks != null && blocks.Length > 0) + parameters.Add(new Tuple("blocks", + JsonConvert.SerializeObject(blocks, Formatting.None, + new JsonSerializerSettings // Shouldn't include a not set property + { + NullValueHandling = NullValueHandling.Ignore + }))); + + if (attachments != null && attachments.Length > 0) + parameters.Add(new Tuple("attachments", + JsonConvert.SerializeObject(attachments, Formatting.None, + new JsonSerializerSettings // Shouldn't include a not set property + { + NullValueHandling = NullValueHandling.Ignore + }))); + + if (unfurl_links.HasValue) + parameters.Add(new Tuple("unfurl_links", unfurl_links.Value ? "true" : "false")); + + if (!string.IsNullOrEmpty(icon_url)) + parameters.Add(new Tuple("icon_url", icon_url)); + + if (!string.IsNullOrEmpty(icon_emoji)) + parameters.Add(new Tuple("icon_emoji", icon_emoji)); + + if (as_user.HasValue) + parameters.Add(new Tuple("as_user", as_user.ToString())); + + if (!string.IsNullOrEmpty(thread_ts)) + parameters.Add(new Tuple("thread_ts", thread_ts)); + + APIRequestWithToken(callback, parameters.ToArray()); + } + public void DialogOpen( Action callback, string triggerId, diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index c6815d26..50400d56 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -604,6 +604,69 @@ public Task PostEphemeralMessageAsync( return APIRequestWithTokenAsync(parameters.ToArray()); } + + public Task ScheduleMessageAsync( + string channelId, + string text, + DateTimeOffset post_at, + string botName = null, + string parse = null, + bool linkNames = false, + IBlock[] blocks = null, + Attachment[] attachments = null, + bool? unfurl_links = null, + string icon_url = null, + string icon_emoji = null, + bool as_user = false, + string thread_ts = null) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("text", text)); + parameters.Add(new Tuple("post_at", post_at.ToUnixTimeSeconds().ToString())); + + if (!string.IsNullOrEmpty(botName)) + parameters.Add(new Tuple("username", botName)); + + if (!string.IsNullOrEmpty(parse)) + parameters.Add(new Tuple("parse", parse)); + + if (linkNames) + parameters.Add(new Tuple("link_names", "1")); + + if (blocks != null && blocks.Length > 0) + parameters.Add(new Tuple("blocks", JsonConvert.SerializeObject(blocks, + new JsonSerializerSettings() + { + NullValueHandling = NullValueHandling.Ignore + }))); + + if (attachments != null && attachments.Length > 0) + parameters.Add(new Tuple("attachments", JsonConvert.SerializeObject(attachments, + new JsonSerializerSettings() + { + NullValueHandling = NullValueHandling.Ignore + }))); + + if (unfurl_links.HasValue) + parameters.Add(new Tuple("unfurl_links", unfurl_links.Value ? "true" : "false")); + + if (!string.IsNullOrEmpty(icon_url)) + parameters.Add(new Tuple("icon_url", icon_url)); + + if (!string.IsNullOrEmpty(icon_emoji)) + parameters.Add(new Tuple("icon_emoji", icon_emoji)); + + if (as_user) + parameters.Add(new Tuple("as_user", true.ToString())); + + if (!string.IsNullOrEmpty(thread_ts)) + parameters.Add(new Tuple("thread_ts", thread_ts)); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + public Task AddReactionAsync( string name = null, string channel = null, From 7658616885868afe94543075a7bd1211bed1b4aa Mon Sep 17 00:00:00 2001 From: avuorine Date: Wed, 14 Oct 2020 09:42:25 +0100 Subject: [PATCH 20/54] scheduled message support --- .../RPCMessages/ScheduleMessageResponse.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 SlackAPI/RPCMessages/ScheduleMessageResponse.cs diff --git a/SlackAPI/RPCMessages/ScheduleMessageResponse.cs b/SlackAPI/RPCMessages/ScheduleMessageResponse.cs new file mode 100644 index 00000000..70a4b5c9 --- /dev/null +++ b/SlackAPI/RPCMessages/ScheduleMessageResponse.cs @@ -0,0 +1,21 @@ +namespace SlackAPI +{ + [RequestPath("chat.scheduleMessage")] + public class ScheduleMessageResponse : Response + { + public string ts; + public string channel; + public string scheduled_message_id; + public int post_at; + public Message message; + + public class Message + { + public string text; + public string user; + public string username; + public string type; + public string subtype; + } + } +} From 2d69ad5898d598f980e7a72c556f18d7ddd692a2 Mon Sep 17 00:00:00 2001 From: avuorine Date: Wed, 14 Oct 2020 10:10:07 +0100 Subject: [PATCH 21/54] changed to use pre 4.6 methods for conversion to unix timestamp --- SlackAPI/SlackClient.cs | 4 ++-- SlackAPI/SlackTaskClient.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index 4e2a2f33..f07ee0be 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -668,7 +668,7 @@ public void ScheduleMessage( Action callback, string channelId, string text, - DateTimeOffset post_at, + DateTime post_at, string botName = null, string parse = null, bool linkNames = false, @@ -684,7 +684,7 @@ public void ScheduleMessage( parameters.Add(new Tuple("channel", channelId)); parameters.Add(new Tuple("text", text)); - parameters.Add(new Tuple("post_at", post_at.ToUnixTimeSeconds().ToString())); + parameters.Add(new Tuple("post_at", (post_at - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds.ToString())); if (!string.IsNullOrEmpty(botName)) parameters.Add(new Tuple("username", botName)); diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 50400d56..e87f65fb 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -608,7 +608,7 @@ public Task PostEphemeralMessageAsync( public Task ScheduleMessageAsync( string channelId, string text, - DateTimeOffset post_at, + DateTime post_at, string botName = null, string parse = null, bool linkNames = false, @@ -624,7 +624,7 @@ public Task ScheduleMessageAsync( parameters.Add(new Tuple("channel", channelId)); parameters.Add(new Tuple("text", text)); - parameters.Add(new Tuple("post_at", post_at.ToUnixTimeSeconds().ToString())); + parameters.Add(new Tuple("post_at", (post_at - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds.ToString())); if (!string.IsNullOrEmpty(botName)) parameters.Add(new Tuple("username", botName)); From 16b7968be700662dcff56ac8b5b2108285803c11 Mon Sep 17 00:00:00 2001 From: apresence Date: Sun, 25 Oct 2020 09:50:45 -0400 Subject: [PATCH 22/54] Fix for GetConversationsList() function requiring the parameter "types". According to the Slack API reference, this should be optional: https://api.slack.com/methods/conversations.list --- SlackAPI/SlackClient.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index eae70331..4385949b 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -154,8 +154,8 @@ public void GetConversationsList(Action callback, str Tuple.Create("exclude_archived", ExcludeArchived ? "1" : "0") }; if (limit > 0) - parameters.Add(Tuple.Create("limit", limit.ToString())); - if (types.Any()) + parameters.Add(Tuple.Create("limit", limit.ToString())); + if ((types != null) && types.Any()) parameters.Add(Tuple.Create("types", string.Join(",", types))); if (!string.IsNullOrEmpty(cursor)) parameters.Add(Tuple.Create("cursor", cursor)); From de660ff425241174ec066f9785ddb303ad886008 Mon Sep 17 00:00:00 2001 From: AJ Henderson Date: Tue, 15 Dec 2020 16:20:46 -0500 Subject: [PATCH 23/54] Change im to use Conversations API. DM API is being deprecated. --- SlackAPI/RPCMessages/JoinDirectMessageChannelResponse.cs | 2 +- SlackAPI/SlackClient.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SlackAPI/RPCMessages/JoinDirectMessageChannelResponse.cs b/SlackAPI/RPCMessages/JoinDirectMessageChannelResponse.cs index 2e9d54bb..a7095398 100644 --- a/SlackAPI/RPCMessages/JoinDirectMessageChannelResponse.cs +++ b/SlackAPI/RPCMessages/JoinDirectMessageChannelResponse.cs @@ -1,6 +1,6 @@ namespace SlackAPI { - [RequestPath("im.open")] + [RequestPath("conversations.open")] public class JoinDirectMessageChannelResponse : Response { public Channel channel; diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index eae70331..e3788054 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -551,7 +551,7 @@ public void Update( public void JoinDirectMessageChannel(Action callback, string user) { - var param = new Tuple("user", user); + var param = new Tuple("users", user); APIRequestWithToken(callback, param); } From 670300c821e75b4c998be25d72a6853b37daaed1 Mon Sep 17 00:00:00 2001 From: taks <857tn859@gmail.com> Date: Thu, 25 Feb 2021 17:06:56 +0900 Subject: [PATCH 24/54] Conversations API support --- .../ConversationsArchiveResponse.cs | 13 ++ .../RPCMessages/ConversationsCloseResponse.cs | 15 +++ .../ConversationsCreateResponse.cs | 10 ++ .../ConversationsInviteResponse.cs | 14 +++ .../RPCMessages/ConversationsKickResponse.cs | 13 ++ .../RPCMessages/ConversationsLeaveResponse.cs | 13 ++ .../RPCMessages/ConversationsMarkResponse.cs | 13 ++ .../ConversationsMessageHistory.cs | 9 ++ .../RPCMessages/ConversationsOpenResponse.cs | 15 +++ .../ConversationsRenameResponse.cs | 14 +++ .../ConversationsSetPurposeResponse.cs | 14 +++ .../ConversationsSetTopicResponse.cs | 14 +++ .../ConversationsUnarchiveResponse.cs | 13 ++ SlackAPI/SlackClient.cs | 99 ++++++++++++++++ SlackAPI/SlackTaskClient.cs | 111 +++++++++++++++++- 15 files changed, 378 insertions(+), 2 deletions(-) create mode 100644 SlackAPI/RPCMessages/ConversationsArchiveResponse.cs create mode 100644 SlackAPI/RPCMessages/ConversationsCloseResponse.cs create mode 100644 SlackAPI/RPCMessages/ConversationsCreateResponse.cs create mode 100644 SlackAPI/RPCMessages/ConversationsInviteResponse.cs create mode 100644 SlackAPI/RPCMessages/ConversationsKickResponse.cs create mode 100644 SlackAPI/RPCMessages/ConversationsLeaveResponse.cs create mode 100644 SlackAPI/RPCMessages/ConversationsMarkResponse.cs create mode 100644 SlackAPI/RPCMessages/ConversationsMessageHistory.cs create mode 100644 SlackAPI/RPCMessages/ConversationsOpenResponse.cs create mode 100644 SlackAPI/RPCMessages/ConversationsRenameResponse.cs create mode 100644 SlackAPI/RPCMessages/ConversationsSetPurposeResponse.cs create mode 100644 SlackAPI/RPCMessages/ConversationsSetTopicResponse.cs create mode 100644 SlackAPI/RPCMessages/ConversationsUnarchiveResponse.cs diff --git a/SlackAPI/RPCMessages/ConversationsArchiveResponse.cs b/SlackAPI/RPCMessages/ConversationsArchiveResponse.cs new file mode 100644 index 00000000..d3203251 --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsArchiveResponse.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SlackAPI +{ + [RequestPath("conversations.archive")] + public class ConversationsArchiveResponse : Response + { + } +} diff --git a/SlackAPI/RPCMessages/ConversationsCloseResponse.cs b/SlackAPI/RPCMessages/ConversationsCloseResponse.cs new file mode 100644 index 00000000..d8a7fca8 --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsCloseResponse.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SlackAPI +{ + [RequestPath("conversations.close")] + public class ConversationsCloseResponse : Response + { + public string no_op; + public string already_closed; + } +} diff --git a/SlackAPI/RPCMessages/ConversationsCreateResponse.cs b/SlackAPI/RPCMessages/ConversationsCreateResponse.cs new file mode 100644 index 00000000..ec71d2e3 --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsCreateResponse.cs @@ -0,0 +1,10 @@ +using System; + +namespace SlackAPI +{ + [RequestPath("conversations.create")] + public class ConversationsCreateResponse : Response + { + public Channel channel; + } +} diff --git a/SlackAPI/RPCMessages/ConversationsInviteResponse.cs b/SlackAPI/RPCMessages/ConversationsInviteResponse.cs new file mode 100644 index 00000000..95f04de4 --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsInviteResponse.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SlackAPI +{ + [RequestPath("conversations.invite")] + public class ConversationsInviteResponse : Response + { + public Channel channel; + } +} diff --git a/SlackAPI/RPCMessages/ConversationsKickResponse.cs b/SlackAPI/RPCMessages/ConversationsKickResponse.cs new file mode 100644 index 00000000..daa081e3 --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsKickResponse.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SlackAPI +{ + [RequestPath("conversations.kick")] + public class ConversationsKickResponse : Response + { + } +} diff --git a/SlackAPI/RPCMessages/ConversationsLeaveResponse.cs b/SlackAPI/RPCMessages/ConversationsLeaveResponse.cs new file mode 100644 index 00000000..0f66be8f --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsLeaveResponse.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SlackAPI +{ + [RequestPath("conversations.leave")] + public class ConversationsLeaveResponse : Response + { + } +} diff --git a/SlackAPI/RPCMessages/ConversationsMarkResponse.cs b/SlackAPI/RPCMessages/ConversationsMarkResponse.cs new file mode 100644 index 00000000..fe7d6665 --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsMarkResponse.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SlackAPI +{ + [RequestPath("conversations.mark")] + public class ConversationsMarkResponse : Response + { + } +} diff --git a/SlackAPI/RPCMessages/ConversationsMessageHistory.cs b/SlackAPI/RPCMessages/ConversationsMessageHistory.cs new file mode 100644 index 00000000..ffff5abc --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsMessageHistory.cs @@ -0,0 +1,9 @@ +using System; + +namespace SlackAPI.RPCMessages +{ + [RequestPath("conversations.history")] + public class ConversationsMessageHistory : MessageHistory + { + } +} diff --git a/SlackAPI/RPCMessages/ConversationsOpenResponse.cs b/SlackAPI/RPCMessages/ConversationsOpenResponse.cs new file mode 100644 index 00000000..b17370be --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsOpenResponse.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SlackAPI +{ + [RequestPath("conversations.open")] + public class ConversationsOpenResponse : Response + { + public string no_op; + public string already_open; + } +} diff --git a/SlackAPI/RPCMessages/ConversationsRenameResponse.cs b/SlackAPI/RPCMessages/ConversationsRenameResponse.cs new file mode 100644 index 00000000..e633eddd --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsRenameResponse.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SlackAPI +{ + [RequestPath("conversations.rename")] + public class ConversationsRenameResponse : Response + { + public Channel channel; + } +} diff --git a/SlackAPI/RPCMessages/ConversationsSetPurposeResponse.cs b/SlackAPI/RPCMessages/ConversationsSetPurposeResponse.cs new file mode 100644 index 00000000..20d4fafe --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsSetPurposeResponse.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SlackAPI +{ + [RequestPath("conversations.setPurpose")] + public class ConversationsSetPurposeResponse : Response + { + public string purpose; + } +} diff --git a/SlackAPI/RPCMessages/ConversationsSetTopicResponse.cs b/SlackAPI/RPCMessages/ConversationsSetTopicResponse.cs new file mode 100644 index 00000000..61ead8db --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsSetTopicResponse.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SlackAPI +{ + [RequestPath("conversations.setTopic")] + public class ConversationsSetTopicResponse : Response + { + public string topic; + } +} diff --git a/SlackAPI/RPCMessages/ConversationsUnarchiveResponse.cs b/SlackAPI/RPCMessages/ConversationsUnarchiveResponse.cs new file mode 100644 index 00000000..1d894e01 --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsUnarchiveResponse.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SlackAPI +{ + [RequestPath("conversations.unarchive")] + public class ConversationsUnarchiveResponse : Response + { + } +} diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index 8857b9ef..ab14e5e3 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -258,6 +258,11 @@ public void GetGroupHistory(Action callback, Channel groupI GetHistory(callback, groupInfo.id, latest, oldest, count, unreads); } + public void GetConversationsHistory(Action callback, Channel groupInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) + { + GetHistory(callback, groupInfo.id, latest, oldest, count, unreads); + } + public void MarkChannel(Action callback, string channelId, DateTime ts) { APIRequestWithToken(callback, @@ -373,6 +378,100 @@ public void GroupsUnarchive(Action callback, string chan #endregion + #region Conversations + public void ConversationsArchive(Action callback, string channelId) + { + APIRequestWithToken(callback, new Tuple("channel", channelId)); + } + + public void ConversationsClose(Action callback, string channelId) + { + APIRequestWithToken(callback, new Tuple("channel", channelId)); + } + + public void ConversationsCreate(Action callback, string name) + { + APIRequestWithToken(callback, new Tuple("name", name)); + } + + public void ConversationsInvite(Action callback, string channelId, string[] userIds) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("users", string.Join(",", userIds))); + + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void ConversationsKick(Action callback, string channelId, string userId) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("user", userId)); + + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void ConversationsLeave(Action callback, string channelId) + { + APIRequestWithToken(callback, new Tuple("channel", channelId)); + } + + public void ConversationsMark(Action callback, string channelId, DateTime ts) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("ts", ts.ToProperTimeStamp())); + + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void ConversationsOpen(Action callback, string channelId) + { + APIRequestWithToken(callback, new Tuple("channel", channelId)); + } + + public void ConversationsRename(Action callback, string channelId, string name) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("name", name)); + + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void ConversationsSetPurpose(Action callback, string channelId, string purpose) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("purpose", purpose)); + + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void ConversationsSetTopic(Action callback, string channelId, string topic) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("topic", topic)); + + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void ConversationsUnarchive(Action callback, string channelId) + { + APIRequestWithToken(callback, new Tuple("channel", channelId)); + } + + #endregion + + public void SearchAll(Action callback, string query, string sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) { List> parameters = new List>(); diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index e87f65fb..53b6d401 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -235,6 +235,11 @@ public Task GetGroupHistoryAsync(Channel groupInfo, DateTim return GetHistoryAsync(groupInfo.id, latest, oldest, count, unreads); } + public Task GetConversationsHistoryAsync(Channel groupInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) + { + return GetHistoryAsync(groupInfo.id, latest, oldest, count, unreads); + } + public Task MarkChannelAsync(string channelId, DateTime ts) { return APIRequestWithTokenAsync(new Tuple("channel", channelId), @@ -349,6 +354,108 @@ public Task GroupsUnarchiveAsync(string channelId) #endregion + #region Conversations + public Task ConversationsArchiveAsync(string channelId) + { + return APIRequestWithTokenAsync(new Tuple("channel", channelId)); + } + + public Task ConversationsCloseAsync(string channelId) + { + return APIRequestWithTokenAsync(new Tuple("channel", channelId)); + } + + public Task ConversationsCreateAsync(string name, bool? isPrivate = null, string teamId = null) + { + List> parameters = new List>(); + parameters.Add(new Tuple("name", name)); + + if (isPrivate.HasValue) + parameters.Add(new Tuple("is_private", isPrivate.Value ? "true" : "false")); + + if (!string.IsNullOrEmpty(teamId)) + parameters.Add(new Tuple("team_id", teamId)); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task ConversationsInviteAsync(string channelId, string[] userIds) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("users", string.Join(",", userIds))); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task ConversationsKickAsync(string channelId, string userId) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("user", userId)); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task ConversationsLeaveAsync(string channelId) + { + return APIRequestWithTokenAsync(new Tuple("channel", channelId)); + } + + public Task ConversationsMarkAsync(string channelId, DateTime ts) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("ts", ts.ToProperTimeStamp())); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task ConversationsOpenAsync(string channelId) + { + return APIRequestWithTokenAsync(new Tuple("channel", channelId)); + } + + public Task ConversationsRenameAsync(string channelId, string name) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("name", name)); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task ConversationsSetPurposeAsync(string channelId, string purpose) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("purpose", purpose)); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task ConversationsSetTopicAsync(string channelId, string topic) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("topic", topic)); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task ConversationsUnarchiveAsync(string channelId) + { + return APIRequestWithTokenAsync(new Tuple("channel", channelId)); + } + + #endregion + public Task SearchAllAsync(string query, string sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) { List> parameters = new List>(); @@ -492,7 +599,7 @@ public Task UpdateAsync(string ts, parameters.Add(new Tuple("attachments", JsonConvert.SerializeObject(attachments))); parameters.Add(new Tuple("as_user", as_user.ToString())); - + if (blocks != null && blocks.Length > 0) parameters.Add(new Tuple("blocks", JsonConvert.SerializeObject(blocks, new JsonSerializerSettings() @@ -562,7 +669,7 @@ public Task PostMessageAsync( if (as_user) parameters.Add(new Tuple("as_user", true.ToString())); - + if (!string.IsNullOrEmpty(thread_ts)) parameters.Add(new Tuple("thread_ts", thread_ts)); From 527f70ba4655c598e655a4a934bb6ff6335a154c Mon Sep 17 00:00:00 2001 From: taks <857tn859@gmail.com> Date: Fri, 26 Feb 2021 08:41:09 +0900 Subject: [PATCH 25/54] fix argument name --- SlackAPI/SlackClient.cs | 4 ++-- SlackAPI/SlackTaskClient.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index ab14e5e3..2d7f2604 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -258,9 +258,9 @@ public void GetGroupHistory(Action callback, Channel groupI GetHistory(callback, groupInfo.id, latest, oldest, count, unreads); } - public void GetConversationsHistory(Action callback, Channel groupInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) + public void GetConversationsHistory(Action callback, Channel conversationInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) { - GetHistory(callback, groupInfo.id, latest, oldest, count, unreads); + GetHistory(callback, conversationInfo.id, latest, oldest, count, unreads); } public void MarkChannel(Action callback, string channelId, DateTime ts) diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 53b6d401..cea7fe0e 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -235,9 +235,9 @@ public Task GetGroupHistoryAsync(Channel groupInfo, DateTim return GetHistoryAsync(groupInfo.id, latest, oldest, count, unreads); } - public Task GetConversationsHistoryAsync(Channel groupInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) + public Task GetConversationsHistoryAsync(Channel conversationInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) { - return GetHistoryAsync(groupInfo.id, latest, oldest, count, unreads); + return GetHistoryAsync(conversationInfo.id, latest, oldest, count, unreads); } public Task MarkChannelAsync(string channelId, DateTime ts) From a26075b5f9171b918f54bff7be5c11b34a2a3383 Mon Sep 17 00:00:00 2001 From: spanhotra <79205065+spanhotra@users.noreply.github.com> Date: Fri, 26 Feb 2021 13:07:46 +0530 Subject: [PATCH 26/54] Update Channel.cs With the new API structure in place and updated Conversation List API https://api.slack.com/methods/conversations.list Adding IM related properties. --- SlackAPI/Channel.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SlackAPI/Channel.cs b/SlackAPI/Channel.cs index 7335e8bd..5d058198 100644 --- a/SlackAPI/Channel.cs +++ b/SlackAPI/Channel.cs @@ -24,5 +24,9 @@ public class Channel : Conversation public OwnedStampedMessage purpose; public string[] members; + + //im related properties + public bool is_im; + public string user; } } From 899dcf961e706b7bd0a18a40f47cfa35a618b3f3 Mon Sep 17 00:00:00 2001 From: Fannur Date: Mon, 1 Mar 2021 18:05:29 +0300 Subject: [PATCH 27/54] fixed auth with token --- SlackAPI/SlackClient.cs | 9 +-------- SlackAPI/SlackClientBase.cs | 26 ++++++++++++++++++++++---- SlackAPI/SlackTaskClient.cs | 6 +----- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index 8857b9ef..63ec2445 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -108,14 +108,7 @@ protected virtual void Connected(LoginResponse loginDetails) public void APIRequestWithToken(Action callback, params Tuple[] getParameters) where K : Response { - Tuple[] tokenArray = new Tuple[]{ - new Tuple("token", APIToken) - }; - - if (getParameters != null && getParameters.Length > 0) - tokenArray = tokenArray.Concat(getParameters).ToArray(); - - APIRequest(callback, tokenArray, new Tuple[0]); + APIRequest(callback, getParameters, new Tuple[0], APIToken); } public void TestAuth(Action callback) diff --git a/SlackAPI/SlackClientBase.cs b/SlackAPI/SlackClientBase.cs index 5b2f08f4..8581f9df 100644 --- a/SlackAPI/SlackClientBase.cs +++ b/SlackAPI/SlackClientBase.cs @@ -33,7 +33,11 @@ protected SlackClientBase(IWebProxy proxySettings) protected Uri GetSlackUri(string path, Tuple[] getParameters) { - string parameters = getParameters + string parameters = default; + + if (getParameters != null && getParameters.Length > 0) + { + parameters = getParameters .Where(x => x.Item2 != null) .Select(new Func, string>(a => { @@ -54,11 +58,19 @@ protected Uri GetSlackUri(string path, Tuple[] getParameters) return string.Format("{0}&{1}", a, b); }); - Uri requestUri = new Uri(string.Format("{0}?{1}", path, parameters)); + } + + Uri requestUri = default; + + if (!string.IsNullOrEmpty(parameters)) + requestUri = new Uri(string.Format("{0}?{1}", path, parameters)); + else + requestUri = new Uri(path); + return requestUri; } - protected void APIRequest(Action callback, Tuple[] getParameters, Tuple[] postParameters) + protected void APIRequest(Action callback, Tuple[] getParameters, Tuple[] postParameters, string token = "") where K : Response { RequestPath path = RequestPath.GetRequestPath(); @@ -68,12 +80,15 @@ protected void APIRequest(Action callback, Tuple[] getPara Uri requestUri = GetSlackUri(Path.Combine(APIBaseLocation, path.Path), getParameters); HttpWebRequest request = CreateWebRequest(requestUri); + if (!string.IsNullOrEmpty(token)) + request.Headers.Add("Authorization", "Bearer " + token); + //This will handle all of the processing. RequestState state = new RequestState(request, postParameters, callback); state.Begin(); } - public Task APIRequestAsync(Tuple[] getParameters, Tuple[] postParameters) + public Task APIRequestAsync(Tuple[] getParameters, Tuple[] postParameters, string token = "") where K : Response { RequestPath path = RequestPath.GetRequestPath(); @@ -83,6 +98,9 @@ public Task APIRequestAsync(Tuple[] getParameters, Tuple(request, postParameters); return state.Execute(); diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index e87f65fb..fcb87a4f 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -91,11 +91,7 @@ public Task APIRequestWithTokenAsync() public Task APIRequestWithTokenAsync(params Tuple[] postParameters) where K : Response { - Tuple[] tokenArray = new Tuple[]{ - new Tuple("token", APIToken) - }; - - return APIRequestAsync(tokenArray, postParameters); + return APIRequestAsync(new Tuple[] { }, postParameters, APIToken); } public Task TestAuthAsync() From b4434483f9e36907eaf2d8b3f4b5a6c5fcf2e056 Mon Sep 17 00:00:00 2001 From: Fannur Date: Mon, 1 Mar 2021 19:28:27 +0300 Subject: [PATCH 28/54] added conversation list test --- SlackAPI.Tests/Conversations.cs | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 SlackAPI.Tests/Conversations.cs diff --git a/SlackAPI.Tests/Conversations.cs b/SlackAPI.Tests/Conversations.cs new file mode 100644 index 00000000..3c8b74dc --- /dev/null +++ b/SlackAPI.Tests/Conversations.cs @@ -0,0 +1,41 @@ +using System.Linq; +using SlackAPI.RPCMessages; +using SlackAPI.Tests.Configuration; +using SlackAPI.Tests.Helpers; +using Xunit; + +namespace SlackAPI.Tests +{ + [Collection("Integration tests")] + public class Conversations + { + private readonly IntegrationFixture fixture; + + public Conversations(IntegrationFixture fixture) + { + this.fixture = fixture; + } + [Fact] + public void ConversationList() + { + var client = this.fixture.UserClient; + ConversationsListResponse actual = null; + using (var sync = new InSync(nameof(SlackClient.ChannelLookup))) + { + client.GetConversationsList(response => + { + actual = response; + sync.Proceed(); + }); + } + + Assert.True(actual.ok, "Error while fetching conversation list."); + Assert.True(actual.channels.Any()); + + // check to null + var someChannel = actual.channels.First(); + Assert.NotNull(someChannel.id); + Assert.NotNull(someChannel.name); + } + } +} \ No newline at end of file From ffb101ab0e85bb3ec2fa94773a75e34fdcbd1a59 Mon Sep 17 00:00:00 2001 From: Fannur Date: Mon, 1 Mar 2021 19:49:55 +0300 Subject: [PATCH 29/54] added is_im property --- SlackAPI/Channel.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/SlackAPI/Channel.cs b/SlackAPI/Channel.cs index 7335e8bd..add01e3d 100644 --- a/SlackAPI/Channel.cs +++ b/SlackAPI/Channel.cs @@ -16,6 +16,7 @@ public class Channel : Conversation public bool is_general; public bool is_channel; public bool is_group; + public bool is_im; //Is this deprecated by is_open? public bool IsPrivateGroup { get { return id != null && id[0] == 'G'; } } From bbff3354a74b809e71f497ba4bfb5d6cd17c0404 Mon Sep 17 00:00:00 2001 From: Fannur Date: Mon, 1 Mar 2021 21:51:18 +0300 Subject: [PATCH 30/54] added user property to channel --- SlackAPI/Channel.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/SlackAPI/Channel.cs b/SlackAPI/Channel.cs index add01e3d..c45d1c23 100644 --- a/SlackAPI/Channel.cs +++ b/SlackAPI/Channel.cs @@ -10,6 +10,7 @@ public class Channel : Conversation { public string name; public string creator; + public string user; public bool is_archived; public bool is_member; From 9ba99aebeaa66af353dbe93d92f8cfa087eeb4a6 Mon Sep 17 00:00:00 2001 From: Fannur Date: Mon, 1 Mar 2021 21:51:44 +0300 Subject: [PATCH 31/54] fixed upload file method --- SlackAPI/SlackClient.cs | 3 +-- SlackAPI/SlackClientBase.cs | 14 ++++++++++++-- SlackAPI/SlackTaskClient.cs | 3 +-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index 63ec2445..fe47bea2 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -766,7 +766,6 @@ public void UploadFile(Action callback, byte[] fileData, str Uri target = new Uri(Path.Combine(APIBaseLocation, useAsync ? "files.uploadAsync" : "files.upload")); List parameters = new List(); - parameters.Add(string.Format("token={0}", APIToken)); //File/Content if (!string.IsNullOrEmpty(fileType)) @@ -786,7 +785,7 @@ public void UploadFile(Action callback, byte[] fileData, str using (MultipartFormDataContent form = new MultipartFormDataContent()) { form.Add(new ByteArrayContent(fileData), "file", fileName); - HttpResponseMessage response = PostRequest(string.Format("{0}?{1}", target, string.Join("&", parameters.ToArray())), form); + HttpResponseMessage response = PostRequestAsync(string.Format("{0}?{1}", target, string.Join("&", parameters.ToArray())), form, APIToken).Result; string result = response.Content.ReadAsStringAsync().Result; callback(result.Deserialize()); } diff --git a/SlackAPI/SlackClientBase.cs b/SlackAPI/SlackClientBase.cs index 8581f9df..1e6d357b 100644 --- a/SlackAPI/SlackClientBase.cs +++ b/SlackAPI/SlackClientBase.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Net; using System.Net.Http; +using System.Net.Http.Headers; using System.Threading.Tasks; using Newtonsoft.Json; @@ -129,9 +130,18 @@ protected HttpWebRequest CreateWebRequest(Uri requestUri) return httpWebRequest; } - protected HttpResponseMessage PostRequest(string requestUri, MultipartFormDataContent form) + protected Task PostRequestAsync(string requestUri, MultipartFormDataContent form, string token) { - return httpClient.PostAsync(requestUri, form).Result; + var requestMessage = new HttpRequestMessage + { + Method = HttpMethod.Post, + Content = form, + RequestUri = new Uri(requestUri), + }; + + requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); + + return httpClient.SendAsync(requestMessage); } public void RegisterConverter(JsonConverter converter) diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index fcb87a4f..5f23204d 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -705,7 +705,6 @@ public async Task UploadFileAsync(byte[] fileData, string fi Uri target = new Uri(Path.Combine(APIBaseLocation, useAsync ? "files.uploadAsync" : "files.upload")); List parameters = new List(); - parameters.Add(string.Format("token={0}", APIToken)); //File/Content if (!string.IsNullOrEmpty(fileType)) @@ -725,7 +724,7 @@ public async Task UploadFileAsync(byte[] fileData, string fi using (MultipartFormDataContent form = new MultipartFormDataContent()) { form.Add(new ByteArrayContent(fileData), "file", fileName); - HttpResponseMessage response = PostRequest(string.Format("{0}?{1}", target, string.Join("&", parameters.ToArray())), form); + HttpResponseMessage response = await PostRequestAsync(string.Format("{0}?{1}", target, string.Join("&", parameters.ToArray())), form, APIToken); string result = await response.Content.ReadAsStringAsync().ConfigureAwait(false); return result.Deserialize(); } From 092bbf6a3e13626f69f0e12dfc68c4b85092c055 Mon Sep 17 00:00:00 2001 From: Fannur Date: Tue, 2 Mar 2021 18:15:39 +0300 Subject: [PATCH 32/54] fixed UserUIInteraction test --- SlackAPI.Tests/UserUIInteraction.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SlackAPI.Tests/UserUIInteraction.cs b/SlackAPI.Tests/UserUIInteraction.cs index 60b7faf8..9323fd97 100644 --- a/SlackAPI.Tests/UserUIInteraction.cs +++ b/SlackAPI.Tests/UserUIInteraction.cs @@ -52,7 +52,7 @@ public void TestGetAccessToken() var accessTokenResponse = GetAccessToken(slackClientHelpers, clientId, clientSecret, redirectUrl, code); Assert.True(accessTokenResponse.ok); - Assert.Equal("identify", accessTokenResponse.scope); + Assert.Equal(accessTokenResponse.access_token, this.fixture.Config.UserAuthToken); } } From 00b0d8de273309d7da87282320605aa201be3217 Mon Sep 17 00:00:00 2001 From: Fannur Date: Tue, 9 Mar 2021 15:15:18 +0300 Subject: [PATCH 33/54] fix channel members --- SlackAPI/Channel.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/SlackAPI/Channel.cs b/SlackAPI/Channel.cs index 8b3cb381..c45d1c23 100644 --- a/SlackAPI/Channel.cs +++ b/SlackAPI/Channel.cs @@ -26,9 +26,5 @@ public class Channel : Conversation public OwnedStampedMessage purpose; public string[] members; - - //im related properties - public bool is_im; - public string user; } } From bebd5009443f51fa7657d61776e3b5e425b93bca Mon Sep 17 00:00:00 2001 From: Fannur Date: Tue, 9 Mar 2021 15:21:57 +0300 Subject: [PATCH 34/54] fix UserUIIntercation test --- SlackAPI.Tests/UserUIInteraction.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SlackAPI.Tests/UserUIInteraction.cs b/SlackAPI.Tests/UserUIInteraction.cs index 9323fd97..0ece63cf 100644 --- a/SlackAPI.Tests/UserUIInteraction.cs +++ b/SlackAPI.Tests/UserUIInteraction.cs @@ -52,7 +52,7 @@ public void TestGetAccessToken() var accessTokenResponse = GetAccessToken(slackClientHelpers, clientId, clientSecret, redirectUrl, code); Assert.True(accessTokenResponse.ok); - Assert.Equal(accessTokenResponse.access_token, this.fixture.Config.UserAuthToken); + Assert.Contains("identify", accessTokenResponse.scope); } } From efc0ff6825cf1c92a530a7827239ef176f7a2d11 Mon Sep 17 00:00:00 2001 From: Matt Richardson Date: Mon, 16 Aug 2021 14:48:52 +1000 Subject: [PATCH 35/54] Add support for multi-person DMs Fixes #279 --- SlackAPI/RPCMessages/ConversationsOpenResponse.cs | 1 + SlackAPI/SlackTaskClient.cs | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/SlackAPI/RPCMessages/ConversationsOpenResponse.cs b/SlackAPI/RPCMessages/ConversationsOpenResponse.cs index b17370be..a455eb16 100644 --- a/SlackAPI/RPCMessages/ConversationsOpenResponse.cs +++ b/SlackAPI/RPCMessages/ConversationsOpenResponse.cs @@ -11,5 +11,6 @@ public class ConversationsOpenResponse : Response { public string no_op; public string already_open; + public Channel channel; } } diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 11962dfb..6152e5b3 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -415,6 +415,11 @@ public Task ConversationsOpenAsync(string channelId) return APIRequestWithTokenAsync(new Tuple("channel", channelId)); } + public Task ConversationsOpenAsync(string[] userIds) + { + return APIRequestWithTokenAsync(new Tuple("users", string.Join(",", userIds))); + } + public Task ConversationsRenameAsync(string channelId, string name) { List> parameters = new List>(); @@ -844,4 +849,4 @@ public Task ChannelSetTopicAsync(string channelId, stri new Tuple("topic", newTopic)); } } -} \ No newline at end of file +} From fbc3cb02774037dc281e143230218191aad2f180 Mon Sep 17 00:00:00 2001 From: Matt Richardson Date: Mon, 16 Aug 2021 16:53:15 +1000 Subject: [PATCH 36/54] Add field for error responses --- SlackAPI/RPCMessages/ConversationsOpenResponse.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SlackAPI/RPCMessages/ConversationsOpenResponse.cs b/SlackAPI/RPCMessages/ConversationsOpenResponse.cs index a455eb16..9603c663 100644 --- a/SlackAPI/RPCMessages/ConversationsOpenResponse.cs +++ b/SlackAPI/RPCMessages/ConversationsOpenResponse.cs @@ -12,5 +12,6 @@ public class ConversationsOpenResponse : Response public string no_op; public string already_open; public Channel channel; - } + public string error; + } From c1322ed2c6cad9d310257e03149d905e7b7bc81a Mon Sep 17 00:00:00 2001 From: Matt Richardson Date: Thu, 26 Aug 2021 05:54:32 +1000 Subject: [PATCH 37/54] Re-add missing closing brace --- SlackAPI/RPCMessages/ConversationsOpenResponse.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SlackAPI/RPCMessages/ConversationsOpenResponse.cs b/SlackAPI/RPCMessages/ConversationsOpenResponse.cs index 9603c663..527f8f16 100644 --- a/SlackAPI/RPCMessages/ConversationsOpenResponse.cs +++ b/SlackAPI/RPCMessages/ConversationsOpenResponse.cs @@ -13,5 +13,5 @@ public class ConversationsOpenResponse : Response public string already_open; public Channel channel; public string error; - + } } From 17dde30d6c8b310e821fdb04f1ff0daa702946db Mon Sep 17 00:00:00 2001 From: taks <857tn859@gmail.com> Date: Wed, 17 Nov 2021 15:40:40 +0900 Subject: [PATCH 38/54] Added attachments field to Message class --- SlackAPI/Message.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/SlackAPI/Message.cs b/SlackAPI/Message.cs index dfb25656..6077ec6c 100644 --- a/SlackAPI/Message.cs +++ b/SlackAPI/Message.cs @@ -16,6 +16,7 @@ public class Message : SlackSocketMessage /// public string username; public string text; + public Attachment[] attachments; public bool is_starred; public string permalink; public Reaction[] reactions; From 293941fafc60599fd047d6c70492059cd802c8ec Mon Sep 17 00:00:00 2001 From: bilgin Date: Tue, 30 Nov 2021 16:51:15 +0300 Subject: [PATCH 39/54] views.publish basics --- SlackAPI/Block.cs | 12 +++++++ SlackAPI/RPCMessages/PublishViewResponse.cs | 38 +++++++++++++++++++++ SlackAPI/SlackClient.cs | 17 +++++++++ SlackAPI/SlackTaskClient.cs | 16 +++++++++ 4 files changed, 83 insertions(+) create mode 100644 SlackAPI/RPCMessages/PublishViewResponse.cs diff --git a/SlackAPI/Block.cs b/SlackAPI/Block.cs index 4fd670fc..19dd5525 100644 --- a/SlackAPI/Block.cs +++ b/SlackAPI/Block.cs @@ -182,6 +182,12 @@ public class DatePickerElement : IElement public Confirm confirm { get; set; } } + public class View + { + public string type { get; set; } = ViewTypes.Home; + public IBlock[] blocks { get; set; } + } + public static class ButtonStyles { public const string Primary = "primary"; @@ -198,6 +204,12 @@ public static class BlockTypes public const string Header = "header"; } + public static class ViewTypes + { + public const string Home = "home"; + public const string Modal = "modal"; + } + public static class TextTypes { public const string Markdown = "mrkdwn"; diff --git a/SlackAPI/RPCMessages/PublishViewResponse.cs b/SlackAPI/RPCMessages/PublishViewResponse.cs new file mode 100644 index 00000000..44638e98 --- /dev/null +++ b/SlackAPI/RPCMessages/PublishViewResponse.cs @@ -0,0 +1,38 @@ +namespace SlackAPI +{ + [RequestPath("views.publish")] + public class PublishViewResponse : Response + { + public string warning; + public ViewResponse view; + + public ResponseMetadata response_metadata { get; set; } + + public class ResponseMetadata + { + public string[] messages { get; set; } + } + + public class ViewResponse + { + public string id; + public string team_id; + public string app_id; + public string app_installed_team_id; + public string bot_id; + public string type; + public IBlock[] blocks; + public string hash; + public string private_metadata; + public string callback_id; + public string root_view_id; + public string external_id; + public Text title; + public object close; + public object submit; + public object previous_view_id; + public bool clear_on_close; + public bool notify_on_close; + } + } +} diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index a0762e9b..a0fa5562 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -897,5 +897,22 @@ public void DeleteFile(Action callback, string file = null) APIRequestWithToken(callback, new Tuple("file", file)); } + + public void PublishView( + Action callback, + string userId, + View view) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("userId", userId)); + parameters.Add(new Tuple("view", JsonConvert.SerializeObject(view, Formatting.None, + new JsonSerializerSettings // Shouldn't include a not set property + { + NullValueHandling = NullValueHandling.Ignore + }))); + + APIRequestWithToken(callback, parameters.ToArray()); + } } } diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 11962dfb..3b99d444 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -843,5 +843,21 @@ public Task ChannelSetTopicAsync(string channelId, stri new Tuple("channel", channelId), new Tuple("topic", newTopic)); } + + public Task PublishView( + string userId, + View view) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("userId", userId)); + parameters.Add(new Tuple("view", JsonConvert.SerializeObject(view, Formatting.None, + new JsonSerializerSettings // Shouldn't include a not set property + { + NullValueHandling = NullValueHandling.Ignore + }))); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } } } \ No newline at end of file From 825505a7d5bcef2d5975b097512d3e582436cc0e Mon Sep 17 00:00:00 2001 From: bilgin Date: Tue, 30 Nov 2021 15:02:17 +0000 Subject: [PATCH 40/54] refactoring --- SlackAPI/Block.cs | 2 +- ...hViewResponse.cs => AppHomeTabResponse.cs} | 44 +++++++++---------- SlackAPI/Response.cs | 4 +- SlackAPI/SlackClient.cs | 22 +++++----- SlackAPI/SlackTaskClient.cs | 22 +++++----- 5 files changed, 50 insertions(+), 44 deletions(-) rename SlackAPI/RPCMessages/{PublishViewResponse.cs => AppHomeTabResponse.cs} (61%) diff --git a/SlackAPI/Block.cs b/SlackAPI/Block.cs index 19dd5525..5b05099f 100644 --- a/SlackAPI/Block.cs +++ b/SlackAPI/Block.cs @@ -184,7 +184,7 @@ public class DatePickerElement : IElement public class View { - public string type { get; set; } = ViewTypes.Home; + public string type { get; set; } public IBlock[] blocks { get; set; } } diff --git a/SlackAPI/RPCMessages/PublishViewResponse.cs b/SlackAPI/RPCMessages/AppHomeTabResponse.cs similarity index 61% rename from SlackAPI/RPCMessages/PublishViewResponse.cs rename to SlackAPI/RPCMessages/AppHomeTabResponse.cs index 44638e98..e0b8db02 100644 --- a/SlackAPI/RPCMessages/PublishViewResponse.cs +++ b/SlackAPI/RPCMessages/AppHomeTabResponse.cs @@ -1,38 +1,38 @@ namespace SlackAPI { [RequestPath("views.publish")] - public class PublishViewResponse : Response + public class AppHomeTabResponse : Response { - public string warning; - public ViewResponse view; + public AppHomeTabView view; - public ResponseMetadata response_metadata { get; set; } - - public class ResponseMetadata - { - public string[] messages { get; set; } - } - - public class ViewResponse + public class AppHomeTabView { public string id; public string team_id; - public string app_id; - public string app_installed_team_id; - public string bot_id; public string type; - public IBlock[] blocks; - public string hash; - public string private_metadata; - public string callback_id; - public string root_view_id; - public string external_id; - public Text title; public object close; public object submit; - public object previous_view_id; + public Block[] blocks; + public string private_metadata; + public string callback_id; + public State state; + public string hash; public bool clear_on_close; public bool notify_on_close; + public string root_view_id; + public object previous_view_id; + public string app_id; + public string external_id; + public string bot_id; + } + + public class State + { + public Values values; + } + + public class Values + { } } } diff --git a/SlackAPI/Response.cs b/SlackAPI/Response.cs index 339bc0b8..8cd5e2c7 100644 --- a/SlackAPI/Response.cs +++ b/SlackAPI/Response.cs @@ -19,6 +19,7 @@ public abstract class Response public string error; public string needed; public string provided; + public string warning; public void AssertOk() { @@ -31,6 +32,7 @@ public void AssertOk() public class ResponseMetaData { - public string next_cursor; + public string next_cursor; + public string[] messages; } } diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index a0fa5562..775db7a3 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -898,19 +898,21 @@ public void DeleteFile(Action callback, string file = null) APIRequestWithToken(callback, new Tuple("file", file)); } - public void PublishView( - Action callback, + public void PublishAppHomeTab( + Action callback, string userId, View view) { - List> parameters = new List>(); - - parameters.Add(new Tuple("userId", userId)); - parameters.Add(new Tuple("view", JsonConvert.SerializeObject(view, Formatting.None, - new JsonSerializerSettings // Shouldn't include a not set property - { - NullValueHandling = NullValueHandling.Ignore - }))); + view.type = ViewTypes.Home; + var parameters = new List> + { + new Tuple("user_id", userId), + new Tuple("view", JsonConvert.SerializeObject(view, Formatting.None, + new JsonSerializerSettings // Shouldn't include a not set property + { + NullValueHandling = NullValueHandling.Ignore + })) + }; APIRequestWithToken(callback, parameters.ToArray()); } diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 3b99d444..4b13d8cb 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -844,20 +844,22 @@ public Task ChannelSetTopicAsync(string channelId, stri new Tuple("topic", newTopic)); } - public Task PublishView( + public Task PublishAppHomeTab( string userId, View view) { - List> parameters = new List>(); - - parameters.Add(new Tuple("userId", userId)); - parameters.Add(new Tuple("view", JsonConvert.SerializeObject(view, Formatting.None, - new JsonSerializerSettings // Shouldn't include a not set property - { - NullValueHandling = NullValueHandling.Ignore - }))); + view.type = ViewTypes.Home; + var parameters = new List> + { + new Tuple("user_id", userId), + new Tuple("view", JsonConvert.SerializeObject(view, Formatting.None, + new JsonSerializerSettings // Shouldn't include a not set property + { + NullValueHandling = NullValueHandling.Ignore + })) + }; - return APIRequestWithTokenAsync(parameters.ToArray()); + return APIRequestWithTokenAsync(parameters.ToArray()); } } } \ No newline at end of file From 4b3903b73ab4442cf360bbcfa62d1e883d54d88a Mon Sep 17 00:00:00 2001 From: bilgin Date: Tue, 30 Nov 2021 20:03:19 +0000 Subject: [PATCH 41/54] test --- SlackAPI.Tests/PublishAppHomeTab.cs | 48 +++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 SlackAPI.Tests/PublishAppHomeTab.cs diff --git a/SlackAPI.Tests/PublishAppHomeTab.cs b/SlackAPI.Tests/PublishAppHomeTab.cs new file mode 100644 index 00000000..8701e7b4 --- /dev/null +++ b/SlackAPI.Tests/PublishAppHomeTab.cs @@ -0,0 +1,48 @@ +using System; +using SlackAPI.RPCMessages; +using SlackAPI.Tests.Configuration; +using SlackAPI.Tests.Helpers; +using System.Linq; +using Xunit; + +namespace SlackAPI.Tests +{ + [Collection("Integration tests")] + public class PublishAppHomeTab + { + private readonly IntegrationFixture fixture; + + public PublishAppHomeTab(IntegrationFixture fixture) + { + this.fixture = fixture; + } + + [Fact] + public void SimpleMessageDelivery() + { + // given + var client = this.fixture.UserClient; + AppHomeTabResponse actual = null; + var text = Guid.NewGuid().ToString("N"); + + // when + using (var sync = new InSync(nameof(SlackClient.PublishAppHomeTab))) + { + var section = new Block { type = BlockTypes.Section, text = new Text { type = TextTypes.Markdown, text = text } }; + client.PublishAppHomeTab( + response => + { + actual = response; + sync.Proceed(); + }, + this.fixture.Config.DirectMessageUser, + new View { type = ViewTypes.Home, blocks = new IBlock[] { section } }); + } + + // then + Assert.True(actual.ok, "Error while posting message to channel. "); + Assert.Equal(text, actual.view.blocks[0].text.text); + Assert.Equal(ViewTypes.Home, actual.view.type); + } + } +} \ No newline at end of file From 988e62daf2b5468f2c00a9326c396a2b3d36e57a Mon Sep 17 00:00:00 2001 From: "wesley.bakewell" Date: Tue, 7 Dec 2021 11:38:47 -0800 Subject: [PATCH 42/54] conversationsJoin --- SlackAPI/RPCMessages/ConversationsJoinResponse.cs | 9 +++++++++ SlackAPI/Response.cs | 1 + SlackAPI/SlackClient.cs | 5 +++++ 3 files changed, 15 insertions(+) create mode 100644 SlackAPI/RPCMessages/ConversationsJoinResponse.cs diff --git a/SlackAPI/RPCMessages/ConversationsJoinResponse.cs b/SlackAPI/RPCMessages/ConversationsJoinResponse.cs new file mode 100644 index 00000000..873818de --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsJoinResponse.cs @@ -0,0 +1,9 @@ +namespace SlackAPI.RPCMessages +{ + + [RequestPath("conversations.join")] + public class ConversationsJoinResponse : Response + { + public Channel channel; + } +} \ No newline at end of file diff --git a/SlackAPI/Response.cs b/SlackAPI/Response.cs index 339bc0b8..50112bf3 100644 --- a/SlackAPI/Response.cs +++ b/SlackAPI/Response.cs @@ -19,6 +19,7 @@ public abstract class Response public string error; public string needed; public string provided; + public string warning; public void AssertOk() { diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index a0762e9b..5ea823bd 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -397,6 +397,11 @@ public void ConversationsInvite(Action callback, st APIRequestWithToken(callback, parameters.ToArray()); } + public void ConversationsJoin(Action callback, string channelId) + { + APIRequestWithToken(callback, new Tuple("channel", channelId)); + } + public void ConversationsKick(Action callback, string channelId, string userId) { List> parameters = new List>(); From 6a75209ca24c77748f1fd8daff55494500aeae2c Mon Sep 17 00:00:00 2001 From: "wesley.bakewell" Date: Tue, 7 Dec 2021 16:21:48 -0800 Subject: [PATCH 43/54] missed async implementation --- SlackAPI/SlackTaskClient.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 11962dfb..179964fd 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -385,6 +385,11 @@ public Task ConversationsInviteAsync(string channel return APIRequestWithTokenAsync(parameters.ToArray()); } + public Task ConversationsJoinAsync(string channelId) + { + return APIRequestWithTokenAsync(new Tuple("channel", channelId)); + } + public Task ConversationsKickAsync(string channelId, string userId) { List> parameters = new List>(); From faafb2f673de6573ce83e80dd4330f1b9363f177 Mon Sep 17 00:00:00 2001 From: "wesley.bakewell" Date: Tue, 7 Dec 2021 16:28:20 -0800 Subject: [PATCH 44/54] Correct the base for PR --- SlackAPI/SlackTaskClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 11962dfb..6bb843b5 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -608,7 +608,7 @@ public Task UpdateAsync(string ts, public Task JoinDirectMessageChannelAsync(string user) { - var param = new Tuple("user", user); + var param = new Tuple("users", user); return APIRequestWithTokenAsync(param); } From 7d2681b8deda671cf6f6833fc02c51f2d3a870b7 Mon Sep 17 00:00:00 2001 From: "wesley.bakewell" Date: Wed, 8 Dec 2021 11:50:42 -0800 Subject: [PATCH 45/54] delete bad test --- SlackAPI.Tests/PublishAppHomeTab.cs | 48 ----------------------------- 1 file changed, 48 deletions(-) delete mode 100644 SlackAPI.Tests/PublishAppHomeTab.cs diff --git a/SlackAPI.Tests/PublishAppHomeTab.cs b/SlackAPI.Tests/PublishAppHomeTab.cs deleted file mode 100644 index 8701e7b4..00000000 --- a/SlackAPI.Tests/PublishAppHomeTab.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using SlackAPI.RPCMessages; -using SlackAPI.Tests.Configuration; -using SlackAPI.Tests.Helpers; -using System.Linq; -using Xunit; - -namespace SlackAPI.Tests -{ - [Collection("Integration tests")] - public class PublishAppHomeTab - { - private readonly IntegrationFixture fixture; - - public PublishAppHomeTab(IntegrationFixture fixture) - { - this.fixture = fixture; - } - - [Fact] - public void SimpleMessageDelivery() - { - // given - var client = this.fixture.UserClient; - AppHomeTabResponse actual = null; - var text = Guid.NewGuid().ToString("N"); - - // when - using (var sync = new InSync(nameof(SlackClient.PublishAppHomeTab))) - { - var section = new Block { type = BlockTypes.Section, text = new Text { type = TextTypes.Markdown, text = text } }; - client.PublishAppHomeTab( - response => - { - actual = response; - sync.Proceed(); - }, - this.fixture.Config.DirectMessageUser, - new View { type = ViewTypes.Home, blocks = new IBlock[] { section } }); - } - - // then - Assert.True(actual.ok, "Error while posting message to channel. "); - Assert.Equal(text, actual.view.blocks[0].text.text); - Assert.Equal(ViewTypes.Home, actual.view.type); - } - } -} \ No newline at end of file From 258fd0cf8e6b42daa329b44c2d8fd53e1e7aab32 Mon Sep 17 00:00:00 2001 From: "wesley.bakewell" Date: Tue, 4 Jan 2022 13:46:49 -0800 Subject: [PATCH 46/54] Don't post as_user unless specified. --- SlackAPI/SlackClient.cs | 8 ++++---- SlackAPI/SlackTaskClient.cs | 11 ++++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index 775db7a3..5d618dc3 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -604,7 +604,7 @@ public void Update( bool linkNames = false, IBlock[] blocks = null, Attachment[] attachments = null, - bool as_user = false) + bool? as_user = null) { List> parameters = new List>(); @@ -634,9 +634,9 @@ public void Update( { NullValueHandling = NullValueHandling.Ignore }))); - - - parameters.Add(new Tuple("as_user", as_user.ToString())); + + if (as_user.HasValue) + parameters.Add(new Tuple("as_user", as_user.ToString())); APIRequestWithToken(callback, parameters.ToArray()); } diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 72b83fbd..1a4ae6cc 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -578,7 +578,7 @@ public Task UpdateAsync(string ts, string parse = null, bool linkNames = false, Attachment[] attachments = null, - bool as_user = false, + bool? as_user = null, IBlock[] blocks = null) { List> parameters = new List>(); @@ -599,7 +599,8 @@ public Task UpdateAsync(string ts, if (attachments != null && attachments.Length > 0) parameters.Add(new Tuple("attachments", JsonConvert.SerializeObject(attachments))); - parameters.Add(new Tuple("as_user", as_user.ToString())); + if (as_user.HasValue) + parameters.Add(new Tuple("as_user", as_user.ToString())); if (blocks != null && blocks.Length > 0) parameters.Add(new Tuple("blocks", JsonConvert.SerializeObject(blocks, @@ -628,7 +629,7 @@ public Task PostMessageAsync( bool? unfurl_links = null, string icon_url = null, string icon_emoji = null, - bool as_user = false, + bool? as_user = null, string thread_ts = null) { List> parameters = new List>(); @@ -668,8 +669,8 @@ public Task PostMessageAsync( if (!string.IsNullOrEmpty(icon_emoji)) parameters.Add(new Tuple("icon_emoji", icon_emoji)); - if (as_user) - parameters.Add(new Tuple("as_user", true.ToString())); + if (as_user.HasValue) + parameters.Add(new Tuple("as_user", as_user.ToString())); if (!string.IsNullOrEmpty(thread_ts)) parameters.Add(new Tuple("thread_ts", thread_ts)); From a393023dd6af10bc3c401e3822705bdd4f8ed259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Solg=C3=A5rd?= Date: Mon, 24 Jan 2022 22:41:05 +0100 Subject: [PATCH 47/54] Add conversations.members #294 --- .../RPCMessages/ConversationsMembersResponse.cs | 8 ++++++++ SlackAPI/SlackClient.cs | 14 ++++++++++++++ SlackAPI/SlackTaskClient.cs | 14 ++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 SlackAPI/RPCMessages/ConversationsMembersResponse.cs diff --git a/SlackAPI/RPCMessages/ConversationsMembersResponse.cs b/SlackAPI/RPCMessages/ConversationsMembersResponse.cs new file mode 100644 index 00000000..80fdfdb7 --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsMembersResponse.cs @@ -0,0 +1,8 @@ +namespace SlackAPI.RPCMessages +{ + [RequestPath("conversations.members")] + public class ConversationsMembersResponse : Response + { + public string[] channels; + } +} \ No newline at end of file diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index 775db7a3..b07fa167 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -155,6 +155,20 @@ public void GetConversationsList(Action callback, str APIRequestWithToken(callback, parameters.ToArray()); } + + public void GetConversationsMembers(Action callback, string channelId, string cursor = "", int limit = 100) + { + List> parameters = new List> + { + new Tuple("channel", channelId) + }; + if (limit > 0) + parameters.Add(Tuple.Create("limit", limit.ToString())); + if (!string.IsNullOrEmpty(cursor)) + parameters.Add(Tuple.Create("cursor", cursor)); + + APIRequestWithToken(callback, parameters.ToArray()); + } public void GetChannelList(Action callback, bool ExcludeArchived = true) { diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 72b83fbd..568dab1d 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -138,6 +138,20 @@ public Task GetConversationsListAsync(string cursor = return APIRequestWithTokenAsync(parameters.ToArray()); } + + public Task GetConversationsMembersAsync(string channelId, string cursor = "", int limit = 100) + { + List> parameters = new List> + { + new Tuple("channel", channelId) + }; + if (limit > 0) + parameters.Add(Tuple.Create("limit", limit.ToString())); + if (!string.IsNullOrEmpty(cursor)) + parameters.Add(new Tuple("cursor", cursor)); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } public Task GetChannelListAsync(bool ExcludeArchived = true) { From 7b4f650c2a7acc1b4e4b5776cb469df1e3256905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Solg=C3=A5rd?= Date: Tue, 25 Jan 2022 08:19:34 +0100 Subject: [PATCH 48/54] Mapped against members --- SlackAPI/RPCMessages/ConversationsMembersResponse.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SlackAPI/RPCMessages/ConversationsMembersResponse.cs b/SlackAPI/RPCMessages/ConversationsMembersResponse.cs index 80fdfdb7..bd53a648 100644 --- a/SlackAPI/RPCMessages/ConversationsMembersResponse.cs +++ b/SlackAPI/RPCMessages/ConversationsMembersResponse.cs @@ -3,6 +3,6 @@ namespace SlackAPI.RPCMessages [RequestPath("conversations.members")] public class ConversationsMembersResponse : Response { - public string[] channels; + public string[] members; } } \ No newline at end of file From c93f241d45e8795551273ce38848f0fbb60caffb Mon Sep 17 00:00:00 2001 From: Pongsakorn Thanopassakul Date: Mon, 21 Feb 2022 14:39:30 +0100 Subject: [PATCH 49/54] + add title to UserProfile class --- SlackAPI/UserProfile.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/SlackAPI/UserProfile.cs b/SlackAPI/UserProfile.cs index 65ab093a..958af2f4 100644 --- a/SlackAPI/UserProfile.cs +++ b/SlackAPI/UserProfile.cs @@ -1,13 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { public class UserProfile : ProfileIcons { + public string title; public string first_name; public string last_name; public string real_name; From 657a7a79bf5c8f764f33b2a5043608ce3536170e Mon Sep 17 00:00:00 2001 From: Pongsakorn Thanopassakul Date: Wed, 23 Feb 2022 17:06:27 +0100 Subject: [PATCH 50/54] feat: Add display_name field for UserProfile --- SlackAPI/UserProfile.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/SlackAPI/UserProfile.cs b/SlackAPI/UserProfile.cs index 958af2f4..6a3d6932 100644 --- a/SlackAPI/UserProfile.cs +++ b/SlackAPI/UserProfile.cs @@ -3,6 +3,7 @@ public class UserProfile : ProfileIcons { public string title; + public string display_name; public string first_name; public string last_name; public string real_name; From 128917d7d206a34896ff0b4682d42ff9fea6173a Mon Sep 17 00:00:00 2001 From: Youssef Elhafyani Date: Wed, 20 Apr 2022 22:06:09 -0400 Subject: [PATCH 51/54] Fix the post_at parameter as the date substraction result in double precision, and slack api doesn't accept a double type , it expect an int as string --- SlackAPI/SlackClient.cs | 2 +- SlackAPI/SlackTaskClient.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index 775db7a3..04fa168d 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -776,7 +776,7 @@ public void ScheduleMessage( parameters.Add(new Tuple("channel", channelId)); parameters.Add(new Tuple("text", text)); - parameters.Add(new Tuple("post_at", (post_at - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds.ToString())); + parameters.Add(new Tuple("post_at", Convert.ToUInt64((post_at - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds).ToString())); if (!string.IsNullOrEmpty(botName)) parameters.Add(new Tuple("username", botName)); diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 72b83fbd..58cb6231 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -732,7 +732,7 @@ public Task ScheduleMessageAsync( parameters.Add(new Tuple("channel", channelId)); parameters.Add(new Tuple("text", text)); - parameters.Add(new Tuple("post_at", (post_at - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds.ToString())); + parameters.Add(new Tuple("post_at", Convert.ToUInt64((post_at - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds).ToString())); if (!string.IsNullOrEmpty(botName)) parameters.Add(new Tuple("username", botName)); From adf25a04dd2d73704fff42a1853fa7e7edad7e04 Mon Sep 17 00:00:00 2001 From: John Mancini Date: Sat, 23 Apr 2022 13:06:34 -0400 Subject: [PATCH 52/54] updated GetUserListAsync with optional arguments --- SlackAPI/SlackTaskClient.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 72b83fbd..079aa714 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -99,9 +99,20 @@ public Task TestAuthAsync() return APIRequestWithTokenAsync(); } - public Task GetUserListAsync() + public Task GetUserListAsync(int limit = 0, bool include_locale = false, string cursor = null, string team_id = null) { - return APIRequestWithTokenAsync(); + var args = new List>(); + args.Add(new Tuple("limit", limit.ToString())); + args.Add(new Tuple("include_locale", include_locale.ToString())); + if (cursor != null) + { + args.Add(new Tuple("cursor", cursor)); + } + if (team_id != null) + { + args.Add(new Tuple("team_id", team_id)); + } + return APIRequestWithTokenAsync(args.ToArray()); } public Task GetUserByEmailAsync(string email) From 52c8d48ed6a01e306a40b55ddf0fc66848107a3e Mon Sep 17 00:00:00 2001 From: John Mancini Date: Sat, 14 May 2022 10:39:31 -0400 Subject: [PATCH 53/54] added gating to limit --- SlackAPI/SlackTaskClient.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 079aa714..ac2809a8 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -101,6 +101,10 @@ public Task TestAuthAsync() public Task GetUserListAsync(int limit = 0, bool include_locale = false, string cursor = null, string team_id = null) { + if (limit < 0) + { + throw new ArgumentException(nameof(limit)); + } var args = new List>(); args.Add(new Tuple("limit", limit.ToString())); args.Add(new Tuple("include_locale", include_locale.ToString())); From 0b1b8c2d113a1d44855a6859954d90dd6cd9f5df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Jun 2022 20:23:41 +0000 Subject: [PATCH 54/54] Bump Newtonsoft.Json from 9.0.1 to 13.0.1 in /SlackAPI Bumps [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json) from 9.0.1 to 13.0.1. - [Release notes](https://github.com/JamesNK/Newtonsoft.Json/releases) - [Commits](https://github.com/JamesNK/Newtonsoft.Json/compare/9.0.1...13.0.1) --- updated-dependencies: - dependency-name: Newtonsoft.Json dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- SlackAPI/SlackAPI.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SlackAPI/SlackAPI.csproj b/SlackAPI/SlackAPI.csproj index b93cc54f..934c5356 100644 --- a/SlackAPI/SlackAPI.csproj +++ b/SlackAPI/SlackAPI.csproj @@ -8,7 +8,7 @@ - +