Name: Towards AI Legal Name: Towards AI, Inc. Description: Towards AI is the world's leading artificial intelligence (AI) and technology publication. Read by thought-leaders and decision-makers around the world. Phone Number: +1-650-246-9381 Email: pub@towardsai.net
228 Park Avenue South New York, NY 10003 United States
Website: Publisher: https://towardsai.net/#publisher Diversity Policy: https://towardsai.net/about Ethics Policy: https://towardsai.net/about Masthead: https://towardsai.net/about
Name: Towards AI Legal Name: Towards AI, Inc. Description: Towards AI is the world's leading artificial intelligence (AI) and technology publication. Founders: Roberto Iriondo, , Job Title: Co-founder and Advisor Works for: Towards AI, Inc. Follow Roberto: X, LinkedIn, GitHub, Google Scholar, Towards AI Profile, Medium, ML@CMU, FreeCodeCamp, Crunchbase, Bloomberg, Roberto Iriondo, Generative AI Lab, Generative AI Lab Denis Piffaretti, Job Title: Co-founder Works for: Towards AI, Inc. Louie Peters, Job Title: Co-founder Works for: Towards AI, Inc. Louis-François Bouchard, Job Title: Co-founder Works for: Towards AI, Inc. Cover:
Towards AI Cover
Logo:
Towards AI Logo
Areas Served: Worldwide Alternate Name: Towards AI, Inc. Alternate Name: Towards AI Co. Alternate Name: towards ai Alternate Name: towardsai Alternate Name: towards.ai Alternate Name: tai Alternate Name: toward ai Alternate Name: toward.ai Alternate Name: Towards AI, Inc. Alternate Name: towardsai.net Alternate Name: pub.towardsai.net
5 stars – based on 497 reviews

Frequently Used, Contextual References

TODO: Remember to copy unique IDs whenever it needs used. i.e., URL: 304b2e42315e

Resources

Take our 85+ lesson From Beginner to Advanced LLM Developer Certification: From choosing a project to deploying a working product this is the most comprehensive and practical LLM course out there!

Publication

Amazon Lex: Conversations in the Cloud
Latest

Amazon Lex: Conversations in the Cloud

Last Updated on January 5, 2023 by Editorial Team

Author(s): ThinkPro Systems

Originally published on Towards AI the World’s Leading AI and Technology News and Media Company. If you are building an AI-related product or service, we invite you to consider becoming an AI sponsor. At Towards AI, we help scale AI and technology startups. Let us help you unleash your technology to the masses.

Amazon Lex

A conversational interface is the way of the future. Nothing can beat the user experience of a user talking to your application. Any amount of color optimization and responsive design on a website or mobile app is trivial when it is compared to the experience of a conversation.

Naturally, such a conversation is difficult to implement. However, it is not so difficult either. We have an array of tools and utilities to help us construct the chatbots as per our requirements. This blog introduces you to Amazon Lex, covering the following topics:

  1. Introduction — What is Lex?
  2. Core concepts
  3. Create a bot — a simple bot
  4. Improving the bot
  5. Lex vs. ChatGPT — Utility, customization, and integration

Introduction

Amazon Lex is a service provided by Amazon Web Services (AWS) that enables users to build and deploy chatbots for use in a variety of applications. These chatbots, also known as conversational interfaces, allow users to interact with a system or service through natural language input and output.

One of the key benefits of Amazon Lex is its integration with other AWS services. This allows users to leverage the power of the AWS ecosystem to build and deploy their chatbots. For example, Amazon Lex chatbots can be integrated with Amazon Connect, a cloud-based contact center service, to provide customer service through a chatbot interface.

In addition to its integration with other AWS services, Amazon Lex also offers a variety of features to help users build and deploy high-quality chatbots. These features include:

  • Automatic speech recognition (ASR): Amazon Lex uses ASR to recognize spoken input from users and translate it into text. This allows users to speak to their chatbot as they would to a human, making the chatbot experience more natural and intuitive.
  • Natural language understanding (NLU): Amazon Lex uses NLU to understand the meaning and context of user input. This allows the chatbot to respond appropriately to user requests and requests for information.
  • Text-to-speech (TTS): Amazon Lex offers TTS capabilities, allowing chatbots to speak to users in a natural, human-like voice. This can be particularly useful for applications such as customer service or information kiosks.
  • Customization: Amazon Lex allows users to customize their chatbots through the use of Amazon Lex ML models and AWS Lambda functions. This enables users to tailor their chatbots to their specific needs and build in custom logic and functionality.

