![]() |
VOOZH | about |
dotnet add package Indice.Features.Messages.Core --version 8.49.0
NuGet\Install-Package Indice.Features.Messages.Core -Version 8.49.0
<PackageReference Include="Indice.Features.Messages.Core" Version="8.49.0" />
<PackageVersion Include="Indice.Features.Messages.Core" Version="8.49.0" />Directory.Packages.props
<PackageReference Include="Indice.Features.Messages.Core" />Project file
paket add Indice.Features.Messages.Core --version 8.49.0
#r "nuget: Indice.Features.Messages.Core, 8.49.0"
#:package Indice.Features.Messages.Core@8.49.0
#addin nuget:?package=Indice.Features.Messages.Core&version=8.49.0Install as a Cake Addin
#tool nuget:?package=Indice.Features.Messages.Core&version=8.49.0Install as a Cake Tool
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
To categorize the new template types a new column must be added. This column is not nullable, defaults to 0 (Full template) and all the existing templates should be categorized as Full. <br> Example script:
ALTER TABLE [cmp].[Template]
ADD [Type] TINYINT NOT NULL
CONSTRAINT DF_Template_TemplateType DEFAULT 0;
Note: This example assumes SQLServer.
The following configuration should be added in the appsettings.json and local.settings.json to determine the frequency of the clean up job:
"MessageJobsOptions:DatabaseCleanUpCronExpression": "0 0 2 * * *"
Note: This configuration is required for Azure Worker deployments. For self-hosted workers, this value is used as the default if not specified.
Keep track of the actual recipient (email, phone number, etc) in the MessageEvent table for easier querying and reporting.
-- 1) Add new columns to [cmp].[MessageEvent]
IF NOT EXISTS (
SELECT 1
FROM sys.columns
WHERE Name = N'Recipient' AND Object_ID = Object_ID(N'[cmp].[MessageEvent]')
)
BEGIN
ALTER TABLE [cmp].[MessageEvent]
ADD Recipient NVARCHAR(128),
Title NVARCHAR(128),
Success BIT;
END
GO
-- 2) Update existing records to populate the new Recipient, Title and Success columns
UPDATE [cmp].[MessageEvent]
SET Recipient =
CASE Events.Channel
WHEN 'SMS' THEN ct.PhoneNumber
WHEN 'Email' THEN ct.Email
ELSE COALESCE(ct.RecipientId, '')
END,
Success = 1,
Title = CASE
WHEN Events.Channel = 'SMS' AND msg.Content IS NOT NULL THEN COALESCE(JSON_VALUE(msg.Content, '$.sms.title'), JSON_VALUE(msg.Content, '$.SMS.title'))
WHEN Events.Channel = 'Email' AND msg.Content IS NOT NULL THEN COALESCE(JSON_VALUE(msg.Content, '$.email.title'), JSON_VALUE(msg.Content, '$.Email.title'))
WHEN Events.Channel = 'Inbox' AND msg.Content IS NOT NULL THEN COALESCE(JSON_VALUE(msg.Content, '$.inbox.title'), JSON_VALUE(msg.Content, '$.Inbox.title'))
WHEN msg.Content IS NOT NULL THEN COALESCE(JSON_VALUE(msg.Content, '$.pushNotification.title'), JSON_VALUE(msg.Content, '$.PushNotification.title'))
ELSE '(deleted)'
END
FROM [cmp].[MessageEvent] as Events
INNER JOIN [cmp].Contact as ct
ON Events.ContactId = ct.Id
LEFT JOIN [cmp].Message as msg
ON msg.Id = Events.MessageId
ALTER TABLE [cmp].[Contact]
ADD [LastResolutionDate] [datetimeoffset](7) NULL
GO
ALTER TABLE [cmp].[Contact]
ADD [Resolved] bit NULL
GO
CREATE NONCLUSTERED INDEX [IX_Contact_RecipientId_Resolved]
ON [cmp].[Contact] ([RecipientId] ASC, [Resolved] ASC)
GO
CREATE NONCLUSTERED INDEX [IX_Campaign_CreatedAt]
ON [cmp].[Campaign] ([CreatedAt] ASC)
GO
CREATE NONCLUSTERED INDEX [IX_MessageEvent_Type]
ON [cmp].[MessageEvent] ([Type] ASC)
GO
CREATE NONCLUSTERED INDEX [IX_MessageEvent_Channel]
ON [cmp].[MessageEvent] ([Channel] ASC)
GO
ALTER TABLE [msg].[DistributionList]
ADD [Alias] NVARCHAR (64) NULL
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_DistributionList_Alias]
ON [msg].[DistributionList]([Alias] ASC) WHERE ([Alias] IS NOT NULL);
GO
Add Message type in template table for linking templates to message types and eventually preferences.
ALTER TABLE [#schema#].[Template]
ADD [MessageTypeId] UNIQUEIDENTIFIER
ALTER TABLE [#schema#].[Template] WITH NOCHECK
ADD CONSTRAINT [FK_Template_MessageType_MessageTypeId] FOREIGN KEY ([MessageTypeId]) REFERENCES [msg].[MessageType] ([Id]);
ALTER TABLE [#schema#].[Template] WITH CHECK CHECK CONSTRAINT [FK_Template_MessageType_MessageTypeId];
The following migration script is needed to add the ContactPreference and ContactCommunicationOption tables.
CREATE TABLE [#schema#].[ContactPreference] (
[Id] UNIQUEIDENTIFIER NOT NULL,
[RecipientId] NVARCHAR (64) NOT NULL,
[Locale] NVARCHAR (16) NULL,
[ConsentCommercial] BIT NOT NULL,
[ConsentCommercialDate] DATETIMEOFFSET (7) NULL,
[DefaultChannels] TINYINT NULL,
[UpdatedAt] DATETIMEOFFSET (7) NULL,
CONSTRAINT [PK_ContactPreference] PRIMARY KEY CLUSTERED ([Id] ASC)
);
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_ContactPreference_RecipientId]
ON [#schema#].[ContactPreference]([RecipientId] ASC);
GO
CREATE TABLE [#schema#].[ContactCommunicationOption] (
[ContactPreferenceId] UNIQUEIDENTIFIER NOT NULL,
[MessageTypeId] UNIQUEIDENTIFIER NOT NULL,
[Channels] TINYINT DEFAULT (CONVERT([tinyint],(0))) NOT NULL,
[UpdatedAt] DATETIMEOFFSET (7) NULL,
CONSTRAINT [PK_ContactCommunicationOption] PRIMARY KEY CLUSTERED ([ContactPreferenceId] ASC, [MessageTypeId] ASC),
CONSTRAINT [FK_ContactCommunicationOption_ContactPreference_ContactPreferenceId] FOREIGN KEY ([ContactPreferenceId]) REFERENCES [#schema#].[ContactPreference] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_ContactCommunicationOption_MessageType_MessageTypeId] FOREIGN KEY ([MessageTypeId]) REFERENCES [#schema#].[MessageType] ([Id]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_ContactCommunicationOption_MessageTypeId]
ON [#schema#].[ContactCommunicationOption]([MessageTypeId] ASC);
GO
In case that you have used communication preferences in your project, you need to run the following migration script to populate the CommunicationPreference and CommunicationPreferenceMessageType tables.
CREATE TABLE #TempContactPreference
(
[RecipientId] nvarchar(64) NOT NULL,
[Locale] nvarchar(16) NULL,
[ConsentCommercial] bit NOT NULL DEFAULT(0),
[DefaultChannels] TINYINT NULL
);
INSERT INTO #TempContactPreference
([RecipientId]
,[Locale]
,[ConsentCommercial]
,[DefaultChannels])
SELECT RecipientId, Locale, ConsentCommercial,CommunicationPreferences
FROM (
SELECT RecipientId, Locale, ConsentCommercial,CommunicationPreferences,
row_number() over (partition by RecipientId order by [UpdatedAt] desc) as rn
FROM [msg].[Contact]
WHERE NULLIF(RecipientId,'') IS NOT NULL
) t
WHERE rn = 1
INSERT INTO [msg].[ContactPreference]
([Id]
,[RecipientId]
,[Locale]
,[ConsentCommercial])
SELECT NEWID(), RecipientId, Locale, ConsentCommercial
FROM #TempContactPreference AS CT
WHERE NOT EXISTS (SELECT TOP 1 1 FROM [msg].[ContactPreference] WHERE RecipientId = ct.RecipientId)
DROP TABLE #TempContactPreference
The last step is to drop the prefernece columns from the Contact table.
ALTER TABLE [#schema#].[Contact] DROP COLUMN [CommunicationPreferences], COLUMN [ConsentCommercial], COLUMN [Locale];
media schema in cases db.
CREATE NONCLUSTERED INDEX [IX_MediaFile_FolderId]
ON [media].[MediaFile]([FolderId] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_MediaFile_Name]
ON [media].[MediaFile]([Name] ASC);
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_MediaFile_Path]
ON [media].[MediaFile]([Path] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_MediaFolder_Name]
ON [media].[MediaFolder]([Name] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_MediaFolder_ParentId]
ON [media].[MediaFolder]([ParentId] ASC);
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_MediaFolder_Path]
ON [media].[MediaFolder]([Path] ASC);
GO
messaging schema in cases db.
CREATE NONCLUSTERED INDEX [IX_Campaign_AttachmentId]
ON [#Schema#].[Campaign]([AttachmentId] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_Campaign_DistributionListId]
ON [#Schema#].[Campaign]([DistributionListId] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_Campaign_TypeId]
ON [#Schema#].[Campaign]([TypeId] ASC);
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_Contact_RecipientId]
ON [#Schema#].[Contact]([RecipientId] ASC) WHERE ([RecipientId] IS NOT NULL);
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_Contact_RecipientId]
ON [#Schema#].[Contact]([RecipientId] ASC) WHERE ([RecipientId] IS NOT NULL);
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_DistributionList_Name]
ON [#Schema#].[DistributionList]([Name] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_DistributionListContact_DistributionListId]
ON [#Schema#].[DistributionListContact]([DistributionListId] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_Hit_CampaignId]
ON [#Schema#].[Hit]([CampaignId] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_Message_CampaignId]
ON [#Schema#].[Message]([CampaignId] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_Message_RecipientId]
ON [#Schema#].[Message]([RecipientId] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_MessageSender_Sender]
ON [#Schema#].[MessageSender]([Sender] ASC);
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_MessageType_Alias]
ON [#Schema#].[MessageType]([Alias] ASC) WHERE ([Alias] IS NOT NULL);
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_MessageType_Name]
ON [#Schema#].[MessageType]([Name] ASC);
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_Template_Alias]
ON [#Schema#].[Template]([Alias] ASC) WHERE ([Alias] IS NOT NULL);
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_Template_Name]
ON [#Schema#].[Template]([Name] ASC);
GO
CREATE TABLE [#Schema#].[MessageEvent](
[Id] [uniqueidentifier] NOT NULL,
[CampaignId] [uniqueidentifier] NOT NULL,
[ContactId] [uniqueidentifier] NOT NULL,
[MessageId] [uniqueidentifier] NULL,
[Type] [nvarchar](64) NOT NULL,
[Channel] [nvarchar](64) NOT NULL,
[CreatedOn] [datetimeoffset](7) NOT NULL,
CONSTRAINT [PK_MessageEvent] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [#Schema#].[Campaign]
ADD IgnoreUserPreferences BIT DEFAULT(0) NOT NULL;
GO
ALTER TABLE [#Schema#].[Contact]
ADD
CommunicationPreferences TINYINT DEFAULT(0) NOT NULL,
ConsentCommercial BIT DEFAULT(0) NOT NULL,
Locale VARCHAR(16);
GO
ALTER TABLE [#Schema#].[DistributionListContact]
ADD Unsubscribed BIT DEFAULT(0) NOT NULL;
GO
ALTER TABLE [#Schema#].[Template]
ADD IgnoreUserPreferences BIT DEFAULT(0) NOT NULL;
GO
ALTER TABLE [#Schema#].[MessageType]
ADD Classification TINYINT DEFAULT(0) NOT NULL;
GO
ALTER TABLE [cmp].[Template]
ADD [Data] [nvarchar](max) NULL
GO
MediaBaseHref in DbCampaignALTER TABLE [cmp].[Campaign]
ADD [MediaBaseHref] [nvarchar](1024) NULL
DbMessageSenderCREATE TABLE [dbo].[MessageSender](
[Id] [uniqueidentifier] NOT NULL,
[Sender] [nvarchar](max) NULL,
[DisplayName] [nvarchar](max) NULL,
[Kind] [tinyint] NOT NULL,
[IsDefault] [bit] NOT NULL,
[CreatedBy] [nvarchar](max) NULL,
[CreatedAt] [datetimeoffset](7) NOT NULL,
[UpdatedBy] [nvarchar](max) NULL,
[UpdatedAt] [datetimeoffset](7) NULL,
CONSTRAINT [PK_MessageSender] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 is compatible. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
Showing the top 5 NuGet packages that depend on Indice.Features.Messages.Core:
| Package | Downloads |
|---|---|
|
Indice.Features.Messages.AspNetCore
Package Description |
|
|
Indice.Features.Messages.Worker.Azure
Package Description |
|
|
Indice.Features.Messages.Worker
Package Description |
|
|
Indice.Hive.Core
Package Description |
|
|
Indice.Hive.Server
Package Description |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 8.49.0 | 302 | 6/5/2026 |
| 8.48.1 | 269 | 6/2/2026 |
| 8.48.0 | 181 | 5/28/2026 |
| 8.47.3 | 198 | 5/26/2026 |
| 8.47.1 | 339 | 5/22/2026 |
| 8.47.0 | 335 | 5/14/2026 |
| 8.47.0-rc06 | 156 | 5/15/2026 |
| 8.47.0-rc05 | 154 | 5/14/2026 |
| 8.47.0-rc04 | 147 | 5/14/2026 |
| 8.47.0-rc03 | 165 | 5/14/2026 |
| 8.47.0-rc02 | 150 | 5/14/2026 |
| 8.47.0-rc01 | 158 | 5/13/2026 |
| 8.46.0 | 718 | 5/5/2026 |
| 8.45.0 | 290 | 4/30/2026 |
| 8.44.0 | 652 | 4/24/2026 |
| 8.43.2 | 355 | 4/20/2026 |
| 8.43.1 | 247 | 4/15/2026 |
| 8.43.0 | 207 | 4/8/2026 |
| 8.42.1 | 200 | 4/6/2026 |
| 8.42.0 | 214 | 3/30/2026 |