How do I make the channels for each chats using Pusher Channel

So basically I am making a social media web using Django, and I also build a chat message on my web as well, so I looked into YouTube and followed a tutorial to make a real-time chat message, and I also use the Pusher WebSocket to hold the message to be sent, but I met a problem is that when I message with the one I click on, the message is also displayed to the other user account, but it does not actually exist because when the other user reload the page, the message from me to the user I chat with disappear. The success part is that the message is displayed forever in my chat with the one I message with even if I reload the page. I spent almost a week to figure it out but any ideas I think about aren’t working.

So these are my code for the real-time message

THIS IS MY VIEWS.PY FILE

@login_required(login_url="login")
def chat_room(request):
    uid = request.user.id
    user = Profiles.objects.get(id = uid)
    follows = user.follows.all()
    context = {'user':user,
               'follows':follows}
    return render(request,"chat_room.html",context)



@login_required(login_url="login")
def chat_details(request,id):
    uid = request.user.id
    user = Profiles.objects.get(id = uid)
    follows = user.follows.get(id=id)
    form = ChatMessageForm()
    chats = ChatMessage.objects.all()
    receive_chats = ChatMessage.objects.filter(msg_sender=follows,msg_receiver=user,seen=False)
    receive_chats.update(seen=True)
    if request.method == "POST":
        form = ChatMessageForm(request.POST)

        if form.is_valid():
            chat_message = form.save(commit=False)
            chat_message.msg_sender = user
            chat_message.msg_receiver = follows
            chat_message.save()
            return redirect('chat_details',id =follows.id)

    context = {'follows':follows,
               'form':form,
               'user':user,
               'chats':chats,}
    return render(request,"chat_details.html",context)


@login_required(login_url="login")
def sent_messages(request,id):
    uid = request.user.id
    user = Profiles.objects.get(id = uid)
    follows = user.follows.get(id=id)
    data = json.loads(request.body)
    new_chat = data["msg"]
    new_chat_message = ChatMessage.objects.create(body = new_chat,msg_sender = user,msg_receiver = follows,seen = False)
    pusher_client = Pusher(
        app_id = "", # I need to hide it for private
        key = "",
        secret = "",
        cluster = "",
        ssl=True)
    pusher_client.trigger('my-channel', 'my-event', {'msg': new_chat_message.body})
    return JsonResponse(new_chat_message.body,safe=False)

@login_required(login_url="login")
def chat_notification(request):
    uid = request.user.id
    user = Profiles.objects.get(id = uid)
    follows = user.follows.all()
    arr = []
    for follow in follows:
        chats = ChatMessage.objects.filter(msg_sender_id=follow,msg_receiver=user,seen = False)
        arr.append(chats.count())
    return JsonResponse(arr,safe=False)

THIS IS MY CHAT_DETAILS.HTML FILE

{% extends 'base.html' %}

{% block content %}
<div>
    <h3>{{follows.username}}</h3>
</div>
    <div id="chat-body">
        {% for chat in chats%}
            {% if chat.msg_sender == user and chat.msg_receiver == follows %}
                <div class="chat-box-sent">
                    {{chat}}
                </div>
            {% elif chat.msg_sender == follows and chat.msg_receiver == user %}
                <div class="chat-box-received">
                    {{chat}}
                </div>
            {% endif %}
        {% endfor %}
    </div>
    <form action="" method="POST" id="myform" >
        {% csrf_token %}
        {{form.body}}
        <button type="submit" id="submit">  
            Send
        </button>
    </form>
    <script>
        function getCookie(name) {
            let cookieValue = null;
            if (document.cookie && document.cookie !== '') {
                const cookies = document.cookie.split(';');
                for (let i = 0; i < cookies.length; i++) {
                    const cookie = cookies[i].trim();
                    if (cookie.substring(0, name.length + 1) === (name + '=')) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                    }
                }
            }
            return cookieValue;
        }
        const pusher = new Pusher('My_Pusher_Key', {
            cluster: 'ap1',
        });

        let form = document.getElementById("myform")
        form.addEventListener("submit", sendChat)
        const chatChannel = pusher.subscribe('my-channel');
        const csrftoken = getCookie('csrftoken');

        chatChannel.bind('my-event', function(data) {
            const newChatMessage = data.msg;
            const chatMessageBox = document.createElement("div");
            chatMessageBox.classList.add("chat-box-received");
            chatMessageBox.innerText = newChatMessage;
            document.getElementById("chat-body").append(chatMessageBox);
        });

        function sendChat(event) {
            event.preventDefault();
            const chatMessage = document.getElementById("id_body").value;

            const data = {
                msg: chatMessage
            };

            fetch("{% url 'sent_messages' follows.id %}", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                    "X-CSRFToken": csrftoken
                },
                body: JSON.stringify(data)
            })
            .then(response => response.json())
            .then(data => {
                console.log("Success:", data);
                document.getElementById("id_body").value = "";
            })
            .catch(error => {
                console.error("Error:", error);
            });
        }

    </script>
{% endblock content %}

THIS IS MY URL.PY FILE

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',views.home),
    path('chat_room/',views.chat_room,name="chat_room"),
    path('chat_room/chat_details/<int:id>',views.chat_details,name="chat_details"),
    path('sent_messages/<int:id>',views.sent_messages,name="sent_messages"),
    path('chat_notification/',views.chat_notification,name="chat_notification"),
    # path('pusher/auth', views.pusher_authentication),
]

THIS IS MY MODEL.PY FILE

class Profiles(AbstractUser):
    first_name = models.CharField(max_length=200, blank= False)
    last_name =  models.CharField(max_length=200, blank= False)
    follows= models.ManyToManyField("self", related_name="followed_by", symmetrical=False, blank=True)
    bio = models.TextField(default="No bio yet", max_length=300)
    email = models.EmailField(max_length=200)
    avatar = models.ImageField(default="avatar.svg")

    REQUIRED_FIELDS = []

class ChatMessage(models.Model):
    body = models.TextField()
    msg_sender = models.ForeignKey(Profiles,on_delete=models.CASCADE,related_name="msg_sender")
    msg_receiver = models.ForeignKey(Profiles,on_delete=models.CASCADE,related_name="msg_receiver")
    seen = models.BooleanField(default=False)

    def __str__(self):
        return self.body

MY FORM.PY FILE

class ChatMessageForm(forms.ModelForm):
    body = forms.CharField(widget=forms.TextInput(attrs={'width':'300px','placeholder':'Type message here...'}))
    class Meta:
        model = ChatMessage
        fields = ['body']

Leave a Comment