Implementation: A "Send WhatsApp Message" sticky button for list-details page

Hi everyone,

Even though I’m a newbie here, this community has helped me so much that I wanted to return the favor sharing something I implemented yesterday and I think someone might find useful. Even though probably it’s a silly thing for people with tech know-how, I personally don’t code and struggled to find information on how to make it work in this community. Thanks to @acjnas and @Astghik for the help.

Use case: You have a list for which the list-details page belongs to people or businesses. You want users to be able to send messages to those people. Every detail page has a different phone number.

For reference, this is how it looks like

Some comments before I share the code:

  • I’m using Airtable.
  • To send a WhatsApp message, you need to create a link that contains the phone number of the recipient and an (optional) encoded message for each person in the directory. You can find more information here..
  • To create this URL, you must first:
  1. Remove all non-numerical characters from the stored phone. This is because Softr stores phone numbers collected through forms in a format like (111) 111-1111 and you need just the numbers.
    In Airtable, I created a formula field in the table that stores the phone numbers and used this to get just the numbers:
    SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE({contractorPhone}, "-", ""), " ", ""), "(", ""), ")", ""), "+", "")
  2. Create the WhatsApp link concatenating the URL, the number and the optional encoded message. Again, create a formula field in Airtable and use this: "https://wa.me/"&normalizedPhone&"?text=Hi%20everyone.%20This%20is%20an%20encoded%20message"
    Note that in this case, normalizedPhone is the name of the variable I created in step 1 to remove non-numerical chars. For the encoded message, you can use a tool like this.

This is the snippet I used:

<script>
    document.addEventListener("DOMContentLoaded", function() {
        var waitForData = setInterval(function() {
            if (typeof $ != 'undefined' && window.records) {
                const recordId = getUrlParam('recordId');
                const whatsappLink = window.records[recordId] && window.records[recordId].record.fields['whatsappLink'];

                if (whatsappLink) {
                    // Find the paragraph with the text "HIDE_FIELD"
                    const paragraphs = document.querySelectorAll('p');
                    for (const p of paragraphs) {
                        if (p.textContent.trim() === "HIDE_FIELD") {
                            // Hide the parent div of the paragraph
                            const parentDiv = p.closest('div');
                            if (parentDiv) {
                                parentDiv.style.display = 'none';
                            }
                        }
                    }

                    // Create the sticky WhatsApp button
                    const whatsappButton = document.createElement('a');
                    whatsappButton.href = whatsappLink; // Set the WhatsApp link URL
                    whatsappButton.target = '_blank'; // Open in a new tab
                    whatsappButton.rel = 'noopener noreferrer'; // Security attributes
                    whatsappButton.style.position = 'fixed';
                    whatsappButton.style.bottom = '20px';
                    whatsappButton.style.right = '20px';
                    whatsappButton.style.zIndex = '1000';
                    whatsappButton.innerHTML = `<img src="https://cdn.icon-icons.com/icons2/3685/PNG/512/whatsapp_logo_icon_229310.png" alt="WhatsApp" style="width: 50px; height: 50px;">`;

                    // Append the button to the body of the document
                    document.body.appendChild(whatsappButton);

                    // Clear the interval once the button is created
                    clearInterval(waitForData);
                }
            }
        }, 100);

        function getUrlParam(name) {
            const url = new URL(window.location.href);
            let param;
            for (var key of url.searchParams.keys()) {
                if (key.toLowerCase() === name.toLowerCase()) {
                    param = url.searchParams.get(name);
                    break;
                }
            }

            if (!param && name.toLowerCase() === 'recordid') {
                param = getRecordIdFromPath();
            }
            return param;
        }

        function getRecordIdFromPath() {
            let pathName = window.location.pathname;
            if (pathName.indexOf('/r/rec') !== -1) {
                pathName = pathName.substr(pathName.indexOf('/r/rec') + 3);
                if (pathName.indexOf("/") !== -1) {
                    pathName = pathName.substring(0, pathName.indexOf('/'));
                }
                return pathName;
            }
            return undefined;
        }
    });
</script>

Some comments:

  • In this case, “whatsappLink” is the name of the variable in which I stored the WhatsApp message URL in step 2.
  • IMPORTANT: For this to work, you need to get the field with the WhatsApp URL from AirTable into the list-details block. This is because, otherwise, the information wouldn’t be there and the code wouldn’t create the button. As I didn’t want the user to see this, I used the text “HIDE_FIELD” as a label for the WhatsApp URL, and then (in the code) searched the HTML for the text “HIDE_FIELD” and hid the parent div.
  • This code has to be placed in the footer (Settings > Custom Code > Code inside footer).
  • IMPORTANT: Testing: the code doesn’t work in the preview. I believe it’s because it uses a reference to a recordId that doesn’t exist when you navigate your web from the preview. It does work when you publish it and see it live.
  • I created this using ChatGPT 4 and some community posts on how to get the Airtable data for a custom code snippet. There might probably be better ways to do it, so experts feel free to share your take on what can be improved.

Happy New Year to everyone!

Cheers

1 Like

Thank you for sharing!

1 Like