Overall, Amazon Lex is a powerful tool for building and deploying chatbots for a variety of applications. Its integration with other AWS services and extensive customization options make it an ideal choice for users looking to build conversational interfaces for their business or service.

Core concepts

Before we get into implementation, we should understand a few important concepts involved in building chatbots.

Intents

An intent represents the intention of the end user — what does the user want? The primary task of the chatbot is to try and guess this intent and map it with the intents it is programmed to process.

Utterances

The chatbot tries to guess the intent based on the utterances of the user. These are spoken or typed phrases in the user input. The chatbot tries to relate them with the utterances configured for each of its known intents, to identify the current intent.

Slots

The intent alone is not enough. The chatbot needs specific details related to the intent so that it can work on it. These details should be identified from the user’s input. We call them slots. They are specific words and phrases that appear in the long sentences that the user utters.

Fulfillment

This is the actual mechanism for your intent. Once the intent and the slots are identified, the chatbot invokes the fulfillment mechanism that we have configured.

Note that the utterances, intents, and slots come in free-flowing text from the user. They do not have a fixed format or sequence. Here, we cannot use the traditional techniques of text matching or regular expressions. We need intense NLP using trained models to get these details. That is why we need Amazon Lex.

With Lex, we have readymade models that help us with these tedious tasks. We just configure the basics and it takes care of the rest.

Create a bot

With the basic theoretical understanding, let us now implement a simple bot using Amazon Lex. Let us create a chatbot that can tell us the latest news related to a given keyword. It is a simple process that involves a few core concepts. Let us check it out.

Jump to the Amazon Lex Console.

Amazon Lex Console

Click on “Create bot” to start the process. The configuration is straightforward.

  • We will start with the blank bot
Create blank bot
  • Provide a name and optional description to identify the bot
Bot configuration
  • Let AWS take care of creating the IAM Roles
Create role
  • We need not worry about the COPPA in the tutorial
Ignore COPPA for demo
  • We should be good with a 5-minute session timeout.
Default timeout
  • To start with, let us focus on text interaction in US English.
US English
  • Finally, click Done to create the bot. That brings us to the intended creation. Provide a name and description for the new intent.
Create Intent
  • Scroll down, to slots, and click on “Add slot”
City slot
  • Expand the “Prompt for slot: city” to provide more details. Click on “Additional options”.
Slot prompts
  • Scroll down on the popup that opens on the right side of the screen, to provide the slot capture success response.
Slot response
  • Click on “Update Slot”. That will get you back to the intent configuration. Scroll up again, and add Sample utterances. Type in the text field and click on “Add utterance” to add individual utterances. Note that {city} in curly braces is related to the slot — city that we added above.
Intent utterances
  • Now scroll down further to enable fulfillment.
Enable fulfillment
  • Click on “Advanced options”. That opens a popup on the right half of the screen. Select the check box to “Use a lambda function for fulfillment”
Attach lambda function
  • Click on “Update options” to close the popup and get back to the intent configuration. Click on “Save Intent” and then click on “Build” to build the chatbot. The build takes some time. Once it is done, add another intent for getting news related to a keyword. The same steps as above, with minor differences. This time, the slot is “keyword,” and its type is alphanumeric.
Keyword slot
  • The utterances should be related to the news.
News utterances
  • Again, save the intent and build it. Confirm the list of intents in the bot. Note that there is a third intent that we did not create. This is the Fallback intent, which is triggered when the bot is not able to classify our request into any of the other intents. If our bot frequently lands here, it means we need to enrich the set of “Sample utterances”. Lex is capable of extending the set of utterances we provide into a more generic collection. However, it makes sense to apply minds here to do our best in providing the data set. That is one of the points that differentiate a well-crafted bot from a poorly developed one.
