diff --git a/Common/Constants.cs b/Common/Constants.cs
index 2a256cd..bc4de73 100644
--- a/Common/Constants.cs
+++ b/Common/Constants.cs
@@ -1,6 +1,6 @@
namespace YTLiveChat.Common
{
- public class Constants
+ internal class Constants
{
public const string YTBaseUrl = "https://www.youtube.com";
diff --git a/Contracts/Models/Author.cs b/Contracts/Models/Author.cs
index 317c0b5..3cec028 100644
--- a/Contracts/Models/Author.cs
+++ b/Contracts/Models/Author.cs
@@ -1,17 +1,45 @@
namespace YTLiveChat.Contracts.Models
{
+ ///
+ /// Represents the Author of the message
+ ///
public class Author
{
+ ///
+ /// Public name of the Author
+ ///
public required string Name { get; set; }
+
+ ///
+ /// ImagePart containing the Authors Thumbnail
+ ///
public ImagePart? Thumbnail { get; set; }
+
+ ///
+ /// ChannelId if available
+ ///
public string? ChannelId { get; set; }
+
+ ///
+ /// Current Badge of the Author within the Live Channel
+ ///
public Badge? Badge { get; set; }
}
+ ///
+ /// Badges available on YouTube for Users
+ ///
public class Badge
{
+ ///
+ /// Text representation of the Badge
+ ///
public required string Label { get; set; }
+
+ ///
+ /// ImagePart containing the Badge Thumbnail
+ ///
public ImagePart? Thumbnail { get; set; }
}
}
diff --git a/Contracts/Models/ChatItem.cs b/Contracts/Models/ChatItem.cs
index dfba2a3..9b21fa7 100644
--- a/Contracts/Models/ChatItem.cs
+++ b/Contracts/Models/ChatItem.cs
@@ -1,15 +1,53 @@
namespace YTLiveChat.Contracts.Models
{
+ ///
+ /// ChatItem containing the full object with any MessageParts and Author details
+ ///
public class ChatItem
{
+ ///
+ /// Unique Identifier
+ ///
public required string Id { get; set; }
+
+ ///
+ /// Author of the ChatItem
+ ///
public required Author Author { get; set; }
+
+ ///
+ /// Array of all message parts (Image, Text or Emoji variant)
+ ///
public required MessagePart[] Message { get; set; }
+
+ ///
+ /// Contains the Superchat if any was given
+ ///
public Superchat? Superchat { get; set; }
+
+ ///
+ /// Whether or not Author has a Membership on the current Live Channel
+ ///
public bool IsMembership { get; set; }
+
+ ///
+ /// Whether or not Author is Verified on YT
+ ///
public bool IsVerified { get; set; }
+
+ ///
+ /// Whether or not Author is Owner of the current Live Channel
+ ///
public bool IsOwner { get; set; }
+
+ ///
+ /// Whether or not Author is a Moderator of the current Live Channel
+ ///
public bool IsModerator { get; set; }
+
+ ///
+ /// Timestamp of the ChatItem creation
+ ///
public DateTime Timestamp { get; set; } = DateTime.Now;
}
}
diff --git a/Contracts/Models/MessagePart.cs b/Contracts/Models/MessagePart.cs
index 9fd23a1..1d7af82 100644
--- a/Contracts/Models/MessagePart.cs
+++ b/Contracts/Models/MessagePart.cs
@@ -1,19 +1,48 @@
namespace YTLiveChat.Contracts.Models
{
+ ///
+ /// Base class for individual message parts
+ ///
public abstract class MessagePart { }
+ ///
+ /// Image variant of a message part
+ ///
public class ImagePart : MessagePart
{
+ ///
+ /// URL of the image
+ ///
public required string Url { get; set; }
+ ///
+ /// Alt string of the image
+ ///
public string? Alt { get; set; }
}
+
+ ///
+ /// Emoji variant of a message part
+ ///
public class EmojiPart : ImagePart
{
+ ///
+ /// Text representation of the emoji
+ ///
public required string EmojiText { get; set; }
+ ///
+ /// Whether or not Emoji is a custom emoji of the channel
+ ///
public bool IsCustomEmoji { get; set; }
};
+
+ ///
+ /// Text variant of a message part
+ ///
public class TextPart : MessagePart
{
+ ///
+ /// Contained text of the message
+ ///
public required string Text { get; set; }
}
}
diff --git a/Contracts/Models/Superchat.cs b/Contracts/Models/Superchat.cs
index 646f12c..245df15 100644
--- a/Contracts/Models/Superchat.cs
+++ b/Contracts/Models/Superchat.cs
@@ -1,9 +1,23 @@
namespace YTLiveChat.Contracts.Models
{
+ ///
+ /// Represents a Superchat
+ ///
public class Superchat
{
+ ///
+ /// Amount of $ gifted
+ ///
public required string Amount { get; set; }
+
+ ///
+ /// Color of Superchat
+ ///
public required string Color { get; set; }
+
+ ///
+ /// If Superchat is a sticker, contains an ImagePart with said Sticker
+ ///
public ImagePart? Sticker { get; set; }
}
}
diff --git a/Contracts/ServiceCollectionExtension.cs b/Contracts/ServiceCollectionExtensions.cs
similarity index 57%
rename from Contracts/ServiceCollectionExtension.cs
rename to Contracts/ServiceCollectionExtensions.cs
index 92af722..2bb144a 100644
--- a/Contracts/ServiceCollectionExtension.cs
+++ b/Contracts/ServiceCollectionExtensions.cs
@@ -5,14 +5,22 @@
namespace YTLiveChat.Contracts
{
- public static class ServiceCollectionExtension
+ ///
+ /// Extensions class
+ ///
+ public static class ServiceCollectionExtensions
{
+ ///
+ /// Adds all relevant services as well as the Service backing IYTLiveChat to the ServiceCollection
+ ///
+ /// IServiceCollection to add the services to
+ /// return IServiceCollection after the services have been added
public static IServiceCollection AddYTLiveChat(this IServiceCollection services)
{
_ = services.AddSingleton();
_ = services.AddHttpClient("YouTubeClient", x => { x.BaseAddress = new Uri(Constants.YTBaseUrl); });
_ = services.AddSingleton();
-
+
return services;
}
}
diff --git a/Contracts/Services/IYTLiveChat.cs b/Contracts/Services/IYTLiveChat.cs
index f56c229..5632d9c 100644
--- a/Contracts/Services/IYTLiveChat.cs
+++ b/Contracts/Services/IYTLiveChat.cs
@@ -2,33 +2,87 @@
namespace YTLiveChat.Contracts.Services
{
+ ///
+ /// Represents the YouTube Live Chat Service
+ ///
public interface IYTLiveChat
{
+ ///
+ /// Fires after the initial Live page was loaded
+ ///
public event EventHandler? InitialPageLoaded;
+
+ ///
+ /// Fires after Chat was stopped
+ ///
public event EventHandler? ChatStopped;
+
+ ///
+ /// Fires when a ChatItem was received
+ ///
public event EventHandler? ChatReceived;
+
+ ///
+ /// Fires on any error from backend or within service
+ ///
public event EventHandler? ErrorOccurred;
+ ///
+ /// Starts the Listeners for the LiveChat and fires InitialPageLoaded when successful. Either , or must be given.
+ ///
+ ///
+ /// This method initially loads the stream page from whatever param was given. If called again, it'll simply register the listeners again, but not load another live stream. If another live stream should be loaded, should be set to true.
+ ///
+ /// The handle of the channel (eg. "@Original151")
+ /// The channelId of the channel (eg. "UCtykdsdm9cBfh5JM8xscA0Q")
+ /// The video ID of the live video (eg. "WZafWA1NVrU")
+ ///
public void Start(string? handle = null, string? channelId = null, string? liveId = null, bool overwrite = false);
+
+ ///
+ /// Stops the listeners
+ ///
public void Stop();
}
+ ///
+ /// EventArgs for InitialPageLoaded event
+ ///
public class InitialPageLoadedEventArgs : EventArgs
{
+ ///
+ /// Video ID selected or found
+ ///
public required string LiveId { get; set; }
}
+ ///
+ /// EventArgs for ChatStopped event
+ ///
public class ChatStoppedEventArgs : EventArgs
{
+ ///
+ /// Reason why the stop occured
+ ///
public string? Reason { get; set; }
}
+ ///
+ /// EventArgs for ChatReceived event
+ ///
public class ChatReceivedEventArgs : EventArgs
{
+ ///
+ /// ChatItem that was received
+ ///
public required ChatItem ChatItem { get; set; }
}
+ ///
+ /// EventArgs for ErrorOccurred event
+ ///
+ /// Exception that triggered the event
public class ErrorOccurredEventArgs(Exception exception) : ErrorEventArgs(exception)
{
}
diff --git a/YTLiveChat.csproj b/YTLiveChat.csproj
index d8f30c7..6b390b0 100644
--- a/YTLiveChat.csproj
+++ b/YTLiveChat.csproj
@@ -1,14 +1,34 @@
+
+
+ Agash Thamo.
+ InnerTube API for YouTube LiveChat to get Live Chat messages without API restrictions. Mainly intended for use in application for the streamer.
+ https://github.com/Agash/YTLiveChat/wiki
+ library, youtube, live-chat, yt, streamer
+ LICENSE.txt
+ README.md
-
- net8.0
- enable
- enable
-
+ Agash.YTLiveChat
+ net8.0
+ enable
+ enable
+ true
+ true
+
-
-
-
-
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ all
+ runtime; build; native; contentfiles; analyzers
+
+
+
+
diff --git a/global.json b/global.json
new file mode 100644
index 0000000..30e28ed
--- /dev/null
+++ b/global.json
@@ -0,0 +1,6 @@
+{
+ "sdk": {
+ "rollForward": "feature",
+ "version": "8.0.204"
+ }
+}
\ No newline at end of file