Introducing Glitch: A Hackathon Collaboration Tool Powered by Appwrite
I sincerely want to express my gratitude to Appwrite and Hashnode, the organizers of this hackathon, for providing us with this remarkable opportunity.
Team Members
Description: Knowing the 'What' and the 'Why'
Overview
On May 20th, I stumbled upon a tweet about a GitHub project called Vibey which was seeking collaborators. Their backend was handled by Appwrite. To learn more about Appwrite, I visited Appwrite's website. There I got to know about an ongoing hackathon that had started on May 15th. Despite being late by about 5 days, I could not resist participating after going through the hackathon details. I had never used Appwrite before, so I needed to act quickly.
Before starting the project, I dedicated a day to studying Appwrite's documentation and made use of the crisp documentation as my resource and asked questions in the highly responsive Discord community. This helped me grasp concepts such as API keys, JWTs, authentication, events, storage, databases, teams, users, accounts, avatars, permissions and functions.
As my understanding grew, so did my confidence. I realized that Appwrite's SDKs, with their extensive features, were ideal for my envisioned app, particularly the real-time events and teams feature 💛. Excited, I aimed to create something valuable for both myself and the community that would have lasting utility beyond the hackathon.
What is it?
So what is Glitch? It's a tool for managing hackathon teams. After creating a team, invite members and use Glitch to work together. Talk in group chats or private messages, share ideas, and easily send or download files. Keep things organized by handling tasks, setting due dates, filtering tasks using advanced filters, and pinning high-priority tasks. Share notes and use the GPT-3.5 Turbo API to create task descriptions. With instant notifications for chats and tasks, Glitch helps your team communicate well. It's the best online space for your team to work together and succeed.
Why tackle this challenge?
Why did I take on this challenge? Well, having participated in hackathons with teams myself, I've witnessed firsthand the struggles that teams face. The lack of accountability, ineffective communication, and poor task management can often lead to confusion and wasted time. It's frustrating when important tasks get lost in a flood of messages, causing unnecessary delays and redundancy.
That's why I created Glitch—a game-changing solution that tackles these problems head-on. With Glitch, task management becomes a breeze. You can define, organize, and prioritize tasks with absolute clarity. No more losing track of crucial assignments.
But Glitch doesn't stop there. It combines the best features of modern chat apps, allowing teams to collaborate seamlessly. You can reply to messages, edit messages, and receive real-time read status, keeping everyone on the same page. It's the ultimate productivity booster.
Imagine the excitement of streamlined team communication, synchronized efforts, and accelerated achievements. Glitch takes advantage of the powerful capabilities of Appwrite, bringing together chatting and task management in an all-new way.
Tech Stack
Technologies Utilized
Frontend: Next.js, Chakra UI
Backend: Appwrite, Vercel Serverless
Database: Appwrite Storage
Live Website Link
Demo Recording
A demo recording showcasing the features and functionality of Glitch.
Appwrite Usage
Let's discuss how all components of the app function, the Appwrite services we utilize, how security is maintained, and how we cache data in the browser to reduce network requests to Appwrite. I will explain the thought process behind the software architecture. Feel free to skip and just watch the video as well.
1‣ Authentication 🔒
- a‣ Sign In and Sign Out Workflow
The sign-in and sign-out workflow is pretty straightforward, utilizing the Account API from the Appwrite Web SDK.
SDK Methods used -
Create Email Session (Account API, Web)
Create OAuth2 Session (Account API, Web)
Create Account (Account API, Web)
Delete Session (Account API, Web)
- b‣ Password Recovery
Password recovery, managed by Appwrite Account API, involves two pages: initiation and confirmation. Users access the confirmation page via an email link containing a secret query parameter.
SDK Methods used -
Create Password Recovery (Account API, Web)
Create Password Recovery (confirmation) (Account API, Web)
2‣ Teams 🤝
a‣ Listing Teams
Upon logging in, users view a list of their teams on the homepage, where team preferences like theme color and team image are displayed.
The list of teams is cached in the browser.
Users can also search for a team using the team name as their search query.
SDK Methods used -
List Teams (Teams API, Web)
Get Document (Databases API, Web) - to get team preferences
Get File Preview (Storage API, Web) - preview team profile image
Get User Initials (Avatar API, Web) - display avatar if no team profile image exists
b‣ Creating a Team
Users create their teams on the homepage. The user who creates the team assumes the role of "owner" as per the API.
Permissions are applied to the document created for team preferences, ensuring that only team members are allowed to read and update the preferences in the future.
During team creation, a random RGB color is assigned as the theme color for team preferences.
SDK Methods used -
Create Team (Web)
Create Document (Web) - store team preferences
- c‣ Updating Team Preferences
Team members can update the team settings like team name, theme color, profile image, and default role for new members.
To enable all members to update the team name, we need to use the team's write and teams' read scope for the API key on the server.
Other preferences can be updated directly with Web SDK.
In case the team profile image is updated, the previous image is deleted from the bucket, and a new image is uploaded and linked to the team.
SDK Methods used -
Create JWT (Account API, Web) - verification
Get Account (Account API, Server) - verification
Create File ( Storage API, Web) - store team profile image
Get Document ( Databases API, Web) - get the id of the previous image
Delete File ( Storage API, Web) - delete the previous image
Update Document ( Databases API, Web) - update preferences
List Team Memberships ( Teams API, Server) - verification
Update Team ( Teams API, Server ) - update team name
d‣ Team Dashboard
Overview
- At the top, the team preferences are displayed, including the name, profile picture, theme color, and default role for new members. The data is cached to reduce server load.
Member List
A list of team members, featuring their names, profile photos, and roles, is presented below preferences.
To reduce server load, all member data, including names and profile pictures, is cached as a crucial step. This data is utilized throughout the app, for instance, in chats and tasks.
- Inviting/Removing Members ( Web SDK )
Users with "owner" roles can invite members via web SDK email invitations or add them directly through Server SDK through the user search page.
Users with "owner" roles can remove team members from the team by clicking on "Remove".
Team membership statuses are updated in real-time through team events.
- Assigning Roles To Members
Users with "owner" roles can update the roles of other members. Adding the "admin" role allows a user to create tasks or mark tasks as complete on behalf of other users.
SDK Methods used -
Get Document ( Databases API, Web)
Get File Preview ( Storage API, Web) - get team profile image
Get User Initials ( Avatars API, Web) - display avatar if no team profile image
List Team Memberships ( Teams API, Web)
Get File Preview (Storage API, Web) - get user profile image
Get User Initials (Avatar API, Web) - display avatar if no user profile image exists
Delete Team Membership ( Teams API, Web) - remove a user from a team
Create Team Membership ( Teams API, Web) - send an email invite
Update Team Membership Status ( Teams API, Web) - accept the invitation and join the team
Update Membership Roles ( Teams API, Web)
- e‣ Search Users (Add To Team with Server SDK)
Users can search for other users and directly add them to their team. In this scenario, an email invitation is not required.
Verification is done on the server using JWT to ensure the user creating the membership has the "owner" role.
SDK Methods used -
List Users ( Users API, Server ) - list users by searching
Create JWT (Account API, Web) - verification
List Team Memberships ( Teams API, Server) - verification
Get Account (Account API, Server) - verification
Get Document ( Databases API, Server) - read the default role from the team preferences
Create Team Membership (Teams API, Server) - add the member to the team with the default role
Get File Preview (Storage API, Web) - get user profile images
Get User Initials (Avatar API, Web) - display avatar if no user profile image exists
f‣ Draggable Sidebar
Implemented a draggable sidebar using the React-Draggable library. Cached dynamic sidebar data to prevent multiple network calls during re-renders while dragging.
Sidebar shows the latest team chat message with the sender's name and a list of direct messages.
3‣ Chats 💬
- a‣ Group Chat
Overview
Chats are managed through a collection that stores each chat, allowing users to send messages, edit them, delete them, and reply to other chats.
File-sharing support, including file preview and download.
A notification system allows for a single tick to indicate message delivery and a double tick for read receipts, which include the read time and the names of team members who have read the message.
The "Unread Messages" divider in the chat differentiates between unread and read messages, much like the functionality found in Discord.
Organize chats by date and display a divider indicating the date, similar to features found in apps such as WhatsApp or Telegram.
Scroll to the initial message by clicking on a replied message, like in WhatsApp or Telegram.
Support for emojis using the emoji-mart library for React.
Security
By default, the chat collection prevents the creation of documents by anyone. Therefore, we use API keys with document creation scopes.
Since chat documents are associated with a team_id, any malicious party could potentially create a team chat without the proper permissions.
Thus, every message creation undergoes a stringent verification process, during which we utilize the JWT from the Account API to confirm that the sender is indeed a member of the team.
Only the message creator has the update and delete permissions for the chat, which are achieved through document-based security from Appwrite.
Only the team members have read permissions for the team chat.
Notifications
Appwrite Functions trigger when a chat document is created, generating a separate set of notifications for each team member in a dedicated notification collection.
Users receive real-time notifications when a new chat arrives, or when they open the app later, with caching of chats to minimize server calls.
Real-time read status is accomplished through the notification system, where messages are marked as read when the intended recipients view them. The sender is then notified in real-time about the read status.
Infinite Chat Scroll
- Query cursorAfter and Query limit from Appwrite were used to load previous messages incrementally. The React Intersection Observer was utilized to initiate this process.
UseLayoutEffect
anduseMemo
was used from React to maintain the position of the scrollbar as previous chats are rendered.
- Query cursorAfter and Query limit from Appwrite were used to load previous messages incrementally. The React Intersection Observer was utilized to initiate this process.
SDK Methods used
Create JWT (Account API, Web) - verification
List Documents (Databases API, Web) - list chats, list notifications, list users who read the message
List Team Memberships ( Teams API, Web) - display user profiles for chat
List Team Memberships ( Teams API, Server) - to verify membership on the server
Get Account (Account API, Server) - verification
Create Document ( Databases API, Server) - to create chat after verification
Get File Preview (Storage API, Web) - get user profile images and files preview
Get File for Download (Storage API, Web) - download files shared in chat
Get User Initials (Avatar API, Web) - display avatar if no user profile image exists
Update Document ( Databases API, Server) - to edit the chat, to mark chats notifications as read
Delete Document ( Databases API, Server) - to delete the chat
Delete File ( Storage API, Server) - delete file associated with chat
Extensive use of the event system and caching is employed to ensure real-time performance and optimal speed.
- b‣ Direct Messaging ( DM )
Most of the functionality is similar to group chats; however, in direct messages, we create a unique channel id for communication between two users to query messages. Architecturally, there isn't a significant difference in how Appwrite is utilized, aside from adjustments to suit the direct messaging scenario. Therefore, I won't be explaining this in depth.
The sidebar displays a list of team members available for direct messaging. Additionally, the sidebar is capable of showing notifications for each user who sends you a message within the team.
4‣ Notifications 🔔 (Architecture)
When a user generates data, such as chat messages or tasks, an Appwrite Function is triggered in response to the event of document creation. The function receives the event data, which contains essential information about the document. It then creates documents in a dedicated notifications collection with read permissions only for the intended user.
For chats, a notification is created for each user in the team excluding the message sender. For tasks, members who are assigned the task get notified. In the case of direct messaging, the recipient gets notified.
When users perform the intended task, for example reading the messages in case of chats, the notifications are marked as false and no longer pop up on the screen. If the user is already on the chat screen then notifications are marked as false instantly.
The notifications are read using Appwrite events in real-time, ensuring a smooth communication flow for notifications.
5‣ Tasks 📌
- a‣ UI Overview
The Tasks page shows a list of team tasks with details like name, description, status, priority, assignee, and creator.
Users with "owner" and "admin" roles are permitted to create, edit, delete tasks, and mark tasks as complete. Only the member assigned to the task, along with owners and admins, can mark it as complete, through JWT verification.
In addition to filtering, tasks can be searched by their ID or by searching for their name.
Security is ensured via document-based JWT verification before task creation. Task creation requires an API key with document write scopes, as it's restricted by default.
- b‣ Create Tasks
Here, users with the "owner" or "admin" roles within the team can create tasks and assign them to other members. The assigned member will receive an instant notification indicating that a task has been assigned to them.
Create a task description using the OpenAI GPT-3.5 Turbo API and edit it before creating a task to enhance efficiency.
c‣ Edit Task
Users with the "owner" or "admin" roles can edit and update tasks, as well as mark them as complete.
d‣ Pinning Tasks
Members can prioritize tasks by pinning them and accessing them directly in the "Pinned Tasks" section.
It is implemented by storing pinned tasks in a document with an array attribute, which enables you to toggle tasks as pinned and unpinned.
- e‣ Filtering Tasks using Appwrite Queries
The Appwrite Query feature is used to create various queries for filtering and sorting tasks effectively.
Filter Tasks:
Filter completed tasks.
Filter pending tasks.
Filter tasks assigned to specific team members.
View pending or complete tasks for each team member.
Sort Tasks:
Sort tasks by priority, placing high-priority tasks at the top.
Sort tasks by date of creation.
Sort tasks by the nearest deadline.
- f‣ Add Notes to a Task
- You can create notes for a specific task, such as text, images, or file attachments, to help you work more effectively. For instance, you can save an app's logo as a task note while developing it.
6‣ User Profile 👤
a‣ Profile Page
Here, other users of the platform can view your profile. Set your name, email, and bio, and link your GitHub profile to display your repositories and stats.
All the data is saved as user preferences. An API key with user read scope is required to display information.
SDK Methods used -
Get User Initials (Avatar API, Web) - display avatar if no user profile image exists
Get User (User API, Web) - get user preferences
Get File Preview (Storage API, Web) - get user profile image
b‣ Edit Profile
-
Here, you can edit the user preferences of your profile.
SDK Methods used -
Get User Initials (Avatar API, Web) - display avatar if no user profile image exists
Get User (User API, Web) - get user preferences
Update Name (Account API, Web)
Update Preferences (Account API, Web)
Get User Locale (Locale API, Web) - to update the country of the user
Get File Preview (Storage API, Web) - get user profile image
-
Challenges Faced
Designing features such as efficient caching for the chat system with a sidebar displaying the last message, a robust notification system, and real-time read status proved to be quite challenging for me, especially since this was my first attempt at developing a chat application.
Furthermore, I encountered a challenge in designing the architecture for the task pinning feature, as each user had their own set of pinned tasks, and the pin status needed to be displayed dynamically, updating the button to show either "Pin" or "Unpin" based on the task's current pin status.
Another minor obstacle involved figuring out how to utilize team preferences, as they were not supported by the cloud at the time. However, this issue was quickly resolved by making the design decision to use a dedicated collection for the same.
Aside from that, the development experience was remarkably seamless, and I would like to extend my appreciation to the Appwrite team for creating such a fantastic product.
Credits
I would like to express my gratitude to my teammate Barbra for her unwavering presence, whether it was testing the application, proofreading the blog for grammatical errors, or just being there in general.
Code Repository
Subscribe to my newsletter
Read articles from Nocturnal directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Nocturnal
Nocturnal
I am a 22 year old developer from India who is passionate about learning and creating scalable technology