For who needs the answer. We can abort the default request and return a custom response by something like code below. My code in this case is abort the default EXM's OpensClicks request and return a custom result that includes some contact facets fields
Create a new pipeline process and patch it after Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel
The process class should be something like that
public class ApiRedirectProcessor : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
if (args.RequestUrl.AbsolutePath.Contains("/sitecore/api/ssc/EXM/OpensClicks"))
{
try
{
args.AbortPipeline();
var messageid = args.HttpContext.Request.Params["messageId"];
var recepientList = GetRecipientList(messageid);
if (recepientList != null && recepientList.Any())
{
var managerRootId = args.HttpContext.Request.Params["managerRootId"];
var pageIndex = int.Parse(args.HttpContext.Request.Params["pageIndex"]);
var pageSize = int.Parse(args.HttpContext.Request.Params["pageSize"]);
var openClickStatisticsService = ServiceLocator.ServiceProvider.GetService<OpenClickStatisticsService>();
MessageDataSourceContext data = new MessageDataSourceContext()
{
MessageId = messageid,
ManagerRootId = managerRootId,
PageIndex = pageIndex,
PageSize = pageSize
};
Task<RecipientActivityResponse> task = System.Threading.Tasks.Task.Run<RecipientActivityResponse>(async () => await openClickStatisticsService.GetResponse(data));
CustomRecipientActivityResponse customResponse = new CustomRecipientActivityResponse(task.Result);
if (customResponse.Items.Any())
{
foreach (var customRecipientActivity in customResponse.Items)
{
var contactInfo = recepientList.FirstOrDefault(x => x.Personal()?.FirstName == customRecipientActivity.FirstName
&& x.Personal()?.LastName == customRecipientActivity.LastName
&& x.Emails()?.PreferredEmail?.SmtpAddress == customRecipientActivity.Email);
if (contactInfo != null)
{
customRecipientActivity.CustomCompany = contactInfo.GetCustom()?.Company;
customRecipientActivity.CustomContactOwner = contactInfo.GetCustom()?.ContactOwner;
}
}
}
args.HttpContext.Response.ContentType = "application/json; charset=utf-8";
args.HttpContext.Response.Output.WriteLine(JsonConvert.SerializeObject(customResponse));
args.HttpContext.Response.End();
}
}
catch (Exception ex)
{
throw ex;
}
}
}
}
public class CustomRecipientActivityResponse : RecipientActivityResponse
{
[JsonProperty("items")]
public List<CustomRecipientActivity> Items { get; set; }
public CustomRecipientActivityResponse(RecipientActivityResponse recipientActivityResponse)
{
if (recipientActivityResponse != null)
{
this.TotalCount = recipientActivityResponse.TotalCount;
List<CustomRecipientActivity> customRecipientActivityList = new List<CustomRecipientActivity>();
if (recipientActivityResponse.Data.Any())
{
foreach (OpenClick item in recipientActivityResponse.Data)
{
customRecipientActivityList.Add(new CustomRecipientActivity(item));
}
}
Items = customRecipientActivityList;
}
}
}
public class CustomRecipientActivity : OpenClick
{
public CustomRecipientActivity(OpenClick recipientActivityModel)
{
if (recipientActivityModel != null)
{
this.FirstName = recipientActivityModel.FirstName;
this.LastName = recipientActivityModel.LastName;
this.Recency = recipientActivityModel.Recency;
this.Email = recipientActivityModel.Email;
this.Date = recipientActivityModel.Date;
this.DateFormatted = recipientActivityModel.DateFormatted;
this.Name = recipientActivityModel.Name;
this.Url = recipientActivityModel.Url;
}
}
[JsonProperty("custom_company")]
public string CustomCompany { get; set; }
[JsonProperty("custom_contactowner")]
public string CustomContactOwner { get; set; }
}