diff --git a/.gitignore b/.gitignore index 9647281..5b65492 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ /logs /App.config *.user +/VoiceChannelGrabber.csproj.user diff --git a/Config.cs b/Config.cs index f220a35..5c21d6b 100644 --- a/Config.cs +++ b/Config.cs @@ -2,12 +2,18 @@ namespace VoiceChannelGrabber { public class Config { - public string SceneName { get; set; } + public string SceneName { get; set; } = string.Empty; - public string SourceName { get; set; } + public string SourceName { get; set; } = string.Empty; - public string WebsocketAddress { get; set; } + public string WebsocketAddress { get; set; } = string.Empty; - public string WebsocketPassword { get; set; } + public string WebsocketPassword { get; set; } = string.Empty; + + public string ClientID { get; set; } = string.Empty; + + public string ClientSecret { get; set; } = string.Empty; + + public string RedirectUri { get; set; } = "http://localhost:3000/callback"; } } \ No newline at end of file diff --git a/Program.cs b/Program.cs index bf2d1a7..12ecc85 100644 --- a/Program.cs +++ b/Program.cs @@ -14,7 +14,6 @@ using OBSWebsocketDotNet.Communication; using Serilog; using Serilog.Sinks.SystemConsole.Themes; -using static Dec.DiscordIPC.Entities.Sticker; namespace VoiceChannelGrabber { @@ -83,18 +82,30 @@ static async Task MainAsync() } else { - Config = new Config{ - WebsocketAddress = "", - WebsocketPassword = "", - SceneName = "", - SourceName = "" - }; + Config = new Config(); // Get configuration settings... Console.WriteLine("Moin!"); Console.WriteLine("Let's do some configuration stuff together. Great fun times... ;-)"); Console.WriteLine(); + Console.Write("Do you have your own private Discord app with Client ID and Client secret? ([N]/Y) "); + var hasDiscordAppAnser = Console.ReadLine(); + if (hasDiscordAppAnser.ToLower() == "y") + { + Console.Write("Enter your Discord Client ID: "); + Config.ClientID = Console.ReadLine(); + Console.Write("Enter your Discord Client Secret: "); + Config.ClientSecret = Console.ReadLine(); + Console.Write("Enter the app's Redirect URI e.g. http://localhost:3000/callback: "); + Config.RedirectUri = Console.ReadLine(); + } + else + { + Log.Logger.Warning("Please make sure you are member of the app tester list! Otherwise this thing doesn't work..."); + Log.Logger.Information("Please have a look here how to join the beta: https://github.com/dichternebel/voice-channel-grabber#joining-the-public-beta"); + Console.WriteLine(); + } Console.Write("Enter the OBS scene name where the Browser Source is in: "); Config.SceneName = Console.ReadLine(); Console.Write("Enter the name of the Browser Source: "); @@ -114,7 +125,7 @@ static async Task MainAsync() // ...and write them to file using FileStream createStream = File.Create(configFile); - await JsonSerializer.SerializeAsync(createStream, Config); + await JsonSerializer.SerializeAsync(createStream, Config, new JsonSerializerOptions { WriteIndented = true }); await createStream.DisposeAsync(); Console.WriteLine(); @@ -123,8 +134,16 @@ static async Task MainAsync() Console.Clear(); } - clientID = ConfigurationManager.AppSettings["ClientID"]; - clientSecret = ConfigurationManager.AppSettings["ClientSecret"]; + if (string.IsNullOrEmpty(Config.ClientID) || string.IsNullOrEmpty(Config.ClientSecret)) + { + clientID = ConfigurationManager.AppSettings["ClientID"]; + clientSecret = ConfigurationManager.AppSettings["ClientSecret"]; + } + else + { + clientID = Config.ClientID; + clientSecret = Config.ClientSecret; + } var token = string.Empty; @@ -136,7 +155,7 @@ static async Task MainAsync() if (!File.Exists(tokenJsonFile)) { //Authorize - await AuthorizeAndAuthenticateDiscord(); + await AuthorizeAndAuthenticateDiscord(Config.RedirectUri); } else { @@ -159,7 +178,7 @@ static async Task MainAsync() ); using FileStream createStream = File.Create(tokenJsonFile); - await JsonSerializer.SerializeAsync(createStream, authResponse); + await JsonSerializer.SerializeAsync(createStream, authResponse, new JsonSerializerOptions { WriteIndented = true }); await createStream.DisposeAsync(); AccessToken = authResponse.AccessToken; @@ -176,7 +195,7 @@ await client.SendCommandAsync(new Authenticate.Args() catch (Exception ex) { Log.Logger.Error(ex.Message); - await AuthorizeAndAuthenticateDiscord(); + await AuthorizeAndAuthenticateDiscord(Config.RedirectUri); } } @@ -186,7 +205,7 @@ await client.SendCommandAsync(new Authenticate.Args() // Initialize and start timer var progress = new Progress((ex) => { - // handle exception from timercallback + // ToDo: handle exception from timercallback throw ex; //if (ex is OBSWebsocketDotNet.ErrorResponseException) //{ @@ -357,7 +376,7 @@ private static async Task WaitForDiscordClient() } } - private static async Task AuthorizeAndAuthenticateDiscord() + private static async Task AuthorizeAndAuthenticateDiscord(string redirectUri) { //Authorize string code; @@ -377,12 +396,12 @@ private static async Task AuthorizeAndAuthenticateDiscord() AuthUri = "https://discord.com/api/oauth2/authorize", AccessTokenUri = "https://discord.com/api/oauth2/token" }, - "http://127.0.0.1", + redirectUri, code ); using FileStream createStream = File.Create(tokenJsonFile); - await JsonSerializer.SerializeAsync(createStream, authResponse); + await JsonSerializer.SerializeAsync(createStream, authResponse, new JsonSerializerOptions { WriteIndented = true }); await createStream.DisposeAsync(); await client.SendCommandAsync(new Authenticate.Args() diff --git a/README.md b/README.md index f6dc3e5..63d6c08 100644 --- a/README.md +++ b/README.md @@ -40,42 +40,35 @@ So the idea was to be able to synchronize the `Discord StreamKit URL` with the c https://streamkit.discord.com/overlay/voice/{guildId}/{channelId}?icon=true&online=true&logo=white ``` -And long story short: the final result is this git repository. :-D - -## Ok, sick! What do I need to get this thing? - -Well, unfortunately Discord is still limiting the usage of the underlying technology called `"RPC"` or `"IPC"`: +But unfortunately Discord is still limiting the usage of the underlying technology called `"RPC"` or `"IPC"`: ![RPC limitation](assets/discord-rpc-limitation.png) > source: https://discord.com/developers/docs/topics/rpc -So there are currently only two possibilities: -1. Ask to join the public Beta I'm starting right now or -2. build and run this thing on your own +With the help of [DiscordIPC](https://github.com/dcdeepesh/DiscordIPC) I managed to build something that is actually working and the final result is this git repository. -### Joining the public Beta +## Ok, sick! What do I need to get this thing? -I am able to offer up to 50 seats to people wanting to test-drive this thing. This should be more than enough for my range of influence that is 4.42 on average! KEKW! +Just download the current version from the [release section](https://github.com/dichternebel/voice-channel-grabber/releases). -So just [join my discord](https://discord.gg/4WFudUV6sm) and ask me, I will add you to the list of testers. +Now after downloading there are currently two possibilities: +1. Ask me to join the app tester list +2. Run this thing on your own with your private Discord app ClientID. -But please only ask for joining this public Beta if you really want to use this for streaming! Also please fulfill all prerequisites prior joining: +### Joining the app tester list -- You are using `OBS on Windows` -- You are using the `Discord Client for Windows` (not the Browser-App!) -- You have already installed the [obs-websocket extension](https://github.com/obsproject/obs-websocket/) for OBS -- You have [StreamKit Discord Overlay](https://streamkit.discord.com/overlay) authorized in Discord and already successfully used it with a `Browser Source in OBS` -- You have an idea why this could be useful for streamers -- Most important: You are no asshole! +I am able to offer up to 50 seats to people wanting to test-drive this thing. -You will get a download link for the console application that synchronizes Discord with OBS. Please keep in mind, that this thing must run as long as you use OBS! +So just [join my discord](https://discord.gg/4WFudUV6sm) and ask me, I will add you to the list of app testers. Once you are on the list you may use this without any limitation whatsoever. -### Building this -It's developed with Visual Studio 2019, but should also be compilable in VS Code. +### Use your own private Discord app + +Go to the [discord developer portal](https://discord.com/developers/applications) and add a `private application` with Redirect URI to `http://localhost:3000/callback`. This thing is not working for apps associated to a team due to the RPC limitations mentioned above resulting in OAuth2 scope errors. -After building the code all you have to do is go to the [discord developer portal](https://discord.com/developers/applications) and add a `private application`. This thing is not working for apps associated to a team due to the RPC limitations mentioned above resulting in OAuth2 scope errors. +### Building this +It's developed starting with Visual Studio 2019 and now v2022, but should also be compilable in VS Code. -Rename the `app.config.example` to `app.config` and paste your client id and client secret into the settings. If you prefer like me a single file application, hit the publish functionality in Visual Studio. That should be it! +Rename the `app.config.example` to `app.config` and paste your client id and client secret into the settings. Make sure you have set up a Redirect URI in your Discord app to `http://localhost:3000/callback`. If you prefer like me a single file application, hit the publish functionality in Visual Studio. That should be it! diff --git a/VoiceChannelGrabber.csproj b/VoiceChannelGrabber.csproj index c2de9cd..eb8e65a 100644 --- a/VoiceChannelGrabber.csproj +++ b/VoiceChannelGrabber.csproj @@ -6,9 +6,9 @@ VoiceChannelGrabber DichterNebe1.ico AnyCPU;x64 - 1.0.1 - 1.0.1.0 - 1.0.1.0 + 1.1.0 + 1.1.0.0 + 1.1.0.0 true dichternebel VoiceChannelGrabber diff --git a/VoiceChannelGrabber.csproj.user b/VoiceChannelGrabber.csproj.user index 156754e..6e2ce59 100644 --- a/VoiceChannelGrabber.csproj.user +++ b/VoiceChannelGrabber.csproj.user @@ -1,6 +1,6 @@  - <_LastSelectedProfileId>D:\Git\voice-channel-grabber\Properties\PublishProfiles\FolderProfile.pubxml + <_LastSelectedProfileId>D:\git\voice-channel-grabber\Properties\PublishProfiles\FolderProfile.pubxml \ No newline at end of file