diff --git a/MisterDoctor/App.config b/MisterDoctor/App.config index b50c74f..9c7c672 100644 --- a/MisterDoctor/App.config +++ b/MisterDoctor/App.config @@ -1,6 +1,18 @@ - + + + + + + + + + + + + + \ No newline at end of file diff --git a/MisterDoctor/Classes/TokenFile.cs b/MisterDoctor/Classes/TokenFile.cs index 5575ebe..0f2b8b0 100644 --- a/MisterDoctor/Classes/TokenFile.cs +++ b/MisterDoctor/Classes/TokenFile.cs @@ -6,7 +6,9 @@ internal class Token public string Username { get; set; } public string UserOAuthKey { get; set; } - + + public string ClientId { get; set; } + public override string ToString() { return $"{Id} - {Username}"; diff --git a/MisterDoctor/Forms/FormMain.cs b/MisterDoctor/Forms/FormMain.cs index bb8bc9e..53d8639 100644 --- a/MisterDoctor/Forms/FormMain.cs +++ b/MisterDoctor/Forms/FormMain.cs @@ -1,6 +1,7 @@ using System; using System.Drawing; using System.Linq; +using System.Net; using System.Threading; using System.Timers; using System.Windows.Forms; @@ -8,6 +9,8 @@ using MisterDoctor.Helpers; using MisterDoctor.Managers; using MisterDoctor.Properties; +using Newtonsoft.Json.Linq; +using RestSharp; using TwitchLib.Client; using TwitchLib.Client.Events; using TwitchLib.Client.Models; @@ -28,6 +31,8 @@ internal partial class FormMain : Form private bool _procNext; private bool _closing; + private string _channelId = string.Empty; + public FormMain() { InitializeComponent(); @@ -294,6 +299,13 @@ private void Connect() return; } + if (string.IsNullOrEmpty(token.ClientId)) + { + ShowError("No Client ID"); + ShowToken(); + return; + } + if (DbHelper.WordRandom() == null) { ShowError("No Substitution Words Set"); @@ -353,7 +365,7 @@ private void Twitch_OnMessageReceived(object sender, OnMessageReceivedArgs e) if (message == null) return; if (message.IsMe) return; if (message.Username.Equals(_twitchClient.TwitchUsername, StringComparison.CurrentCultureIgnoreCase)) return; - + // Check for command if (message.Message.StartsWith(_settings.CommandIgnore, StringComparison.CurrentCultureIgnoreCase)) @@ -396,9 +408,9 @@ private void Twitch_OnMessageReceived(object sender, OnMessageReceivedArgs e) var send = GoodBadCheck(parts, _twitchClient.TwitchUsername); if (string.IsNullOrEmpty(send)) send = PhraseCheck(parts, message.Username); - if (string.IsNullOrEmpty(send)) send = RandomReplace(parts); + if (string.IsNullOrEmpty(send)) send = RandomReplace(message.Username, message.Channel, parts); if (string.IsNullOrEmpty(send)) return; - + var sendParts = new MessageParts(send); sendParts.UpdateWildcards(message); @@ -430,7 +442,7 @@ private static string PhraseCheck(MessageParts parts, string username) return PhraseManager.CheckMessage(parts, username); } - private string RandomReplace(MessageParts parts) + private string RandomReplace(string user, string channel, MessageParts parts) { // Cooldown ? if (_coolDownTime.HasValue) @@ -450,6 +462,10 @@ private string RandomReplace(MessageParts parts) _procNext = true; + // First check if the user is following (check after proc) + + if (!IsFollowing(user, channel)) return string.Empty; + // Get the indexes of the nouns if (!parts.HasNoun()) return string.Empty; @@ -470,5 +486,60 @@ private string RandomReplace(MessageParts parts) return messageToSend; } + + private bool IsFollowing(string messageUsername, string channelName) + { + if (messageUsername.Equals(channelName, StringComparison.CurrentCultureIgnoreCase)) return true; + + // get https://api.twitch.tv/kraken/users//follows/channels/ + // Accept: application/vnd.twitchtv.v5+json + // Client-ID: xxxxxxxxxxxx + + var client = new RestClient("https://api.twitch.tv/kraken/"); + var id = DbHelper.TokenGet().ClientId; + + // Get the channels id number (if hasn't been pulled yet) + + if (string.IsNullOrEmpty(_channelId)) + { + var channelRequest = new RestRequest($"users?login={channelName}"); + channelRequest.AddHeader("Accept", "application/vnd.twitchtv.v5+json"); + channelRequest.AddHeader("Client-ID", id); + + var channelResponse = client.Get(channelRequest); + + var crObj = JObject.Parse(channelResponse.Content); + if (!crObj.ContainsKey("_total")) return false; + if (crObj["_total"].ToObject() != 1) return false; + + _channelId = ((JArray)crObj.GetValue("users")).First()["_id"].ToString(); + } + + // Get the users id number + + var userRequest = new RestRequest($"users?login={messageUsername}"); + userRequest.AddHeader("Accept", "application/vnd.twitchtv.v5+json"); + userRequest.AddHeader("Client-ID", id); + + var userResponse = client.Get(userRequest); + + var urObj = JObject.Parse(userResponse.Content); + if (!urObj.ContainsKey("_total")) return false; + if (urObj["_total"].ToObject() != 1) return false; + var userId = ((JArray)urObj.GetValue("users")).First()["_id"].ToString(); + + // Get the follow information + + var followRequest = new RestRequest($"users/{userId}/follows/channels/{_channelId}"); + followRequest.AddHeader("Accept", "application/vnd.twitchtv.v5+json"); + followRequest.AddHeader("Client-ID", id); + + var followResponse = client.Get(followRequest); + + var statusCode = followResponse.StatusCode; + + return statusCode == HttpStatusCode.OK; + + } } } diff --git a/MisterDoctor/Forms/FormToken.Designer.cs b/MisterDoctor/Forms/FormToken.Designer.cs index fb24f94..a5bec7c 100644 --- a/MisterDoctor/Forms/FormToken.Designer.cs +++ b/MisterDoctor/Forms/FormToken.Designer.cs @@ -35,6 +35,9 @@ private void InitializeComponent() this.btnSave = new System.Windows.Forms.Button(); this.btnCancel = new System.Windows.Forms.Button(); this.lnkGetOAuth = new System.Windows.Forms.LinkLabel(); + this.label1 = new System.Windows.Forms.Label(); + this.txtClientId = new System.Windows.Forms.TextBox(); + this.lnkGetClient = new System.Windows.Forms.LinkLabel(); this.SuspendLayout(); // // lblUsername @@ -73,7 +76,7 @@ private void InitializeComponent() // // btnSave // - this.btnSave.Location = new System.Drawing.Point(12, 58); + this.btnSave.Location = new System.Drawing.Point(15, 112); this.btnSave.Name = "btnSave"; this.btnSave.Size = new System.Drawing.Size(75, 23); this.btnSave.TabIndex = 4; @@ -83,7 +86,7 @@ private void InitializeComponent() // btnCancel // this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnCancel.Location = new System.Drawing.Point(275, 58); + this.btnCancel.Location = new System.Drawing.Point(275, 112); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(75, 23); this.btnCancel.TabIndex = 6; @@ -100,11 +103,42 @@ private void InitializeComponent() this.lnkGetOAuth.TabStop = true; this.lnkGetOAuth.Text = "Get OAuth Key"; // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 89); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(101, 13); + this.label1.TabIndex = 7; + this.label1.Text = "Twitch Bot Client ID"; + // + // txtClientId + // + this.txtClientId.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtClientId.Location = new System.Drawing.Point(130, 86); + this.txtClientId.Name = "txtClientId"; + this.txtClientId.Size = new System.Drawing.Size(220, 20); + this.txtClientId.TabIndex = 8; + // + // lnkGetClient + // + this.lnkGetClient.AutoSize = true; + this.lnkGetClient.Location = new System.Drawing.Point(127, 117); + this.lnkGetClient.Name = "lnkGetClient"; + this.lnkGetClient.Size = new System.Drawing.Size(67, 13); + this.lnkGetClient.TabIndex = 9; + this.lnkGetClient.TabStop = true; + this.lnkGetClient.Text = "Get Client ID"; + // // FormToken // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(362, 90); + this.ClientSize = new System.Drawing.Size(362, 149); + this.Controls.Add(this.lnkGetClient); + this.Controls.Add(this.txtClientId); + this.Controls.Add(this.label1); this.Controls.Add(this.lnkGetOAuth); this.Controls.Add(this.btnCancel); this.Controls.Add(this.btnSave); @@ -133,5 +167,8 @@ private void InitializeComponent() private System.Windows.Forms.Button btnSave; private System.Windows.Forms.Button btnCancel; private System.Windows.Forms.LinkLabel lnkGetOAuth; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox txtClientId; + private System.Windows.Forms.LinkLabel lnkGetClient; } } \ No newline at end of file diff --git a/MisterDoctor/Forms/FormToken.cs b/MisterDoctor/Forms/FormToken.cs index df36d2b..eb55542 100644 --- a/MisterDoctor/Forms/FormToken.cs +++ b/MisterDoctor/Forms/FormToken.cs @@ -23,11 +23,13 @@ private void FormToken_Load(object sender, EventArgs e) { txtUsername.Text = Token.Username; txtOAuth.Text = Token.UserOAuthKey; + txtClientId.Text = Token.ClientId; } CancelButton = btnCancel; lnkGetOAuth.LinkClicked += lnkGetOAuth_LinkClicked; + lnkGetClient.LinkClicked += lnkGetClient_LinkClicked; btnSave.Click += btnSave_Click; btnCancel.Click += btnCancel_Click; @@ -37,6 +39,11 @@ private void FormToken_Load(object sender, EventArgs e) ToggleSave(); } + private static void lnkGetClient_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + Process.Start("https://dev.twitch.tv/console/apps/"); + } + private static void lnkGetOAuth_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { Process.Start("https://twitchapps.com/tmi/"); @@ -77,7 +84,8 @@ private void btnSave_Click(object sender, EventArgs e) Token = new Token { Username = txtUsername.Text.Trim(), - UserOAuthKey = txtOAuth.Text.Trim() + UserOAuthKey = txtOAuth.Text.Trim(), + ClientId = txtClientId.Text.Trim() }; Save = true; diff --git a/MisterDoctor/Helpers/DbHelper.cs b/MisterDoctor/Helpers/DbHelper.cs index 7ddbe56..346344f 100644 --- a/MisterDoctor/Helpers/DbHelper.cs +++ b/MisterDoctor/Helpers/DbHelper.cs @@ -47,6 +47,7 @@ public static void TokenSet(Token token) { origToken.Username = token.Username; origToken.UserOAuthKey = token.UserOAuthKey; + origToken.ClientId = token.ClientId; collection.Update(origToken); } diff --git a/MisterDoctor/MisterDoctor.csproj b/MisterDoctor/MisterDoctor.csproj index ca402e7..01528bd 100644 --- a/MisterDoctor/MisterDoctor.csproj +++ b/MisterDoctor/MisterDoctor.csproj @@ -45,15 +45,75 @@ ..\packages\LiteDB.4.1.4\lib\net40\LiteDB.dll - - ..\packages\Microsoft.Extensions.Logging.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\packages\Microsoft.Extensions.Logging.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll + + + ..\packages\RestSharp.106.10.1\lib\net452\RestSharp.dll + + ..\packages\System.Net.Http.4.3.3\lib\net46\System.Net.Http.dll + True + True + + + ..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll + True + True + + + ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll + True + True + + + ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll + True + True + + + ..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll + True + True + + + + ..\packages\TwitchLib.Api.3.1.2\lib\netstandard2.0\TwitchLib.Api.dll + + + ..\packages\TwitchLib.Api.Core.3.1.2\lib\netstandard2.0\TwitchLib.Api.Core.dll + + + ..\packages\TwitchLib.Api.Core.Enums.3.1.2\lib\netstandard2.0\TwitchLib.Api.Core.Enums.dll + + + ..\packages\TwitchLib.Api.Core.Interfaces.3.1.2\lib\netstandard2.0\TwitchLib.Api.Core.Interfaces.dll + + + ..\packages\TwitchLib.Api.Core.Models.3.1.2\lib\netstandard2.0\TwitchLib.Api.Core.Models.dll + + + ..\packages\TwitchLib.Api.Helix.3.1.2\lib\netstandard2.0\TwitchLib.Api.Helix.dll + + + ..\packages\TwitchLib.Api.Helix.Models.3.1.2\lib\netstandard2.0\TwitchLib.Api.Helix.Models.dll + + + ..\packages\TwitchLib.Api.V5.3.1.2\lib\netstandard2.0\TwitchLib.Api.V5.dll + + + ..\packages\TwitchLib.Api.V5.Models.3.1.2\lib\netstandard2.0\TwitchLib.Api.V5.Models.dll + ..\packages\TwitchLib.Client.3.1.4\lib\netstandard2.0\TwitchLib.Client.dll @@ -66,6 +126,9 @@ ..\packages\TwitchLib.Communication.1.0.3\lib\netstandard2.0\TwitchLib.Communication.dll + + ..\packages\TwitchLib.PubSub.3.1.3\lib\netstandard2.0\TwitchLib.PubSub.dll + diff --git a/MisterDoctor/packages.config b/MisterDoctor/packages.config index b5144e5..1ac5ac6 100644 --- a/MisterDoctor/packages.config +++ b/MisterDoctor/packages.config @@ -3,7 +3,10 @@ - + + + +