Three intents
  • Now, we have to work on the Lambda function that can fulfill our intent. So jump to the Lambda console and create a new Lambda function. Give it a name and choose Runtime as NodeJS. Leave everything else as default and click “Create function”.
Create lambda function
  • Check out this link for the required source code in the Lambda function. Clone or download the repository. There is a deploy.zip file that must be uploaded to the Lambda function. On the lambda code tab, click on “Update from” and upload this zip file into the lambda function. The Lambda function uses public APIs for the weather and news. You will have to visit those websites and get the API keys for them. It is simple and free. Once done, add those keys to the lambda environment. Note that the lambda environment variable is not the best place to save API keys. However, it is okay for a demo application like this.
API Keys
  • Deploy it, and we are ready to go. Now come back to the Lex console, where the bot is ready for us. Click on Test, and it will open a popup.
Test the bot
  • Click on the gear icon to open the settings. It will open another popup for the settings. There, add the Lambda function that should process the fulfillment requests.
Attach the lambda functions
  • Type into it to see how our bot works. Here is my conversation with the bot.

Wow! Try out different ways of asking the same question. If something fails, try to update the intent utterances and save the intent and build the bot again.

We can easily integrate this with our website or mobile app using AWS Amplify.

Improving the bot

That was good for a simple demo bot. It gives a glimpse of what we can do with Lex. Obviously, there is a lot more to Lex and chatbot development. For example, we can configure several other aspects of the intent. The confirmation, closing remarks, etc. We can build up the session context as the user chats with the bot. So, the user can refer to an object used in a few commands before. For example, the user can ask about the weather in a city. Then ask for news with a pronoun. The bot can “remember” the context and give the news about the same city. Or the user can ask about the weather after a few minutes — how is the weather now? The bot can remember the previous request and fulfill it without asking for the city again.

These are the interaction aspects of the bot. We can also enhance it functionally. For example, instead of invoking free APIs for the news and weather, we could have a bot that queries the real prices of the share market. The user can just query the share prices and instruct a buy or sell from the chat console.

And, of course, we can use a voice interface to make this even more interesting. In the above example, we have used the text-only interface. We can enable a voice to make it even more interesting.

The sky is the limit for the variety of use cases and possibilities we have with the Amazon Lex bots. It is an absolutely trivial task to configure and get the basic structure working. Once it is ready, we can add more and more features to it.

Lex vs. ChatGPT

ChatGPT has hit many headlines (and also many minds) in the last few weeks. However, there is a big difference between the two. ChatGPT no doubt has great features for generating awesome text content. However, when it comes to functionality, utility, and configurability, it is far behind Lex.

Functionality

Amazon Lex is a fully-featured chatbot platform that allows developers to build, test, and deploy chatbots for various applications. It includes natural language understanding (NLU) and automatic speech recognition (ASR) capabilities, as well as integration with other AWS services. ChatGPT, on the other hand, is an open-source chatbot toolkit based on the GPT-3 language model. It is designed for generating human-like text and can be used to build chatbots that can hold conversations with users.

Customization

Amazon Lex offers a high level of customization, allowing developers to fine-tune the chatbot’s behavior and responses based on their specific needs. ChatGPT, on the other hand, is more limited in terms of customization. It generates text based on the input it receives, but developers have less control over the specific responses the chatbot provides.

Integration

Amazon Lex integrates seamlessly with other AWS services, such as Lambda and Amazon Connect. This allows developers to build chatbots that can access data from other AWS services and perform various actions. ChatGPT, on the other hand, does not have this level of integration with other tools and services.

Overall, Amazon Lex is a more comprehensive chatbot platform, while ChatGPT is a more specialized tool that is primarily focused on generating human-like text. Both can be useful for building chatbots, but the best choice will depend on the specific needs and goals of the project.


Amazon Lex: Conversations in the Cloud was originally published in Towards AI on Medium, where people are continuing the conversation by highlighting and responding to this story.

Join thousands of data leaders on the AI newsletter. It’s free, we don’t spam, and we never share your email address. Keep up to date with the latest work in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming a sponsor.

Published via Towards AI

Feedback ↓

