Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Sunshine And March Vibes (2025 Wallpapers Edition)

      June 1, 2025

      The Case For Minimal WordPress Setups: A Contrarian View On Theme Frameworks

      June 1, 2025

      How To Fix Largest Contentful Paint Issues With Subpart Analysis

      June 1, 2025

      How To Prevent WordPress SQL Injection Attacks

      June 1, 2025

      7 MagSafe accessories that I recommend every iPhone user should have

      June 1, 2025

      I replaced my Kindle with an iPad Mini as my ebook reader – 8 reasons why I don’t regret it

      June 1, 2025

      Windows 11 version 25H2: Everything you need to know about Microsoft’s next OS release

      May 31, 2025

      Elden Ring Nightreign already has a duos Seamless Co-op mod from the creator of the beloved original, and it’ll be “expanded on in the future”

      May 31, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      Student Record Android App using SQLite

      June 1, 2025
      Recent

      Student Record Android App using SQLite

      June 1, 2025

      When Array uses less memory than Uint8Array (in V8)

      June 1, 2025

      Laravel 12 Starter Kits: Definite Guide Which to Choose

      June 1, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      Photobooth is photobooth software for the Raspberry Pi and PC

      June 1, 2025
      Recent

      Photobooth is photobooth software for the Raspberry Pi and PC

      June 1, 2025

      Le notizie minori del mondo GNU/Linux e dintorni della settimana nr 22/2025

      June 1, 2025

      Rilasciata PorteuX 2.1: Novità e Approfondimenti sulla Distribuzione GNU/Linux Portatile Basata su Slackware

      June 1, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»Development»Personalized Optimizely CMS Website Search Experiences Azure AI Search & Personalizer

    Personalized Optimizely CMS Website Search Experiences Azure AI Search & Personalizer

    April 10, 2025
    Personalized Optimizely CMS Website Search Experiences Azure AI Search & Personalizer

    In the last blog, we discussed Integrating the Optimizely CMS website with Azure AI search. Now let’s take a bit more advanced topic to serve Personalization experience with Azure AI search with Azure personalizer. Together, they enable you to serve dynamic customized content and search results across user  behaviour, preferences, and context.

    What is Azure Personalizer?

    Azure Personalizer Cognitive Service for Real-time Association using Reinforcement Learning. It gives you the ability to serve content or experiences that are most relevant to a user — informed by past behaviour and current context.

    Benefits of AI Personalizer:

    • So it can study and evolve as people engage with it.
    • Amazingly helpful for ranking search results.
    • Can customize direct calls to action, highlighted articles, or goods.

    How It Works with Azure AI Search and Optimizely

    1. The user performs a search on your Optimizely site.
    2. Azure AI Search simply gives a  list of matching documents
    3. These documents are sent to Azure Personalizer as “rankable actions.”
    4. The personalized orders results using the context of the user.
    5. Your app serves personalized results and the user’s feedback helps Personalizer to learn & evolve further.

    Set Up Azure Personalizer

    • Navigate to Azure Portal → Personalizer resource creation
    • Save your endpoint and API key.
    • In step 3, specify the Content that you want to be ranked (i.e., search results)

    Integration Code

    Model for Rankable Action

    public class RankableDocument
    {
        public string Id { get; set; }
        public string Title { get; set; }
        public string Summary { get; set; }
        public string Category { get; set; }
    }

    Send Info to Personalizer with Context:

    private object GetUserContext(HttpRequestBase request)
    {
        return new
        {
            timeOfDay = DateTime.Now.Hour,
            device = request.Browser.IsMobileDevice ? "mobile" : "desktop",
            userAgent = request.UserAgent,
            language = request.UserLanguages?.FirstOrDefault() ?? "en"
        };
    }
    public async Task<List<RankableDocument>> GetPersonalizedResultsAsync(List<RankableDocument> documents, string userId)
    {
        var contextFeatures = new[] { GetUserContext(Request) };
    
        var actions = documents.Select(doc => new
        {
            id = doc.Id,
            features = new[]
            {
                new { category = doc.Category },
                new { title = doc.Title }
            }
        });
    
        _eventId = Guid.NewGuid().ToString();
    
        var request = new
        {
            contextFeatures = contextFeatures,
            actions = actions,
            excludedActions = new string[] {},
            eventId = _eventId,
            deferActivation = false
        };
    
        var client = new HttpClient();
        client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "--YOUR API KEY ---");
        var response = await client.PostAsync("--Endpoint--/personalizer/v1.0/rank",
            new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"));
    
        var result = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
        var topActionId = result.RootElement.GetProperty("rewardActionId").GetString();
    
        return documents.OrderByDescending(d => d.Id == topActionId).ToList();
    }

    Now let’s consider our previous example of search page controller & view and extend it

    Search Controller

    public class AzureSearchPageController : PageController<AzureSearchPage>
    {
        private static string _eventId;
    
        public async Task<ActionResult> Index(AzureSearchPage currentPage, string q = "")
        {
            var results = new List<RankableDocument>();
    
            if (!string.IsNullOrEmpty(q))
            {
                var url = $"https://<search-service>.search.windows.net/indexes/<index-name>/docs?api-version=2021-04-30-Preview&search={q}";
                using var client = new HttpClient();
                client.DefaultRequestHeaders.Add("api-key", "<your-query-key>");
                var response = await client.GetStringAsync(url);
    
                var doc = JsonDocument.Parse(response);
                results = doc.RootElement.GetProperty("value")
                    .EnumerateArray()
                    .Select(x => new RankableDocument
                    {
                        Id = x.GetProperty("id").GetString(),
                        Title = x.GetProperty("name").GetString(),
                        Category = x.GetProperty("type").GetString(),
                        Summary = x.GetProperty("content").GetString()
                    }).ToList();
    
                results = await GetPersonalizedResultsAsync(results, "user123");
            }
    
            ViewBag.Results = results;
            ViewBag.Query = q;
            ViewBag.EventId = _eventId;
            return View(currentPage);
        }
    
        [HttpPost]
        public async Task<ActionResult> Reward(string eventId, double rewardScore)
        {
            using var client = new HttpClient();
            client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "<your-api-key>");
    
            var rewardUrl = $"<your-endpoint>/personalizer/v1.0/events/{eventId}/reward";
            var result = await client.PostAsync(rewardUrl, new StringContent(rewardScore.ToString(), Encoding.UTF8, "application/json"));
    
            return Json(new { success = result.IsSuccessStatusCode });
        }
    }

    Search Page View

    @model AzureSearchPage
    <h1>Personalized Search Results</h1>
    <form method="get">
        <input type="text" name="q" value="@ViewBag.Query" placeholder="Search..." />
        <button type="submit">Search</button>
    </form>
    
    <ul>
    @foreach (var result in ViewBag.Results as List<RankableDocument>)
    {
        <li>
            <h4>@result.Title</h4>
            <p>@result.Summary</p>
            <button onclick="sendReward('@ViewBag.EventId', 1.0)">Like</button>
            <button onclick="sendReward('@ViewBag.EventId', 0.0)">Not Relevant</button>
        </li>
    }
    </ul>
    <script>
    function sendReward(eventId, score) {
        fetch('/AzureSearchPage/Reward', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ eventId: eventId, rewardScore: score })
        }).then(r => {
            if (r.ok) alert("Thanks! Your feedback was recorded.");
        });
    }
    </script>

    With Azure AI Search delivering relevant results and Azure Personalizer re-ranking them based on real-time context, your Optimizely site becomes an intelligent experience engine.

    This blog has also been published here.

    Source: Read More 

    Hostinger
    Facebook Twitter Reddit Email Copy Link
    Previous ArticleAgents bring the role of AI in development from reactive to proactive
    Next Article Android Development Codelab: Mastering Advanced Concepts

    Related Posts

    Artificial Intelligence

    Markus Buehler receives 2025 Washington Award

    June 1, 2025
    Artificial Intelligence

    LWiAI Podcast #201 – GPT 4.5, Sonnet 3.7, Grok 3, Phi 4

    June 1, 2025
    Leave A Reply Cancel Reply

    Continue Reading

    Capcom has revealed new framerate and resolution improvements coming to Monster Hunter Wilds’s launch, along with weapon gameplay changes and more

    Development

    The Top 5 WordPress Page Builders Compared

    Web Development

    Containerize .NET 8.0 Web API with Docker

    Development

    Multiple browser support

    Development

    Highlights

    Quick Hit #12

    August 23, 2024

    Giant kudos to Scott Jehl on releasing his new Web Components De-Mystified online course! Eight…

    Researchers at Stanford Propose TRANSIC: A Human-in-the-Loop Method to Handle the Sim-to-Real Transfer of Policies for Contact-Rich Manipulation Tasks

    May 23, 2024

    The best Amazon Fire TV Stick VPNs of 2024: Expert tested and reviewed

    July 3, 2024

    Rilasciato SDL 3.2: Una Versione Stabile con API Migliorate, Documentazione Aggiornata e Nuove Funzionalità

    January 23, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.