How to Push Realtime Events from Frappe Backend to Android App using frappe.publish_realtime?

Hi everyone,

I’ve developed a chat application using the WhatsApp Business API, with Frappe as the backend where all incoming and outgoing messages are logged. The frontend, including an Android app interface, displays these messages.

Currently, I’m using frappe.publish_realtime to broadcast new message events to the Frappe frontend, where they are displayed using frappe.realtime.on. Here’s the backend Python code I’m using:

def after_insert(self):
    try:
        """Send message to socket."""
        wa_team = self.whatsapp_team
        user = frappe.db.get_value("WhatsApp Team", wa_team, "user")

        message_data = {
            "name": self.name,
            "type": "Incoming",
            "from": getattr(self, "from"),
            "contact": self.contact,
            "message": self.message,
            "creation": self.creation,
        }

        frappe.publish_realtime(
            event="new_whatsapp_message",
            message={"message": message_data, "user": user},
            doctype="WhatsApp Message",
            docname=self.name,
            user=user,
            after_commit=True,
        )
    except Exception as e:
        frappe.log_error(frappe.get_traceback(), "Socket Error")

And this is the JavaScript I’m using on the Frappe frontend:

$(document).on('app_ready', function () {
    frappe.realtime.on("new_whatsapp_message", (data) => {
        if (data && data.message) {
            const messageData = data.message;

            if (messageData.type === "Incoming") {
                const messageContent = messageData.message;
                const sender = messageData.from;
                const contactName = messageData.contact;
                const timeStamp = new Date(messageData.creation);
                const name = messageData.name;

                function formatDateTime(date) {
                    const day = String(date.getDate()).padStart(2, '0');
                    const month = String(date.getMonth() + 1).padStart(2, '0');
                    const year = date.getFullYear();

                    let hours = date.getHours();
                    const minutes = String(date.getMinutes()).padStart(2, '0');
                    const ampm = hours >= 12 ? 'PM' : 'AM';

                    hours = hours % 12;
                    hours = hours ? String(hours).padStart(2, '0') : '12';

                    return `${day}/${month}/${year} ${hours}:${minutes} ${ampm}`;
                }

                const formattedMessage = `
                    <strong>New Message from ${contactName || sender}:</strong><br>
                    <em>${messageContent}</em><br>
                    <small><em>Received on: ${formatDateTime(timeStamp)}</em></small>
                `;

                frappe.msgprint({
                    title: __('New WhatsApp Message'),
                    message: formattedMessage,
                    indicator: 'green',
                    label: 'GO TO MESSAGE',
                    primary_action: {
                        action: () => {
                            frappe.set_route('Form', 'WhatsApp Message', name);
                        },
                        label: __('GO TO MESSAGE')
                    }
                });
            }
        } else {
            console.error("Received data does not have the expected structure:", data);
        }
    });
});

And here’s how it displays on the Frappe frontend when a new incoming message is received:

Problem: I now need to push the same real-time data to my Android app as well. How can I set up frappe.publish_realtime to send events to an Android app? Alternatively, what would be the best approach to achieve this in Frappe? Any tips on handling this efficiently would be highly appreciated!

Thank you in advance for your help!

@buildwithhussain, if you have any insights, they would be very helpful.

The technology used is WebSockets. By opening a WebSocket to the site, you will be able to subscribe to events as you did in JavaScript already.

However, this will probably not work if your Android app is in the background. So you might need to take a look at Firebase Cloud Messaging by Google Cloud for another way of handling push notifications / realtime events, but this is not ideal.

Thanks, let me try with WebSocket

1 Like