Sign Up for the Course
`; } else { console.error('Element with id="subscribe" not found within the page with class "home".'); } } }); // Remove duplicate text from articles /* Backup: 09/11/24 function removeDuplicateText() { const elements = document.querySelectorAll('h1, h2, h3, h4, h5, strong'); // Select the desired elements const seenTexts = new Set(); // A set to keep track of seen texts const tagCounters = {}; // Object to track instances of each tag elements.forEach(el => { const tagName = el.tagName.toLowerCase(); // Get the tag name (e.g., 'h1', 'h2', etc.) // Initialize a counter for each tag if not already done if (!tagCounters[tagName]) { tagCounters[tagName] = 0; } // Only process the first 10 elements of each tag type if (tagCounters[tagName] >= 2) { return; // Skip if the number of elements exceeds 10 } const text = el.textContent.trim(); // Get the text content const words = text.split(/\s+/); // Split the text into words if (words.length >= 4) { // Ensure at least 4 words const significantPart = words.slice(0, 5).join(' '); // Get first 5 words for matching // Check if the text (not the tag) has been seen before if (seenTexts.has(significantPart)) { // console.log('Duplicate found, removing:', el); // Log duplicate el.remove(); // Remove duplicate element } else { seenTexts.add(significantPart); // Add the text to the set } } tagCounters[tagName]++; // Increment the counter for this tag }); } removeDuplicateText(); */ // Remove duplicate text from articles function removeDuplicateText() { const elements = document.querySelectorAll('h1, h2, h3, h4, h5, strong'); // Select the desired elements const seenTexts = new Set(); // A set to keep track of seen texts const tagCounters = {}; // Object to track instances of each tag // List of classes to be excluded const excludedClasses = ['medium-author', 'post-widget-title']; elements.forEach(el => { // Skip elements with any of the excluded classes if (excludedClasses.some(cls => el.classList.contains(cls))) { return; // Skip this element if it has any of the excluded classes } const tagName = el.tagName.toLowerCase(); // Get the tag name (e.g., 'h1', 'h2', etc.) // Initialize a counter for each tag if not already done if (!tagCounters[tagName]) { tagCounters[tagName] = 0; } // Only process the first 10 elements of each tag type if (tagCounters[tagName] >= 10) { return; // Skip if the number of elements exceeds 10 } const text = el.textContent.trim(); // Get the text content const words = text.split(/\s+/); // Split the text into words if (words.length >= 4) { // Ensure at least 4 words const significantPart = words.slice(0, 5).join(' '); // Get first 5 words for matching // Check if the text (not the tag) has been seen before if (seenTexts.has(significantPart)) { // console.log('Duplicate found, removing:', el); // Log duplicate el.remove(); // Remove duplicate element } else { seenTexts.add(significantPart); // Add the text to the set } } tagCounters[tagName]++; // Increment the counter for this tag }); } removeDuplicateText(); //Remove unnecessary text in blog excerpts document.querySelectorAll('.blog p').forEach(function(paragraph) { // Replace the unwanted text pattern for each paragraph paragraph.innerHTML = paragraph.innerHTML .replace(/Author\(s\): [\w\s]+ Originally published on Towards AI\.?/g, '') // Removes 'Author(s): XYZ Originally published on Towards AI' .replace(/This member-only story is on us\. Upgrade to access all of Medium\./g, ''); // Removes 'This member-only story...' }); //Load ionic icons and cache them if ('localStorage' in window && window['localStorage'] !== null) { const cssLink = 'https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css'; const storedCss = localStorage.getItem('ionicons'); if (storedCss) { loadCSS(storedCss); } else { fetch(cssLink).then(response => response.text()).then(css => { localStorage.setItem('ionicons', css); loadCSS(css); }); } } function loadCSS(css) { const style = document.createElement('style'); style.innerHTML = css; document.head.appendChild(style); } //Remove elements from imported content automatically function removeStrongFromHeadings() { const elements = document.querySelectorAll('h1, h2, h3, h4, h5, h6, span'); elements.forEach(el => { const strongTags = el.querySelectorAll('strong'); strongTags.forEach(strongTag => { while (strongTag.firstChild) { strongTag.parentNode.insertBefore(strongTag.firstChild, strongTag); } strongTag.remove(); }); }); } removeStrongFromHeadings(); "use strict"; window.onload = () => { /* //This is an object for each category of subjects and in that there are kewords and link to the keywods let keywordsAndLinks = { //you can add more categories and define their keywords and add a link ds: { keywords: [ //you can add more keywords here they are detected and replaced with achor tag automatically 'data science', 'Data science', 'Data Science', 'data Science', 'DATA SCIENCE', ], //we will replace the linktext with the keyword later on in the code //you can easily change links for each category here //(include class="ml-link" and linktext) link: 'linktext', }, ml: { keywords: [ //Add more keywords 'machine learning', 'Machine learning', 'Machine Learning', 'machine Learning', 'MACHINE LEARNING', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, ai: { keywords: [ 'artificial intelligence', 'Artificial intelligence', 'Artificial Intelligence', 'artificial Intelligence', 'ARTIFICIAL INTELLIGENCE', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, nl: { keywords: [ 'NLP', 'nlp', 'natural language processing', 'Natural Language Processing', 'NATURAL LANGUAGE PROCESSING', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, des: { keywords: [ 'data engineering services', 'Data Engineering Services', 'DATA ENGINEERING SERVICES', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, td: { keywords: [ 'training data', 'Training Data', 'training Data', 'TRAINING DATA', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, ias: { keywords: [ 'image annotation services', 'Image annotation services', 'image Annotation services', 'image annotation Services', 'Image Annotation Services', 'IMAGE ANNOTATION SERVICES', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, l: { keywords: [ 'labeling', 'labelling', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, pbp: { keywords: [ 'previous blog posts', 'previous blog post', 'latest', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, mlc: { keywords: [ 'machine learning course', 'machine learning class', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, }; //Articles to skip let articleIdsToSkip = ['post-2651', 'post-3414', 'post-3540']; //keyword with its related achortag is recieved here along with article id function searchAndReplace(keyword, anchorTag, articleId) { //selects the h3 h4 and p tags that are inside of the article let content = document.querySelector(`#${articleId} .entry-content`); //replaces the "linktext" in achor tag with the keyword that will be searched and replaced let newLink = anchorTag.replace('linktext', keyword); //regular expression to search keyword var re = new RegExp('(' + keyword + ')', 'g'); //this replaces the keywords in h3 h4 and p tags content with achor tag content.innerHTML = content.innerHTML.replace(re, newLink); } function articleFilter(keyword, anchorTag) { //gets all the articles var articles = document.querySelectorAll('article'); //if its zero or less then there are no articles if (articles.length > 0) { for (let x = 0; x < articles.length; x++) { //articles to skip is an array in which there are ids of articles which should not get effected //if the current article's id is also in that array then do not call search and replace with its data if (!articleIdsToSkip.includes(articles[x].id)) { //search and replace is called on articles which should get effected searchAndReplace(keyword, anchorTag, articles[x].id, key); } else { console.log( `Cannot replace the keywords in article with id ${articles[x].id}` ); } } } else { console.log('No articles found.'); } } let key; //not part of script, added for (key in keywordsAndLinks) { //key is the object in keywords and links object i.e ds, ml, ai for (let i = 0; i < keywordsAndLinks[key].keywords.length; i++) { //keywordsAndLinks[key].keywords is the array of keywords for key (ds, ml, ai) //keywordsAndLinks[key].keywords[i] is the keyword and keywordsAndLinks[key].link is the link //keyword and link is sent to searchreplace where it is then replaced using regular expression and replace function articleFilter( keywordsAndLinks[key].keywords[i], keywordsAndLinks[key].link ); } } function cleanLinks() { // (making smal functions is for DRY) this function gets the links and only keeps the first 2 and from the rest removes the anchor tag and replaces it with its text function removeLinks(links) { if (links.length > 1) { for (let i = 2; i < links.length; i++) { links[i].outerHTML = links[i].textContent; } } } //arrays which will contain all the achor tags found with the class (ds-link, ml-link, ailink) in each article inserted using search and replace let dslinks; let mllinks; let ailinks; let nllinks; let deslinks; let tdlinks; let iaslinks; let llinks; let pbplinks; let mlclinks; const content = document.querySelectorAll('article'); //all articles content.forEach((c) => { //to skip the articles with specific ids if (!articleIdsToSkip.includes(c.id)) { //getting all the anchor tags in each article one by one dslinks = document.querySelectorAll(`#${c.id} .entry-content a.ds-link`); mllinks = document.querySelectorAll(`#${c.id} .entry-content a.ml-link`); ailinks = document.querySelectorAll(`#${c.id} .entry-content a.ai-link`); nllinks = document.querySelectorAll(`#${c.id} .entry-content a.ntrl-link`); deslinks = document.querySelectorAll(`#${c.id} .entry-content a.des-link`); tdlinks = document.querySelectorAll(`#${c.id} .entry-content a.td-link`); iaslinks = document.querySelectorAll(`#${c.id} .entry-content a.ias-link`); mlclinks = document.querySelectorAll(`#${c.id} .entry-content a.mlc-link`); llinks = document.querySelectorAll(`#${c.id} .entry-content a.l-link`); pbplinks = document.querySelectorAll(`#${c.id} .entry-content a.pbp-link`); //sending the anchor tags list of each article one by one to remove extra anchor tags removeLinks(dslinks); removeLinks(mllinks); removeLinks(ailinks); removeLinks(nllinks); removeLinks(deslinks); removeLinks(tdlinks); removeLinks(iaslinks); removeLinks(mlclinks); removeLinks(llinks); removeLinks(pbplinks); } }); } //To remove extra achor tags of each category (ds, ml, ai) and only have 2 of each category per article cleanLinks(); */ //Recommended Articles var ctaLinks = [ /* ' ' + '

