Repository navigation
Releases: Nacorpio/Signal.NET
Release list
Signal.NET 0.5.0-preview.1
Milestone 0.5 (command system 2.0). Every change is binary-compatible with 0.4.0-preview.1: new members on existing
interfaces are default interface members, and new registration helpers are extension methods.
Added
- Command groups (roadmap 0.5.1):
[CommandGroup("playlist", Aliases = ["pl"])]on a module orICommandclass makes its commands/playlist add,/pl add, and so on. Module preconditions apply to the whole group.CommandDescriptor.Group(CommandGroupInfo) andFullName;ICommandRegistry.GetGroup(default interface member)./groupalone, or with an unknown subcommand, replies with the group's commands./help groupdescribes a group.
- Prompts (roadmap 0.5.2):
BackgroundWork.PromptAsync(question)andPromptAsync<T>(anyIParsable<T>, re-asking on invalid input) wait for the triggering sender's next message in the conversation, and return aPromptResult<T>(Answered,TimedOut,Invalid).- The host routes answers through the new
IPromptRegistrybefore partitioning. Commands (by the conversation's own prefixes) are never consumed as answers. - New option
Signal:Background:PromptTimeout(2 minutes).BackgroundWork.SenderandBackgroundWorkItem.Senderidentify who may answer.
- The host routes answers through the new
- Background work (roadmap 0.5.3):
CommandModule.RunInBackgroundAsync(work => …)(orMessageContext.QueueBackgroundWorkAsync, orIBackgroundWorkQueue) runs slow work outside the conversation partition, so later messages aren't held up.- Each item runs in its own DI scope and can reply to the original conversation with
work.ReplyAsync. - The queue is bounded and in memory, configured by
Signal:Background:MaxConcurrency(4) andCapacity(100).AddSignalhosts the processor (IBackgroundWorkProcessor). - At shutdown, running work is cancelled and queued items are dropped with a warning.
- Each item runs in its own DI scope and can reply to the original conversation with
- Scheduled messages (roadmap 0.5.4):
CommandModule.ScheduleReplyAsync/MessageContext.ScheduleReplyAsyncandIMessageScheduler(ScheduleAsync,ListAsync,CancelAsync) send text messages later, once or everyrepeatEvery(at least one minute).IScheduledMessageStoreis the persistence port; the default keeps messages in memory.AddSignalhosts the dispatcher, which checks everySignal:Scheduler:PollInterval(1 s) and retries failed sends afterRetryDelay(1 min).- After downtime, a recurring message sends one catch-up, not one per missed occurrence.
- Localisation (roadmap 0.5.5): every text the framework sends (errors, usage, help, precondition failures, prompt re-asks) goes through the new
ISignalTexts, with keys inTextKey.- Translations go under
Signal:Localization:Texts:{culture}:{key}. Lookup falls backde-AT→de→ English. - The culture is the conversation's
ConversationSettings.Culture, otherwiseLocalization:DefaultCulture. Cultures are plain names, so this works in invariant-globalization mode too. - Argument type names are translated via
Type.{English name}. Custom preconditions can useFail(context, key, args), andMessageContext.GetCultureAsync()exposes the culture. - English output is unchanged.
- Translations go under
- Roles (roadmap 0.5.6):
[RequireRole("moderator", Role.GroupAdmin)]passes when the sender has any listed role.- Roles come from
IRoleProviders:Signal:Commands:Roles(role → numbers or UUIDs),admin(includesCommands:Admins) andgroup-admin(Signal group admins, looked up live). AddRoleProvider<T>()adds your own provider, e.g. database-backed.IRoleServicechecks roles outside commands.
- Roles come from
- Per-conversation settings (roadmap 0.5.7):
ConversationSettingsper group or direct chat:Prefixes(replace the global ones there),DisabledCommands(full or group names) andCulture.- Stored through the new
IConversationSettingsStoreport (in memory by default) and read once per message viaMessageContext.GetConversationSettingsAsync(). - Disabled commands reply with
Commands:DisabledCommandMessage, and help and suggestions hide them. ICommandParser.TryParse(text, prefixes, …)is a new default interface member.
- Stored through the new
- Better help (roadmap 0.5.8):
/helplists commands under headings for each command group and[Category("…")](a flat list when there's only one section). It pages byCommands:HelpPageSize(default 20;/help 2)./help <command>shows[Example("…")]s.CommandDescriptor.CategoryandExamplesdescribe them. - "Did you mean …?" (roadmap 0.5.9): unknown-command replies suggest the closest visible command, alias, group or subcommand (
/hlep→ "Did you mean /help?"). Adjacent swaps count as one typo. Controlled byCommands:SuggestSimilarCommands(defaulttrue). - Collection parameters (roadmap 0.5.10):
params int[] numbers,List<PhoneNumber> people,IReadOnlyList<string> tags, and other array, list or collection-interface parameters take all remaining positional arguments, each converted (and@mention-resolved) individually.CommandParameter.ElementTypeandIsCollectiondescribe them. - Reaction commands (roadmap 0.5.11):
ReactionModulemethods with[OnReaction("👍")]run when someone reacts to the bot's messages (or any message withAnyMessage, removals withIncludeRemovals).- Emojis match regardless of skin tone and variation selector.
- Registered with
AddReactionModule<T>()orAddCommands(assembly); invalid handler signatures fail at registration.
Changed
- Cooldowns, usage lines, logs and
CommandDescriptor.ToString()use the full command name (playlist add). Nothing changes for commands outside a group. /helptakes the rest of the text, so/help playlist addworks.
What's Changed
- Validate against the 0.4.0-preview.1 baseline by @Nacorpio in #31
- Remove stray PublicAPI.Shipped.txt.new files by @Nacorpio in #32
- Add command groups and subcommands (0.5.1) by @Nacorpio in #33
- Suggest the closest command on typos (0.5.9) by @Nacorpio in #34
- Bind collection parameters from remaining arguments (0.5.10) by @Nacorpio in #35
- Improve help: sections, paging and examples (0.5.8) by @Nacorpio in #36
- Run slow command work in the background (0.5.3) by @Nacorpio in #37
- Add prompts to background work (0.5.2) by @Nacorpio in #38
- Add scheduled messages (0.5.4) by @Nacorpio in #39
- Add role-based permissions (0.5.6) by @Nacorpio in #40
- Add per-conversation settings (0.5.7) by @Nacorpio in #41
- Localise framework replies (0.5.5) by @Nacorpio in #42
- Add reaction commands (0.5.11) by @Nacorpio in #43
- Release v0.5.0-preview.1 by @Nacorpio in #44
Full Changelog: v0.4.0-preview.1...v0.5.0-preview.1
Signal.NET 0.4.0-preview.1
Milestone 0.4 (richer incoming model). Every change is binary-compatible with 0.3.0-preview.1. New
EnvelopeContent cases raise compiler warnings in exhaustive switches, and a few behaviors changed (see below).
Added
- Sync messages (roadmap 0.4.1):
EnvelopeContenthas a new case,SentTranscript, for messages the account sent from its other devices, raising the newMessageSentevent.IncomingEnvelope.Conversationis the transcript's destination. Transcripts never run commands. They are delivered only withAccessControl:IgnoreOwnMessages = false, so the default behavior is unchanged. - Edits, remote deletes and received stickers (roadmap 0.4.2, 0.4.3, 0.4.4):
EnvelopeContenthas a new case,EditMessage(edited message's timestamp plus the new version), raising the newMessageEditedevent. Edits never run commands.DataMessage.RemoteDeleteraises the newMessageDeletedevent.DataMessage.Stickercarries received stickers.
- Stories (roadmap 0.4.5):
EnvelopeContenthas a new case,StoryMessage(file or text, optional group,AllowsReplies), raising the newStoryReceivedevent. Opt-in viaReceive:IgnoreStories = false. - Calls (roadmap 0.4.6):
EnvelopeContenthas a new case,CallMessage(CallEventKindoffer, answer, busy or hangup;CallId;IsVideofor offers), raising the newCallReceivedevent. - Mention-aware binding (roadmap 0.4.7): a positional command argument that is an
@mentionbinds as the mentioned user's phone number (or UUID if hidden), so/kick @Bobworks withRecipient,PhoneNumberandAccountIdparameters. A placeholder without a matching mention fails withCould not resolve the @mention for <name>.Before, it would have been accepted as a username. - Received text styles (roadmap 0.4.8):
DataMessage.TextStyleslists the sender's formatting asStyledRange(TextStyle, Start, Length). - Group update context (roadmap 0.4.9):
GroupUpdatedhasNameandRevision, and every group message exposesDataMessage.GroupNameandGroupRevision. Signal doesn't report what changed; compare revisions or fetch the group to find out.
Changed
Receive:IgnoreStoriesis now enforced in the WebSocket (json-rpc*) modes too. Before, it was only passed to the API when polling.- Exhaustive
switches overEnvelopeContentnow produce a warning until they handleEditMessage,SentTranscript,StoryMessageandCallMessage. This is source-compatible and binary-compatible. - Sticker-only messages now raise
MessageReceived(they were dropped before).DataMessage.HasContentistruefor them, whileTextisnull.
What's Changed
- Validate against the 0.3.0-preview.1 baseline by @Nacorpio in #24
- Model received edits, remote deletes and stickers (0.4.2-0.4.4) by @Nacorpio in #25
- Model sent transcripts from other devices (0.4.1) by @Nacorpio in #26
- Bind @mentions and map received text styles (0.4.7, 0.4.8) by @Nacorpio in #27
- Model received stories and call events (0.4.5, 0.4.6) by @Nacorpio in #28
- Carry group name and revision on group updates (0.4.9) by @Nacorpio in #29
- Release v0.4.0-preview.1 by @Nacorpio in #30
Full Changelog: v0.3.0-preview.1...v0.4.0-preview.1
Signal.NET 0.3.0-preview.1
Milestone 0.3 (complete API coverage). Every change is additive: members added to existing interfaces have default
implementations, so code written against 0.2.0-preview.2 keeps compiling.
Added
-
Typed capabilities (roadmap 0.3.13):
SignalCapability(withSendQuotesandSendMentions),SignalApiInfo.SupportsandSignalApiInfo.EnsureSupported. The latter throws aNotSupportedExceptionnaming the missing feature and the API version. -
Group extras, contact sync and number search (roadmap 0.3.8, 0.3.9, 0.3.10):
- New
IGroupServicemembers:JoinAsync(accept an invitation),BlockAsync,UpdateSettingsAsync(GroupPermissions,GroupLinkMode, disappearing-messages timer),PinMessageAsyncandUnpinMessageAsync. - New
IContactServicemembers:SyncAsyncsends contacts to linked devices;CheckRegisteredAsyncreports which numbers are registered with Signal. - All are default interface members, so existing implementations keep compiling.
- New
-
Stickers and link previews (roadmap 0.3.6, 0.3.7):
OutgoingMessageBuilder.WithStickersends a sticker. The newStickervalue object parsespackId:stickerIdand binds as a command argument.- The new
IStickerServicelists and installs sticker packs, by id and key or from asignal.artshare link. OutgoingMessageBuilder.WithLinkPreviewattaches a preview card.Build()rejects previews whose URL isn't in the text, and stickers combined with attachments.
-
Device management (roadmap 0.3.2):
- The new
IDeviceServicelists (LinkedDevice), links and removes the devices of an account registered in the container. IAccountService.GetLinkUriAsyncreturns the rawsgnl://linkdeviceURI, so you can render your own QR code. It's a default interface member.
- The new
-
Account management (roadmap 0.3.3, 0.3.4, 0.3.11): new
IAccountServicemembers:SetUsernameAsyncandDeleteUsernameAsync;UpdateSettingsAsync(discoverability, number sharing);SetPinAsyncandRemovePinAsyncfor the registration lock;SubmitRateLimitChallengeAsyncto lift a rate limit with a captcha.
They are default interface members, so existing implementations keep compiling.
-
Registration and verification (roadmap 0.3.1):
- The new
IRegistrationServiceregisters a number as the container's primary device (RegisterAsyncby SMS or voice, with an optional captcha). VerifyAsynccompletes the registration with the received code and an optional registration-lock PIN.UnregisterAsyncremoves the number again.- Calls are never retried, so no duplicate verification codes are sent.
- The new
-
Remote delete (roadmap 0.3.5):
IMessageSender.RemoteDeleteAsyncdeletes a sent message for everyone, identified by itsSendResult.Timestamp. It's a default interface member, so existingIMessageSenderimplementations keep compiling. -
Streaming attachment downloads (roadmap 0.3.12):
IAttachmentService.OpenReadAsyncreturns anAttachmentDownloadwhose stream reads directly from the HTTP response, with content type and length. It's a default interface member, so existingIAttachmentServiceimplementations keep compiling. -
Release workflow: waits until every package is listed on nuget.org before creating the GitHub Release (roadmap 0.2.8).
-
Package validation: compares against the published
0.2.0-preview.2baseline, so breaking API changes faildotnet pack.
What's Changed
- Verify packages are listed on nuget.org before announcing a release by @Nacorpio in #13
- Stream attachment downloads (roadmap 0.3.12) by @Nacorpio in #14
- Add remote delete of sent messages (roadmap 0.3.5) by @Nacorpio in #15
- Add number registration and verification (roadmap 0.3.1) by @Nacorpio in #16
- Fix remaining race in WebSocket reconnect test by @Nacorpio in #17
- Add account management: username, settings, PIN, rate-limit challenge by @Nacorpio in #18
- Add device management (0.3.2) by @Nacorpio in #19
- Add stickers and link previews (0.3.6, 0.3.7) by @Nacorpio in #20
- Add group extras, contact sync and number search (0.3.8-0.3.10) by @Nacorpio in #21
- Add typed capability checks (0.3.13) by @Nacorpio in #22
- Release v0.3.0-preview.1 by @Nacorpio in #23
Full Changelog: v0.2.0-preview.2...v0.3.0-preview.1
Signal.NET 0.2.0-preview.2
First release on nuget.org, under the new Nacorpio.Signal.* package IDs.
Changed
- NuGet package IDs are now owner-prefixed:
Nacorpio.Signal.Domain,Nacorpio.Signal.Application,Nacorpio.Signal.InfrastructureandNacorpio.Signal.Hosting.- The template package is now
Nacorpio.Signal.Templates. - The
Signal.ID prefix is reserved by another owner on nuget.org, so the 0.2.0-preview.1 packages were never published. - Assembly names and namespaces are unchanged.
- Release workflow: a rejected nuget.org push now fails the release instead of being skipped as a duplicate.
What's Changed
- Publish under owner-prefixed Nacorpio.Signal.* package IDs by @Nacorpio in #11
- Update roadmap to the project's current state by @Nacorpio in #10
- Prepare release 0.2.0-preview.2 by @Nacorpio in #12
Full Changelog: v0.2.0-preview.1...v0.2.0-preview.2
Signal.NET 0.2.0-preview.1
First preview release.
Added
-
Release process (roadmap 0.2):
- A tag-driven release workflow (NuGet via Trusted Publishing, then a GitHub Release).
- MinVer versioning from git tags.
- Public API tracking with
PublicAPI.*.txt. - Package validation.
- Coverage summaries in CI.
- A DocFX documentation site on GitHub Pages.
- The
Signal.NET.Templatespackage with adotnet new signalbottemplate.
-
Layers:
Signal.Domain: value objects, theIncomingEnvelopeaggregate,OutgoingMessagebuilder, entities and domain events.Signal.Application: ports, options with validation, the message pipeline with built-in middleware, and domain event dispatching.Signal.Infrastructure: REST adapters for every endpoint group, a source-generated JSON contract, the resilience pipeline, and polling and WebSocket receivers.Signal.Hosting:AddSignal(),ISignalBuilder, the partitionedSignalHostedServiceand a health check.
-
Text command system: module and class commands, lambda commands, typed argument binding, flags, preconditions, cooldowns and generated help.
-
Execution modes: support for all four container modes (
normal,native,json-rpc,json-rpc-native), with startup mode verification. -
C# 15 unions:
Recipient,EnvelopeContent,CommandResult,ArgumentBindingResult. -
Documentation: full XML documentation (enforced by the build) and the
docs/guides. -
Repository: sample bot, Docker Compose file, CI workflow for GitHub Actions.
What's Changed
- Add release readiness tooling (roadmap milestone 0.2) by @Nacorpio in #6
- Move to .NET 11 RC1 SDK and fix grouped Microsoft.Extensions bump by @Nacorpio in #7
- Bump coverlet.collector and 2 others by @dependabot[bot] in #5
- Bump actions/upload-artifact from 4 to 7 by @dependabot[bot] in #3
- Bump actions/checkout from 4 to 7 by @dependabot[bot] in #2
- Bump actions/setup-dotnet from 4 to 6 by @dependabot[bot] in #1
- Publish to nuget.org with Trusted Publishing instead of an API key by @Nacorpio in #8
- Prepare release 0.2.0-preview.1 by @Nacorpio in #9
New Contributors
- @Nacorpio made their first contribution in #6
- @dependabot[bot] made their first contribution in #5
Full Changelog: https://github.com/Nacorpio/Signal.NET/commits/v0.2.0-preview.1