├── .gitignore ├── LICENSE ├── README.md └── StreamElementsNET ├── StreamElements.Test ├── StreamElements.Test.sln └── StreamElements.Test │ ├── Program.cs │ └── StreamElements.Test.csproj ├── StreamElementsNET.sln └── StreamElementsNET ├── Client.cs ├── Models ├── Cheer │ ├── Cheer.cs │ ├── CheerLatest.cs │ ├── CheerSessionTopDonation.cs │ └── CheerSessionTopDonator.cs ├── Follower │ └── Follower.cs ├── Host │ ├── Host.cs │ └── HostLatest.cs ├── Internal │ ├── Authenticated.cs │ └── SessionMetadata.cs ├── Store │ └── StoreRedemption.cs ├── Subscriber │ ├── Subscriber.cs │ ├── SubscriberAlltimeGifter.cs │ ├── SubscriberGiftedLatest.cs │ ├── SubscriberLatest.cs │ ├── SubscriberNewLatest.cs │ └── SubscriberResubLatest.cs ├── Tip │ ├── Tip.cs │ ├── TipLatest.cs │ ├── TipSessionTopDonation.cs │ └── TipSessionTopDonator.cs └── Unknown │ └── UnknownEventArgs.cs ├── Parsing ├── Cheer.cs ├── Follower.cs ├── Host.cs ├── Internal.cs ├── StoreRedemption.cs ├── Subscriber.cs └── Tip.cs └── StreamElementsNET.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # Build results 11 | [Dd]ebug/ 12 | [Dd]ebugPublic/ 13 | [Rr]elease/ 14 | [Rr]eleases/ 15 | x64/ 16 | x86/ 17 | build/ 18 | bld/ 19 | [Bb]in/ 20 | [Oo]bj/ 21 | 22 | # Roslyn cache directories 23 | *.ide/ 24 | *.vs/ 25 | 26 | # MSTest test Results 27 | [Tt]est[Rr]esult*/ 28 | [Bb]uild[Ll]og.* 29 | 30 | #NUNIT 31 | *.VisualState.xml 32 | TestResult.xml 33 | 34 | # Build Results of an ATL Project 35 | [Dd]ebugPS/ 36 | [Rr]eleasePS/ 37 | dlldata.c 38 | 39 | *_i.c 40 | *_p.c 41 | *_i.h 42 | *.ilk 43 | *.meta 44 | *.obj 45 | *.pch 46 | *.pdb 47 | *.pgc 48 | *.pgd 49 | *.rsp 50 | *.sbr 51 | *.tlb 52 | *.tli 53 | *.tlh 54 | *.tmp 55 | *.tmp_proj 56 | *.log 57 | *.vspscc 58 | *.vssscc 59 | .builds 60 | *.pidb 61 | *.svclog 62 | *.scc 63 | 64 | # Chutzpah Test files 65 | _Chutzpah* 66 | 67 | # Visual C++ cache files 68 | ipch/ 69 | *.aps 70 | *.ncb 71 | *.opensdf 72 | *.sdf 73 | *.cachefile 74 | 75 | # Visual Studio profiler 76 | *.psess 77 | *.vsp 78 | *.vspx 79 | 80 | # TFS 2012 Local Workspace 81 | $tf/ 82 | 83 | # Guidance Automation Toolkit 84 | *.gpState 85 | 86 | # ReSharper is a .NET coding add-in 87 | _ReSharper*/ 88 | *.[Rr]e[Ss]harper 89 | *.DotSettings.user 90 | 91 | # JustCode is a .NET coding addin-in 92 | .JustCode 93 | 94 | # TeamCity is a build add-in 95 | _TeamCity* 96 | 97 | # DotCover is a Code Coverage Tool 98 | *.dotCover 99 | 100 | # NCrunch 101 | _NCrunch_* 102 | .*crunch*.local.xml 103 | 104 | # MightyMoose 105 | *.mm.* 106 | AutoTest.Net/ 107 | 108 | # Web workbench (sass) 109 | .sass-cache/ 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.[Pp]ublish.xml 129 | *.azurePubxml 130 | # TODO: Comment the next line if you want to checkin your web deploy settings 131 | # but database connection strings (with potential passwords) will be unencrypted 132 | *.pubxml 133 | *.publishproj 134 | 135 | # NuGet Packages 136 | *.nupkg 137 | # The packages folder can be ignored because of Package Restore 138 | **/packages/* 139 | # except build/, which is used as an MSBuild target. 140 | !**/packages/build/ 141 | # If using the old MSBuild-Integrated Package Restore, uncomment this: 142 | #!**/packages/repositories.config 143 | 144 | # Windows Azure Build Output 145 | csx/ 146 | *.build.csdef 147 | 148 | # Windows Store app package directory 149 | AppPackages/ 150 | 151 | # Others 152 | sql/ 153 | *.Cache 154 | ClientBin/ 155 | [Ss]tyle[Cc]op.* 156 | ~$* 157 | *~ 158 | *.dbmdl 159 | *.dbproj.schemaview 160 | *.pfx 161 | *.publishsettings 162 | node_modules/ 163 | 164 | # RIA/Silverlight projects 165 | Generated_Code/ 166 | 167 | # Backup & report files from converting an old project file 168 | # to a newer Visual Studio version. Backup files are not needed, 169 | # because we have git ;-) 170 | _UpgradeReport_Files/ 171 | Backup*/ 172 | UpgradeLog*.XML 173 | UpgradeLog*.htm 174 | 175 | # SQL Server files 176 | *.mdf 177 | *.ldf 178 | 179 | # Business Intelligence projects 180 | *.rdl.data 181 | *.bim.layout 182 | *.bim_*.settings 183 | 184 | # Microsoft Fakes 185 | FakesAssemblies/ 186 | 187 | # ========================= 188 | # Operating System Files 189 | # ========================= 190 | 191 | # OSX 192 | # ========================= 193 | 194 | .DS_Store 195 | .AppleDouble 196 | .LSOverride 197 | 198 | # Thumbnails 199 | ._* 200 | 201 | # Files that might appear on external disk 202 | .Spotlight-V100 203 | .Trashes 204 | 205 | # Directories potentially created on remote AFP share 206 | .AppleDB 207 | .AppleDesktop 208 | Network Trash Folder 209 | Temporary Items 210 | .apdisk 211 | 212 | # Windows 213 | # ========================= 214 | 215 | # Windows image file caches 216 | Thumbs.db 217 | ehthumbs.db 218 | 219 | # Folder config file 220 | Desktop.ini 221 | 222 | # Recycle Bin used on file shares 223 | $RECYCLE.BIN/ 224 | 225 | # Windows Installer files 226 | *.cab 227 | *.msi 228 | *.msm 229 | *.msp 230 | 231 | # Windows shortcuts 232 | *.lnk 233 | 234 | # Rider files 235 | .idea/ 236 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Cole 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # StreamElementsNET 2 | 3 | ## Overview 4 | C# library for reading event data from StreamElements. Events include tips, subscriptions, hosts, followers, and cheers. All that is required is the JWT that is obtained when logged into StreamElements. **DESIGNED FOR TWITCH INTEGRATIONS** 5 | 6 | ### Supported events 7 | ##### Tips 8 | - `OnTip` 9 | - `OnTipCount` 10 | - `OnTipLatest` 11 | - `OnTipSession` 12 | - `OnTipGoal` 13 | - `OnTipWeek` 14 | - `OnTipTotal` 15 | - `OnTipMonth` 16 | - `OnTipSessionTopDonator` 17 | - `OnTipSessionTopDonation` 18 | 19 | ##### Subscriptions 20 | - `OnSubscriber` 21 | - `OnSubscriberLatest` 22 | - `OnSubscriberSession` 23 | - `OnSubscriberGoal` 24 | - `OnSubscriberMonth` 25 | - `OnSubscriberWWeek` 26 | - `OnSubscriberTotal` 27 | - `OnSubscriberPoints` 28 | - `OnSubscriberResubSession` 29 | - `OnSubscriberResubLatest` 30 | - `OnSubscriberNewSession` 31 | - `OnSubscriberGiftedSession` 32 | - `OnSubscriberNewLatest` 33 | - `OnSubscriberAlltimeGifter` 34 | - `OnSubscriberGiftedLatest` 35 | 36 | ##### Hosts 37 | - `OnHost` 38 | - `OnHostLatest` 39 | 40 | ##### Followers 41 | - `OnFollower` 42 | - `OnFollowerLatest` 43 | - `OnFollowerGoal` 44 | - `OnFollowerMonth` 45 | - `OnFollowerWeek` 46 | - `OnFollowerTotal` 47 | - `OnFollowerSession` 48 | 49 | ##### Cheers 50 | - `OnCheer` 51 | - `OnCheerLatest` 52 | - `OnCheerGoal` 53 | - `OnCheerCount` 54 | - `OnCheerTotal` 55 | - `OnCheerSession` 56 | - `OnCheerSessionTopDonator` 57 | - `OnCheerSessionTopDonation` 58 | - `OnCheerMonth` 59 | - `OnCheerWeek` 60 | 61 | ### Usage 62 | ``` 63 | var streamElements = new StreamElementsNET.Client(); 64 | 65 | streamElements.OnConnected += StreamElements_OnConnected; 66 | streamElements.OnAuthenticated += StreamElements_OnAuthenticated; 67 | streamElements.OnFollower += StreamElements_OnFollower; 68 | streamElements.OnSubscriber += StreamElements_OnSubscriber; 69 | streamElements.OnHost += StreamElements_OnHost; 70 | streamElements.OnTip += StreamElements_OnTip; 71 | streamElements.OnCheer += StreamElements_OnCheer; 72 | streamElements.OnAuthenticationFailure += StreamElements_OnAuthenticationFailure; 73 | streamElements.OnReceivedRawMessage += StreamElements_OnReceivedRawMessage; 74 | streamElements.OnSent += StreamElements_OnSent; 75 | 76 | streamElements.Connect(""); 77 | ``` 78 | 79 | ### Testing 80 | A tests project has been included in this repository to demonstrate basic usage of the library. 81 | 82 | ### NuGet 83 | Available via NuGet: Install-Package [StreamElementNET](https://www.nuget.org/packages/StreamElementsNET/) 84 | 85 | ## Libraries 86 | - Newtonsoft.Json - JSON parsing 87 | - Websocket4net - Websocket client 88 | 89 | ## Contributors 90 | * Cole ([@swiftyspiffy](http://twitter.com/swiftyspiffy)) 91 | 92 | ## License 93 | MIT License. © 2021 Cole -------------------------------------------------------------------------------- /StreamElementsNET/StreamElements.Test/StreamElements.Test.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.329 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StreamElements.Test", "StreamElements.Test\StreamElements.Test.csproj", "{76F0A4D1-0354-4172-BB5E-098772BC0224}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {76F0A4D1-0354-4172-BB5E-098772BC0224}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {76F0A4D1-0354-4172-BB5E-098772BC0224}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {76F0A4D1-0354-4172-BB5E-098772BC0224}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {76F0A4D1-0354-4172-BB5E-098772BC0224}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {0DDC0DAC-B2DE-4B5B-B3EC-D4C2210B9808} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElements.Test/StreamElements.Test/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using StreamElementsNET; 3 | 4 | namespace StreamElements.Test 5 | { 6 | class Program 7 | { 8 | static void Main(string[] args) 9 | { 10 | var token = ""; 11 | var streamElements = new Client(); 12 | 13 | streamElements.OnConnected += StreamElements_OnConnected; 14 | streamElements.OnAuthenticated += StreamElements_OnAuthenticated; 15 | streamElements.OnFollower += StreamElements_OnFollower; 16 | streamElements.OnSubscriber += StreamElements_OnSubscriber; 17 | streamElements.OnHost += StreamElements_OnHost; 18 | streamElements.OnTip += StreamElements_OnTip; 19 | streamElements.OnCheer += StreamElements_OnCheer; 20 | streamElements.OnStoreRedemption += StreamElements_OnStoreRedemption; 21 | streamElements.OnAuthenticationFailure += StreamElements_OnAuthenticationFailure; 22 | streamElements.OnReceivedRawMessage += StreamElements_OnReceivedRawMessage; 23 | streamElements.OnSent += StreamElements_OnSent; 24 | streamElements.OnUnknownSimpleUpdate += StreamElements_OnUnknown; 25 | 26 | streamElements.Connect(token); 27 | 28 | while (true) ; 29 | } 30 | 31 | private static void StreamElements_OnSent(object sender, string e) 32 | { 33 | Console.WriteLine($"SENT: {e}"); 34 | } 35 | 36 | private static void StreamElements_OnReceivedRawMessage(object sender, string e) 37 | { 38 | Console.WriteLine($"RECEIVED: {e}"); 39 | } 40 | 41 | private static void StreamElements_OnAuthenticationFailure(object sender, EventArgs e) 42 | { 43 | Console.WriteLine($"Failed to login! Invalid JWT token!"); 44 | } 45 | 46 | private static void StreamElements_OnCheer(object sender, StreamElementsNET.Models.Cheer.Cheer e) 47 | { 48 | Console.WriteLine($"New cheer! From: {e.Username}, amount: {e.Amount}, message: {e.Message}"); 49 | } 50 | 51 | private static void StreamElements_OnTip(object sender, StreamElementsNET.Models.Tip.Tip e) 52 | { 53 | Console.WriteLine($"New tip! From: {e.Username}, amount: ${e.Amount}, currency: {e.Currency}, message: {e.Message}"); 54 | } 55 | 56 | private static void StreamElements_OnHost(object sender, StreamElementsNET.Models.Host.Host e) 57 | { 58 | Console.WriteLine($"New host! Host from: {e.Username}, viewers: {e.Amount}"); 59 | } 60 | 61 | private static void StreamElements_OnSubscriber(object sender, StreamElementsNET.Models.Subscriber.Subscriber e) 62 | { 63 | Console.WriteLine($"New subscriber! Name: {e.Username}, tier: {e.Tier}, months: {e.Amount}, gifted? {e.Gifted}, gifted by: {e.Sender}"); 64 | } 65 | 66 | private static void StreamElements_OnFollower(object sender, StreamElementsNET.Models.Follower.Follower e) 67 | { 68 | Console.WriteLine($"New follower! Username: {e.Username}, userid: {e.UserId}, display name: {e.DisplayName}, avatar: {e.Avatar}"); 69 | } 70 | 71 | private static void StreamElements_OnAuthenticated(object sender, StreamElementsNET.Models.Internal.Authenticated e) 72 | { 73 | Console.WriteLine($"Authenticated! Using {e.ClientId} in channel {e.ChannelId}"); 74 | } 75 | 76 | private static void StreamElements_OnConnected(object sender, EventArgs e) 77 | { 78 | Console.WriteLine($"Connected!"); 79 | } 80 | 81 | private static void StreamElements_OnStoreRedemption(object sender, StreamElementsNET.Models.Store.StoreRedemption e) 82 | { 83 | Console.WriteLine($"Store redemption: store item {e.StoreItemName} by {e.Username} with message {e.Message}"); 84 | } 85 | 86 | private static void StreamElements_OnUnknown(object sender, StreamElementsNET.Models.Unknown.UnknownEventArgs e) 87 | { 88 | Console.WriteLine($"Unknown event args: {e.Type} - {e.Data}"); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElements.Test/StreamElements.Test/StreamElements.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.329 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StreamElementsNET", "StreamElementsNET\StreamElementsNET.csproj", "{42F5EB0D-3B65-4F6F-988B-AD2AE51C1E9A}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StreamElements.Test", "StreamElements.Test\StreamElements.Test\StreamElements.Test.csproj", "{FB7D70A8-9358-4032-AE11-E6A924A30A62}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {42F5EB0D-3B65-4F6F-988B-AD2AE51C1E9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {42F5EB0D-3B65-4F6F-988B-AD2AE51C1E9A}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {42F5EB0D-3B65-4F6F-988B-AD2AE51C1E9A}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {42F5EB0D-3B65-4F6F-988B-AD2AE51C1E9A}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {FB7D70A8-9358-4032-AE11-E6A924A30A62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {FB7D70A8-9358-4032-AE11-E6A924A30A62}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {FB7D70A8-9358-4032-AE11-E6A924A30A62}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {FB7D70A8-9358-4032-AE11-E6A924A30A62}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {8AFD3005-C647-41AE-8BC1-F9115BA0FD2B} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Client.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System; 3 | using System.Timers; 4 | using StreamElementsNET.Models.Unknown; 5 | using WebSocket4Net; 6 | 7 | namespace StreamElementsNET 8 | { 9 | public class Client 10 | { 11 | private readonly string StreamElementsUrl = "wss://realtime.streamelements.com/socket.io/?cluster=main&EIO=3&transport=websocket"; 12 | 13 | private WebSocket client; 14 | private string token; 15 | private Timer pingTimer; 16 | 17 | public event EventHandler OnConnected; 18 | public event EventHandler OnDisconnected; 19 | public event EventHandler OnError; 20 | public event EventHandler OnSent; 21 | public event EventHandler OnReceivedRawMessage; 22 | 23 | // authentication 24 | public event EventHandler OnAuthenticated; 25 | public event EventHandler OnAuthenticationFailure; 26 | 27 | // follower 28 | public event EventHandler OnFollower; 29 | public event EventHandler OnFollowerLatest; 30 | public event EventHandler OnFollowerGoal; 31 | public event EventHandler OnFollowerMonth; 32 | public event EventHandler OnFollowerWeek; 33 | public event EventHandler OnFollowerTotal; 34 | public event EventHandler OnFollowerSession; 35 | 36 | // cheer 37 | public event EventHandler OnCheer; 38 | public event EventHandler OnCheerLatest; 39 | public event EventHandler OnCheerGoal; 40 | public event EventHandler OnCheerCount; 41 | public event EventHandler OnCheerTotal; 42 | public event EventHandler OnCheerSession; 43 | public event EventHandler OnCheerSessionTopDonator; 44 | public event EventHandler OnCheerSessionTopDonation; 45 | public event EventHandler OnCheerMonth; 46 | public event EventHandler OnCheerWeek; 47 | 48 | // host 49 | public event EventHandler OnHost; 50 | public event EventHandler OnHostLatest; 51 | 52 | // tip 53 | public event EventHandler OnTip; 54 | public event EventHandler OnTipCount; 55 | public event EventHandler OnTipLatest; 56 | public event EventHandler OnTipSession; 57 | public event EventHandler OnTipGoal; 58 | public event EventHandler OnTipWeek; 59 | public event EventHandler OnTipTotal; 60 | public event EventHandler OnTipMonth; 61 | public event EventHandler OnTipSessionTopDonator; 62 | public event EventHandler OnTipSessionTopDonation; 63 | 64 | // subscriber 65 | public event EventHandler OnSubscriber; 66 | public event EventHandler OnSubscriberLatest; 67 | public event EventHandler OnSubscriberSession; 68 | public event EventHandler OnSubscriberGoal; 69 | public event EventHandler OnSubscriberMonth; 70 | public event EventHandler OnSubscriberWeek; 71 | public event EventHandler OnSubscriberTotal; 72 | public event EventHandler OnSubscriberPoints; 73 | public event EventHandler OnSubscriberResubSession; 74 | public event EventHandler OnSubscriberResubLatest; 75 | public event EventHandler OnSubscriberNewSession; 76 | public event EventHandler OnSubscriberGiftedSession; 77 | public event EventHandler OnSubscriberNewLatest; 78 | public event EventHandler OnSubscriberAlltimeGifter; 79 | public event EventHandler OnSubscriberGiftedLatest; 80 | 81 | // store 82 | public event EventHandler OnStoreRedemption; 83 | 84 | // unknowns 85 | public event EventHandler OnUnknownComplexObject; 86 | public event EventHandler OnUnknownSimpleUpdate; 87 | 88 | public Client() 89 | { 90 | client = new WebSocket(StreamElementsUrl); 91 | client.Opened += Client_Opened; 92 | client.Error += Client_Error; 93 | client.Closed += Client_Closed; 94 | client.MessageReceived += Client_MessageReceived; 95 | } 96 | 97 | public void Connect(string jwt) 98 | { 99 | token = jwt; 100 | client.Open(); 101 | } 102 | 103 | public void Disconnect() 104 | { 105 | client.Close(); 106 | } 107 | 108 | public void TestMessageParsing(string message) 109 | { 110 | handleMessage(message); 111 | } 112 | 113 | private void send(string msg) 114 | { 115 | client.Send(msg); 116 | OnSent?.Invoke(client, msg); 117 | } 118 | 119 | private void handleAuthentication() 120 | { 121 | send($"42[\"authenticate\",{{\"method\":\"jwt\",\"token\":\"{token}\"}}]"); 122 | } 123 | 124 | private void handlePingInitialization(Models.Internal.SessionMetadata md) 125 | { 126 | // start with a ping 127 | send("2"); 128 | // start ping timer 129 | pingTimer = new Timer(md.PingInterval); 130 | pingTimer.Elapsed += PingTimer_Elapsed; 131 | pingTimer.Start(); 132 | } 133 | 134 | private void Client_MessageReceived(object sender, MessageReceivedEventArgs e) 135 | { 136 | handleMessage(e.Message); 137 | } 138 | 139 | private void handleMessage(string msg) 140 | { 141 | OnReceivedRawMessage?.Invoke(client, msg); 142 | // there's a number at the start of every message, figure out what it is, and remove it 143 | var raw = msg; 144 | if (raw.Contains("\"")) 145 | { 146 | var number = msg.Split('"')[0].Substring(0, msg.Split('"')[0].Length - 1); 147 | raw = msg.Substring(number.Length); 148 | } 149 | if (msg.StartsWith("40")) 150 | { 151 | handleAuthentication(); 152 | return; 153 | } 154 | if (msg.StartsWith("0{\"sid\"")) 155 | { 156 | handlePingInitialization(Parsing.Internal.handleSessionMetadata(JObject.Parse(raw))); 157 | } 158 | if (msg.StartsWith("42[\"authenticated\"")) 159 | { 160 | OnAuthenticated?.Invoke(client, Parsing.Internal.handleAuthenticated(JArray.Parse(raw))); 161 | return; 162 | } 163 | if (msg.StartsWith("42[\"unauthorized\"")) 164 | { 165 | OnAuthenticationFailure?.Invoke(client, null); 166 | } 167 | if (msg.StartsWith("42[\"event\",{\"type\"")) 168 | { 169 | handleComplexObject(JArray.Parse(raw)); 170 | return; 171 | } 172 | if (msg.StartsWith("42[\"event:update\",{\"name\"")) 173 | { 174 | handleSimpleUpdate(JArray.Parse(raw)); 175 | return; 176 | } 177 | } 178 | 179 | private void handleComplexObject(JArray decoded) 180 | { 181 | var objectType = decoded[0]?.ToString() ?? string.Empty; 182 | if (objectType != "event") { return; } 183 | 184 | var eventPayload = decoded[1]; 185 | if(eventPayload == null) { return; } 186 | 187 | var provider = eventPayload["provider"]?.ToString() ?? string.Empty; 188 | if (provider != "twitch") { return;} 189 | 190 | var eventType = eventPayload["type"]?.ToString() ?? string.Empty; 191 | var eventData = eventPayload["data"]; 192 | 193 | switch (eventType) 194 | { 195 | case "follow": 196 | OnFollower?.Invoke(client, Parsing.Follower.handleFollower(eventData)); 197 | return; 198 | case "cheer": 199 | OnCheer?.Invoke(client, Parsing.Cheer.handleCheer(eventData)); 200 | return; 201 | case "host": 202 | OnHost?.Invoke(client, Parsing.Host.handleHost(eventData)); 203 | return; 204 | case "tip": 205 | OnTip?.Invoke(client, Parsing.Tip.handleTip(eventData)); 206 | return; 207 | case "subscriber": 208 | OnSubscriber?.Invoke(client, Parsing.Subscriber.handleSubscriber(eventData)); 209 | return; 210 | default: 211 | OnUnknownComplexObject?.Invoke(client, new UnknownEventArgs(eventType, eventData)); 212 | return; 213 | } 214 | } 215 | 216 | private void handleSimpleUpdate(JArray decoded) 217 | { 218 | // only handle "event:update" types 219 | if (decoded[0].ToString() != "event:update") 220 | return; 221 | 222 | var eventPayload = decoded[1]; 223 | if(eventPayload == null) { return; } 224 | 225 | var data = eventPayload["data"]; 226 | var type = eventPayload["name"]?.ToString() ?? string.Empty; 227 | 228 | switch (type) 229 | { 230 | case "follower-latest": 231 | OnFollowerLatest?.Invoke(client, Parsing.Follower.handleFollowerLatest(data)); 232 | return; 233 | case "follower-goal": 234 | OnFollowerGoal?.Invoke(client, Parsing.Follower.handleFollowerGoal(data)); 235 | return; 236 | case "follower-month": 237 | OnFollowerMonth?.Invoke(client, Parsing.Follower.handleFollowerMonth(data)); 238 | return; 239 | case "follower-week": 240 | OnFollowerWeek?.Invoke(client, Parsing.Follower.handleFollowerWeek(data)); 241 | return; 242 | case "follower-total": 243 | OnFollowerTotal?.Invoke(client, Parsing.Follower.handleFollowerTotal(data)); 244 | return; 245 | case "follower-session": 246 | OnFollowerSession?.Invoke(client, Parsing.Follower.handleFollowerSession(data)); 247 | return; 248 | case "cheer-latest": 249 | OnCheerLatest?.Invoke(client, Parsing.Cheer.handleCheerLatest(data)); 250 | return; 251 | case "cheer-goal": 252 | OnCheerGoal?.Invoke(client, Parsing.Cheer.handleCheerGoal(data)); 253 | return; 254 | case "cheer-count": 255 | OnCheerCount?.Invoke(client, Parsing.Cheer.handleCheerCount(data)); 256 | return; 257 | case "cheer-total": 258 | OnCheerTotal?.Invoke(client, Parsing.Cheer.handleCheerTotal(data)); 259 | return; 260 | case "cheer-session": 261 | OnCheerSession?.Invoke(client, Parsing.Cheer.handleCheerSession(data)); 262 | return; 263 | case "cheer-session-top-donator": 264 | OnCheerSessionTopDonator?.Invoke(client, Parsing.Cheer.handleCheerSessionTopDonator(data)); 265 | return; 266 | case "cheer-session-top-donation": 267 | OnCheerSessionTopDonation?.Invoke(client, Parsing.Cheer.handleCheerSessionTopDonation(data)); 268 | return; 269 | case "cheer-month": 270 | OnCheerMonth?.Invoke(client, Parsing.Cheer.handleCheerMonth(data)); 271 | return; 272 | case "cheer-week": 273 | OnCheerWeek?.Invoke(client, Parsing.Cheer.handleCheerWeek(data)); 274 | return; 275 | case "host-latest": 276 | OnHostLatest?.Invoke(client, Parsing.Host.handleHostLatest(data)); 277 | return; 278 | case "tip-count": 279 | OnTipCount?.Invoke(client, Parsing.Tip.handleTipCount(data)); 280 | return; 281 | case "tip-latest": 282 | OnTipLatest?.Invoke(client, Parsing.Tip.handleTipLatest(data)); 283 | return; 284 | case "tip-session": 285 | OnTipSession?.Invoke(client, Parsing.Tip.handleTipSession(data)); 286 | return; 287 | case "tip-goal": 288 | OnTipGoal?.Invoke(client, Parsing.Tip.handleTipGoal(data)); 289 | return; 290 | case "tip-week": 291 | OnTipWeek?.Invoke(client, Parsing.Tip.handleTipWeek(data)); 292 | return; 293 | case "tip-total": 294 | OnTipTotal?.Invoke(client, Parsing.Tip.handleTipTotal(data)); 295 | return; 296 | case "tip-month": 297 | OnTipMonth?.Invoke(client, Parsing.Tip.handleTipMonth(data)); 298 | return; 299 | case "tip-session-top-donator": 300 | OnTipSessionTopDonator?.Invoke(client, Parsing.Tip.handleTipSessionTopDonator(data)); 301 | return; 302 | case "tip-session-top-donation": 303 | OnTipSessionTopDonation?.Invoke(client, Parsing.Tip.handleTipSessionTopDonation(data)); 304 | return; 305 | case "subscriber-latest": 306 | OnSubscriberLatest?.Invoke(client, Parsing.Subscriber.handleSubscriberLatest(data)); 307 | return; 308 | case "subscriber-session": 309 | OnSubscriberSession?.Invoke(client, Parsing.Subscriber.handleSubscriberSession(data)); 310 | return; 311 | case "subscriber-goal": 312 | OnSubscriberGoal?.Invoke(client, Parsing.Subscriber.handleSubscriberGoal(data)); 313 | return; 314 | case "subscriber-month": 315 | OnSubscriberMonth?.Invoke(client, Parsing.Subscriber.handleSubscriberMonth(data)); 316 | return; 317 | case "subscriber-week": 318 | OnSubscriberWeek?.Invoke(client, Parsing.Subscriber.handleSubscriberWeek(data)); 319 | return; 320 | case "subscriber-total": 321 | OnSubscriberTotal?.Invoke(client, Parsing.Subscriber.handleSubscriberTotal(data)); 322 | return; 323 | case "subscriber-points": 324 | OnSubscriberPoints?.Invoke(client, Parsing.Subscriber.handleSubscriberPoints(data)); 325 | return; 326 | case "subscriber-resub-session": 327 | OnSubscriberResubSession?.Invoke(client, Parsing.Subscriber.handleSubscriberResubSession(data)); 328 | return; 329 | case "subscriber-resub-latest": 330 | OnSubscriberResubLatest?.Invoke(client, Parsing.Subscriber.handleSubscriberResubLatest(data)); 331 | return; 332 | case "subscriber-new-session": 333 | OnSubscriberNewSession?.Invoke(client, Parsing.Subscriber.handleSubscriberNewSession(data)); 334 | return; 335 | case "subscriber-gifted-session": 336 | OnSubscriberGiftedSession?.Invoke(client, Parsing.Subscriber.handleSubscriberGiftedSession(data)); 337 | return; 338 | case "subscriber-new-latest": 339 | OnSubscriberNewLatest?.Invoke(client, Parsing.Subscriber.handleSubscriberNewLatest(data)); 340 | return; 341 | case "subscriber-alltime-gifter": 342 | OnSubscriberAlltimeGifter?.Invoke(client, Parsing.Subscriber.handleSubscriberAlltimeGifter(data)); 343 | return; 344 | case "subscriber-gifted-latest": 345 | OnSubscriberGiftedLatest?.Invoke(client, Parsing.Subscriber.handleSubscriberGiftedLatest(data)); 346 | return; 347 | case "redemption-latest": 348 | OnStoreRedemption?.Invoke(client, Parsing.StoreRedemption.handleStoreRedemption(data)); 349 | return; 350 | default: 351 | OnUnknownSimpleUpdate?.Invoke(client, new UnknownEventArgs(type, decoded[1]["data"])); 352 | return; 353 | } 354 | } 355 | 356 | private void Client_Closed(object sender, EventArgs e) 357 | { 358 | pingTimer.Stop(); 359 | OnDisconnected?.Invoke(sender, e); 360 | } 361 | 362 | private void Client_Error(object sender, SuperSocket.ClientEngine.ErrorEventArgs e) 363 | { 364 | OnError?.Invoke(sender, e); 365 | } 366 | 367 | private void Client_Opened(object sender, EventArgs e) 368 | { 369 | OnConnected?.Invoke(sender, e); 370 | } 371 | 372 | private void PingTimer_Elapsed(object sender, ElapsedEventArgs e) 373 | { 374 | // to remain connected, we need to send a "2" every 25 seconds 375 | send("2"); 376 | } 377 | } 378 | } 379 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Cheer/Cheer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Cheer 8 | { 9 | public class Cheer 10 | { 11 | public string Username { get; } 12 | public string UserId { get; } 13 | public string DisplayName { get; } 14 | public int Amount { get; } 15 | public string Message { get; } 16 | public string Avatar { get; } 17 | 18 | public Cheer(string username, string userId, string displayName, int amount, string message, string avatar) 19 | { 20 | Username = username; 21 | UserId = userId; 22 | Amount = amount; 23 | Message = message; 24 | Avatar = avatar; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Cheer/CheerLatest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Cheer 8 | { 9 | public class CheerLatest 10 | { 11 | public string Name { get; } 12 | public int Amount { get; } 13 | public string Message { get; } 14 | 15 | public CheerLatest(string name, int amount, string message) 16 | { 17 | Name = name; 18 | Amount = amount; 19 | Message = message; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Cheer/CheerSessionTopDonation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Cheer 8 | { 9 | public class CheerSessionTopDonation 10 | { 11 | public string Name { get; } 12 | public int Amount { get; } 13 | public string Message { get; } 14 | 15 | public CheerSessionTopDonation(string name, int amount, string message) 16 | { 17 | Name = name; 18 | Amount = amount; 19 | Message = message; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Cheer/CheerSessionTopDonator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Cheer 8 | { 9 | public class CheerSessionTopDonator 10 | { 11 | public string Name { get; } 12 | public int Amount { get; } 13 | 14 | public CheerSessionTopDonator(string name, int amount) 15 | { 16 | Name = name; 17 | Amount = amount; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Follower/Follower.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Follower 8 | { 9 | public class Follower 10 | { 11 | public string Username { get; } 12 | public string UserId { get; } 13 | public string DisplayName { get; } 14 | public string Avatar { get; } 15 | 16 | public Follower(string username, string userId, string displayName, string avatar) 17 | { 18 | Username = username; 19 | UserId = userId; 20 | DisplayName = displayName; 21 | Avatar = avatar; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Host/Host.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Host 8 | { 9 | public class Host 10 | { 11 | public string Username { get; } 12 | public string UserId { get; } 13 | public string DisplayName { get; } 14 | public int Amount { get; } 15 | public string Avatar { get; } 16 | 17 | public Host(string username, string userId, string displayName, int amount, string avatar) 18 | { 19 | Username = username; 20 | UserId = userId; 21 | DisplayName = displayName; 22 | Amount = amount; 23 | Avatar = avatar; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Host/HostLatest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Host 8 | { 9 | public class HostLatest 10 | { 11 | public string Name { get; } 12 | public int Amount { get; } 13 | 14 | public HostLatest(string name, int amount) 15 | { 16 | Name = name; 17 | Amount = amount; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Internal/Authenticated.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Internal 8 | { 9 | public class Authenticated 10 | { 11 | public string ClientId { get; } 12 | public string ChannelId { get; } 13 | 14 | public Authenticated(string clientId, string channelId) 15 | { 16 | ClientId = clientId; 17 | ChannelId = channelId; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Internal/SessionMetadata.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Internal 8 | { 9 | public class SessionMetadata 10 | { 11 | public string SID { get; } 12 | public int PingInterval { get; } 13 | public int PingTimeout { get; } 14 | 15 | public SessionMetadata(string sid, int pingInterval, int pingTimeout) 16 | { 17 | SID = sid; 18 | PingInterval = pingInterval; 19 | PingTimeout = pingTimeout; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Store/StoreRedemption.cs: -------------------------------------------------------------------------------- 1 | namespace StreamElementsNET.Models.Store 2 | { 3 | public class StoreRedemption 4 | { 5 | public string ItemId { get; } 6 | public string Username { get; } 7 | public string Type { get; } 8 | public string StoreItemName { get; } 9 | public string Message { get; } 10 | 11 | public StoreRedemption(string itemId, string username, string type, string storeItemName, string message) 12 | { 13 | ItemId = itemId; 14 | Username = username; 15 | Type = type; 16 | StoreItemName = storeItemName; 17 | Message = message; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Subscriber/Subscriber.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Subscriber 8 | { 9 | public class Subscriber 10 | { 11 | public string Username { get; } 12 | public string UserId { get; } 13 | public string DisplayName { get; } 14 | public int Amount { get; } 15 | public string Tier { get; } 16 | public bool Gifted { get; } 17 | public string Sender { get; } 18 | public string Message { get; } 19 | public string Avatar { get; } 20 | 21 | public Subscriber(string username, string userid, string displayName, int amount, string tier, bool gifted, string sender, string message, string avatar) 22 | { 23 | Username = username; 24 | UserId = userid; 25 | DisplayName = displayName; 26 | Amount = amount; 27 | Tier = tier; 28 | Gifted = gifted; 29 | Sender = sender; 30 | Message = message; 31 | Avatar = avatar; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Subscriber/SubscriberAlltimeGifter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Subscriber 8 | { 9 | public class SubscriberAlltimeGifter 10 | { 11 | public string Name { get; } 12 | public int Amount { get; } 13 | 14 | public SubscriberAlltimeGifter(string name, int amount) 15 | { 16 | Name = name; 17 | Amount = amount; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Subscriber/SubscriberGiftedLatest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Subscriber 8 | { 9 | public class SubscriberGiftedLatest 10 | { 11 | public string Name { get; } 12 | public int Amount { get; } 13 | public string Sender { get; } 14 | public string Tier { get; } 15 | public string Message { get; } 16 | 17 | public SubscriberGiftedLatest(string name, int amount, string sender, string tier, string message) 18 | { 19 | Name = name; 20 | Amount = amount; 21 | Sender = sender; 22 | Tier = tier; 23 | Message = message; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Subscriber/SubscriberLatest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Subscriber 8 | { 9 | public class SubscriberLatest 10 | { 11 | public string Name { get; } 12 | public int Amount { get; } 13 | public string Tier { get; } 14 | public string Message { get; } 15 | public bool Gifted { get; } 16 | public string Sender { get; } 17 | 18 | public SubscriberLatest(string name, int amount, string tier, string message, bool gifted, string sender) 19 | { 20 | Name = name; 21 | Amount = amount; 22 | Tier = tier; 23 | Message = message; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Subscriber/SubscriberNewLatest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Subscriber 8 | { 9 | public class SubscriberNewLatest 10 | { 11 | public string Name { get; } 12 | public int Amount { get; } 13 | public string Message { get; } 14 | 15 | public SubscriberNewLatest(string name, int amount, string message) 16 | { 17 | Name = name; 18 | Amount = amount; 19 | Message = message; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Subscriber/SubscriberResubLatest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Subscriber 8 | { 9 | public class SubscriberResubLatest 10 | { 11 | public string Name { get; } 12 | public int Amount { get; } 13 | public string Message { get; } 14 | 15 | public SubscriberResubLatest(string name, int amount, string message) 16 | { 17 | Name = name; 18 | Amount = amount; 19 | Message = message; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Tip/Tip.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Tip 8 | { 9 | public class Tip 10 | { 11 | public string TipId { get; } 12 | public string Username { get; } 13 | public double Amount { get; } 14 | public string Currency { get; } 15 | public string Message { get; } 16 | public string Avatar { get; } 17 | 18 | public Tip(string tipId, string username, double amount, string currency, string message, string avatar) 19 | { 20 | TipId = tipId; 21 | Username = username; 22 | Amount = amount; 23 | Currency = currency; 24 | Message = message; 25 | Avatar = avatar; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Tip/TipLatest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Tip 8 | { 9 | public class TipLatest 10 | { 11 | public string Name { get; } 12 | public double Amount { get; } 13 | public string Message { get; } 14 | 15 | public TipLatest(string name, double amount, string message) 16 | { 17 | Name = name; 18 | Amount = amount; 19 | Message = message; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Tip/TipSessionTopDonation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Tip 8 | { 9 | public class TipSessionTopDonation 10 | { 11 | public string Name { get; } 12 | public double Amount { get; } 13 | 14 | public TipSessionTopDonation(string name, double amount) 15 | { 16 | Name = name; 17 | Amount = amount; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Tip/TipSessionTopDonator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace StreamElementsNET.Models.Tip 8 | { 9 | public class TipSessionTopDonator 10 | { 11 | public string Name { get; } 12 | public double Amount { get; } 13 | 14 | public TipSessionTopDonator(string name, double amount) 15 | { 16 | Name = name; 17 | Amount = amount; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Models/Unknown/UnknownEventArgs.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | 3 | namespace StreamElementsNET.Models.Unknown 4 | { 5 | public class UnknownEventArgs 6 | { 7 | public string Type { get; } 8 | public JToken Data { get; } 9 | 10 | public UnknownEventArgs(string type, JToken data) 11 | { 12 | Type = type; 13 | Data = data; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Parsing/Cheer.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace StreamElementsNET.Parsing 7 | { 8 | internal static class Cheer 9 | { 10 | public static Models.Cheer.Cheer handleCheer(JToken json) 11 | { 12 | return new Models.Cheer.Cheer(json["username"].ToString(), json["providerId"].ToString(), json["displayName"].ToString(), int.Parse(json["amount"].ToString()), json["message"].ToString(), json["avatar"].ToString()); 13 | } 14 | 15 | public static Models.Cheer.CheerLatest handleCheerLatest(JToken json) 16 | { 17 | return new Models.Cheer.CheerLatest(json["name"].ToString(), int.Parse(json["amount"].ToString()), json["message"].ToString()); 18 | } 19 | 20 | public static int handleCheerGoal(JToken json) 21 | { 22 | return int.Parse(json["amount"].ToString()); 23 | } 24 | 25 | public static int handleCheerCount(JToken json) 26 | { 27 | return int.Parse(json["count"].ToString()); 28 | } 29 | 30 | public static int handleCheerTotal(JToken json) 31 | { 32 | return int.Parse(json["amount"].ToString()); 33 | } 34 | 35 | public static int handleCheerSession(JToken json) 36 | { 37 | return int.Parse(json["amount"].ToString()); 38 | } 39 | 40 | public static Models.Cheer.CheerSessionTopDonator handleCheerSessionTopDonator(JToken json) 41 | { 42 | return new Models.Cheer.CheerSessionTopDonator(json["name"].ToString(), int.Parse(json["amount"].ToString())); 43 | } 44 | 45 | public static Models.Cheer.CheerSessionTopDonation handleCheerSessionTopDonation(JToken json) 46 | { 47 | return new Models.Cheer.CheerSessionTopDonation(json["name"].ToString(), int.Parse(json["amount"].ToString()), json["message"].ToString()); 48 | } 49 | 50 | public static int handleCheerMonth(JToken json) 51 | { 52 | return int.Parse(json["amount"].ToString()); 53 | } 54 | 55 | public static int handleCheerWeek(JToken json) 56 | { 57 | return int.Parse(json["amount"].ToString()); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Parsing/Follower.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace StreamElementsNET.Parsing 7 | { 8 | internal static class Follower 9 | { 10 | public static Models.Follower.Follower handleFollower(JToken json) 11 | { 12 | return new Models.Follower.Follower(json["username"].ToString(), json["providerId"].ToString(), json["displayName"].ToString(), json["avatar"].ToString()); 13 | } 14 | 15 | public static string handleFollowerLatest(JToken json) 16 | { 17 | return json["name"].ToString(); 18 | } 19 | 20 | public static int handleFollowerGoal(JToken json) 21 | { 22 | return int.Parse(json["amount"].ToString()); 23 | } 24 | 25 | public static int handleFollowerMonth(JToken json) 26 | { 27 | return int.Parse(json["count"].ToString()); 28 | } 29 | 30 | public static int handleFollowerWeek(JToken json) 31 | { 32 | return int.Parse(json["count"].ToString()); 33 | } 34 | 35 | public static int handleFollowerTotal(JToken json) 36 | { 37 | return int.Parse(json["count"].ToString()); 38 | } 39 | 40 | public static int handleFollowerSession(JToken json) 41 | { 42 | return int.Parse(json["count"].ToString()); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Parsing/Host.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace StreamElementsNET.Parsing 7 | { 8 | internal static class Host 9 | { 10 | public static Models.Host.Host handleHost(JToken json) 11 | { 12 | return new Models.Host.Host(json["username"].ToString(), json["providerId"].ToString(), json["displayName"].ToString(), int.Parse(json["amount"].ToString()), json["avatar"].ToString()); 13 | } 14 | 15 | public static Models.Host.HostLatest handleHostLatest(JToken json) 16 | { 17 | return new Models.Host.HostLatest(json["name"].ToString(), int.Parse(json["amount"].ToString())); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Parsing/Internal.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace StreamElementsNET.Parsing 7 | { 8 | internal static class Internal 9 | { 10 | public static Models.Internal.Authenticated handleAuthenticated(JArray json) 11 | { 12 | //["authenticated",{"clientId":"nmccwgA5DoIqh9ZYAAqx","channelId":"59b84223a291f04c810bce21","project":"realtime","message":"You are in a maze of dank memes, all alike."}] 13 | return new Models.Internal.Authenticated(json[1]["clientId"].ToString(), json[1]["channelId"].ToString()); 14 | } 15 | 16 | public static Models.Internal.SessionMetadata handleSessionMetadata(JToken json) 17 | { 18 | //{"sid":"Xa70GYsr_HrF3DbQAgUW","upgrades":[],"pingInterval":25000,"pingTimeout":5000} 19 | return new Models.Internal.SessionMetadata(json["sid"].ToString(), int.Parse(json["pingInterval"].ToString()), int.Parse(json["pingTimeout"].ToString())); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Parsing/StoreRedemption.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | 3 | namespace StreamElementsNET.Parsing 4 | { 5 | public static class StoreRedemption 6 | { 7 | public static Models.Store.StoreRedemption handleStoreRedemption(JToken json) 8 | { 9 | return new Models.Store.StoreRedemption(json["itemId"].ToString(), json["name"].ToString(), 10 | json["type"].ToString(), json["item"].ToString(), json["message"]?.ToString() ?? string.Empty); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Parsing/Subscriber.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace StreamElementsNET.Parsing 7 | { 8 | internal static class Subscriber 9 | { 10 | public static Models.Subscriber.Subscriber handleSubscriber(JToken json) 11 | { 12 | var gifted = json["gifted"] != null; 13 | var sender = json["sender"] != null ? json["sender"].ToString() : ""; 14 | var message = json["message"] != null ? json["message"].ToString() : ""; 15 | return new Models.Subscriber.Subscriber(json["username"].ToString(), json["providerId"].ToString(), json["displayName"].ToString(), 16 | int.Parse(json["amount"].ToString()), json["tier"].ToString(), gifted, sender, message, json["avatar"].ToString()); 17 | } 18 | 19 | public static Models.Subscriber.SubscriberLatest handleSubscriberLatest(JToken json) 20 | { 21 | var gifted = json["gifted"] != null; 22 | var sender = json["sender"] != null ? json["sender"].ToString() : ""; 23 | var message = json["message"] != null ? json["message"].ToString() : ""; 24 | return new Models.Subscriber.SubscriberLatest(json["name"].ToString(), int.Parse(json["amount"].ToString()), json["tier"].ToString(), message, gifted, sender); 25 | } 26 | 27 | public static int handleSubscriberSession(JToken json) 28 | { 29 | return int.Parse(json["count"].ToString()); 30 | } 31 | 32 | public static int handleSubscriberGoal(JToken json) 33 | { 34 | return int.Parse(json["amount"].ToString()); 35 | } 36 | 37 | public static int handleSubscriberMonth(JToken json) 38 | { 39 | return int.Parse(json["count"].ToString()); 40 | } 41 | 42 | public static int handleSubscriberWeek(JToken json) 43 | { 44 | return int.Parse(json["count"].ToString()); 45 | } 46 | 47 | public static int handleSubscriberTotal(JToken json) 48 | { 49 | return int.Parse(json["count"].ToString()); 50 | } 51 | 52 | public static int handleSubscriberPoints(JToken json) 53 | { 54 | return int.Parse(json["amount"].ToString()); 55 | } 56 | 57 | public static int handleSubscriberResubSession(JToken json) 58 | { 59 | return int.Parse(json["count"].ToString()); 60 | } 61 | 62 | public static Models.Subscriber.SubscriberResubLatest handleSubscriberResubLatest(JToken json) 63 | { 64 | var message = json["message"] != null ? json["message"].ToString() : ""; 65 | return new Models.Subscriber.SubscriberResubLatest(json["name"].ToString(), int.Parse(json["amount"].ToString()), message); 66 | } 67 | 68 | public static int handleSubscriberNewSession(JToken json) 69 | { 70 | return int.Parse(json["count"].ToString()); 71 | } 72 | 73 | public static int handleSubscriberGiftedSession(JToken json) 74 | { 75 | return int.Parse(json["count"].ToString()); 76 | } 77 | 78 | public static Models.Subscriber.SubscriberNewLatest handleSubscriberNewLatest(JToken json) 79 | { 80 | return new Models.Subscriber.SubscriberNewLatest(json["name"].ToString(), int.Parse(json["amount"].ToString()), json["message"].ToString()); 81 | } 82 | 83 | public static Models.Subscriber.SubscriberAlltimeGifter handleSubscriberAlltimeGifter(JToken json) 84 | { 85 | return new Models.Subscriber.SubscriberAlltimeGifter(json["name"].ToString(), int.Parse(json["amount"].ToString())); 86 | } 87 | 88 | public static Models.Subscriber.SubscriberGiftedLatest handleSubscriberGiftedLatest(JToken json) 89 | { 90 | return new Models.Subscriber.SubscriberGiftedLatest(json["name"].ToString(), int.Parse(json["amount"].ToString()), json["sender"].ToString(), json["tier"].ToString(), json["message"].ToString()); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/Parsing/Tip.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace StreamElementsNET.Parsing 7 | { 8 | internal static class Tip 9 | { 10 | public static Models.Tip.Tip handleTip(JToken json) 11 | { 12 | return new Models.Tip.Tip(json["tipId"].ToString(), json["username"].ToString(), double.Parse(json["amount"].ToString()), json["currency"].ToString(), json["message"].ToString(), json["avatar"].ToString()); 13 | } 14 | 15 | public static int handleTipCount(JToken json) 16 | { 17 | return int.Parse(json["count"].ToString()); 18 | } 19 | 20 | public static Models.Tip.TipLatest handleTipLatest(JToken json) 21 | { 22 | return new Models.Tip.TipLatest(json["name"].ToString(), double.Parse(json["amount"].ToString()), json["message"].ToString()); 23 | } 24 | 25 | public static double handleTipSession(JToken json) 26 | { 27 | return double.Parse(json["amount"].ToString()); 28 | } 29 | 30 | public static double handleTipGoal(JToken json) 31 | { 32 | return double.Parse(json["amount"].ToString()); 33 | } 34 | 35 | public static double handleTipWeek(JToken json) 36 | { 37 | return double.Parse(json["amount"].ToString()); 38 | } 39 | 40 | public static double handleTipTotal(JToken json) 41 | { 42 | return double.Parse(json["amount"].ToString()); 43 | } 44 | 45 | public static double handleTipMonth(JToken json) 46 | { 47 | return double.Parse(json["amount"].ToString()); 48 | } 49 | 50 | public static Models.Tip.TipSessionTopDonator handleTipSessionTopDonator(JToken json) 51 | { 52 | return new Models.Tip.TipSessionTopDonator(json["name"].ToString(), double.Parse(json["amount"].ToString())); 53 | } 54 | 55 | public static Models.Tip.TipSessionTopDonation handleTipSessionTopDonation(JToken json) 56 | { 57 | return new Models.Tip.TipSessionTopDonation(json["name"].ToString(), double.Parse(json["amount"].ToString())); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /StreamElementsNET/StreamElementsNET/StreamElementsNET.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | .netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | --------------------------------------------------------------------------------