Subscribe to our AI newsletter!

' + */ '

Take our 85+ lesson From Beginner to Advanced LLM Developer Certification: From choosing a project to deploying a working product this is the most comprehensive and practical LLM course out there!

'+ '

Towards AI has published Building LLMs for Production—our 470+ page guide to mastering LLMs with practical projects and expert insights!

' + '
' + '' + '' + '

Note: Content contains the views of the contributing authors and not Towards AI.
Disclosure: This website may contain sponsored content and affiliate links.

' + 'Discover Your Dream AI Career at Towards AI Jobs' + '

Towards AI has built a jobs board tailored specifically to Machine Learning and Data Science Jobs and Skills. Our software searches for live AI jobs each hour, labels and categorises them and makes them easily searchable. Explore over 10,000 live jobs today with Towards AI Jobs!

' + '
' + '

🔥 Recommended Articles 🔥

' + 'Why Become an LLM Developer? Launching Towards AI’s New One-Stop Conversion Course'+ 'Testing Launchpad.sh: A Container-based GPU Cloud for Inference and Fine-tuning'+ 'The Top 13 AI-Powered CRM Platforms
' + 'Top 11 AI Call Center Software for 2024
' + 'Learn Prompting 101—Prompt Engineering Course
' + 'Explore Leading Cloud Providers for GPU-Powered LLM Training
' + 'Best AI Communities for Artificial Intelligence Enthusiasts
' + 'Best Workstations for Deep Learning
' + 'Best Laptops for Deep Learning
' + 'Best Machine Learning Books
' + 'Machine Learning Algorithms
' + 'Neural Networks Tutorial
' + 'Best Public Datasets for Machine Learning
' + 'Neural Network Types
' + 'NLP Tutorial
' + 'Best Data Science Books
' + 'Monte Carlo Simulation Tutorial
' + 'Recommender System Tutorial
' + 'Linear Algebra for Deep Learning Tutorial
' + 'Google Colab Introduction
' + 'Decision Trees in Machine Learning
' + 'Principal Component Analysis (PCA) Tutorial
' + 'Linear Regression from Zero to Hero
'+ '

', /* + '

Join thousands of data leaders on the AI newsletter. It’s free, we don’t spam, and we never share your email address. Keep up to date with the latest work in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming a sponsor.

',*/ ]; var replaceText = { '': '', '': '', '
': '
' + ctaLinks + '
', }; Object.keys(replaceText).forEach((txtorig) => { //txtorig is the key in replacetext object const txtnew = replaceText[txtorig]; //txtnew is the value of the key in replacetext object let entryFooter = document.querySelector('article .entry-footer'); if (document.querySelectorAll('.single-post').length > 0) { //console.log('Article found.'); const text = entryFooter.innerHTML; entryFooter.innerHTML = text.replace(txtorig, txtnew); } else { // console.log('Article not found.'); //removing comment 09/04/24 } }); var css = document.createElement('style'); css.type = 'text/css'; css.innerHTML = '.post-tags { display:none !important } .article-cta a { font-size: 18px; }'; document.body.appendChild(css); //Extra //This function adds some accessibility needs to the site. function addAlly() { // In this function JQuery is replaced with vanilla javascript functions const imgCont = document.querySelector('.uw-imgcont'); imgCont.setAttribute('aria-label', 'AI news, latest developments'); imgCont.title = 'AI news, latest developments'; imgCont.rel = 'noopener'; document.querySelector('.page-mobile-menu-logo a').title = 'Towards AI Home'; document.querySelector('a.social-link').rel = 'noopener'; document.querySelector('a.uw-text').rel = 'noopener'; document.querySelector('a.uw-w-branding').rel = 'noopener'; document.querySelector('.blog h2.heading').innerHTML = 'Publication'; const popupSearch = document.querySelector$('a.btn-open-popup-search'); popupSearch.setAttribute('role', 'button'); popupSearch.title = 'Search'; const searchClose = document.querySelector('a.popup-search-close'); searchClose.setAttribute('role', 'button'); searchClose.title = 'Close search page'; // document // .querySelector('a.btn-open-popup-search') // .setAttribute( // 'href', // 'https://medium.com/towards-artificial-intelligence/search' // ); } // Add external attributes to 302 sticky and editorial links function extLink() { // Sticky 302 links, this fuction opens the link we send to Medium on a new tab and adds a "noopener" rel to them var stickyLinks = document.querySelectorAll('.grid-item.sticky a'); for (var i = 0; i < stickyLinks.length; i++) { /* stickyLinks[i].setAttribute('target', '_blank'); stickyLinks[i].setAttribute('rel', 'noopener'); */ } // Editorial 302 links, same here var editLinks = document.querySelectorAll( '.grid-item.category-editorial a' ); for (var i = 0; i < editLinks.length; i++) { editLinks[i].setAttribute('target', '_blank'); editLinks[i].setAttribute('rel', 'noopener'); } } // Add current year to copyright notices document.getElementById( 'js-current-year' ).textContent = new Date().getFullYear(); // Call functions after page load extLink(); //addAlly(); setTimeout(function() { //addAlly(); //ideally we should only need to run it once ↑ }, 5000); }; function closeCookieDialog (){ document.getElementById("cookie-consent").style.display = "none"; return false; } setTimeout ( function () { closeCookieDialog(); }, 15000); console.log(`%c 🚀🚀🚀 ███ █████ ███████ █████████ ███████████ █████████████ ███████████████ ███████ ███████ ███████ ┌───────────────────────────────────────────────────────────────────┐ │ │ │ Towards AI is looking for contributors! │ │ Join us in creating awesome AI content. │ │ Let's build the future of AI together → │ │ https://towardsai.net/contribute │ │ │ └───────────────────────────────────────────────────────────────────┘ `, `background: ; color: #00adff; font-size: large`); //Remove latest category across site document.querySelectorAll('a[rel="category tag"]').forEach(function(el) { if (el.textContent.trim() === 'Latest') { // Remove the two consecutive spaces (  ) if (el.nextSibling && el.nextSibling.nodeValue.includes('\u00A0\u00A0')) { el.nextSibling.nodeValue = ''; // Remove the spaces } el.style.display = 'none'; // Hide the element } }); // Add cross-domain measurement, anonymize IPs 'use strict'; //var ga = gtag; ga('config', 'G-9D3HKKFV1Q', 'auto', { /*'allowLinker': true,*/ 'anonymize_ip': true/*, 'linker': { 'domains': [ 'medium.com/towards-artificial-intelligence', 'datasets.towardsai.net', 'rss.towardsai.net', 'feed.towardsai.net', 'contribute.towardsai.net', 'members.towardsai.net', 'pub.towardsai.net', 'news.towardsai.net' ] } */ }); ga('send', 'pageview'); -->