This is a summary of the work I did for the zulip server and web application as a part of Google Summer of Code 2024.
Zulip: Open-source team chat with topic-based threading
Zulip combines the immediacy of real-time chat with an email threading model. With Zulip, you can catch up on important conversations while ignoring irrelevant ones.
Why Zulip? - Efficient communication with organized team chat.
- Name: Rohan Gudimetla
- Title: Cluster of Priority Features.
- Repository: zulip/zulip
- Mentor: Prakhar Pratyush
- Project Size: Large
- Commits during GSoC
- Pull requests during GSoC
- All commits to zulip/zulip
- All pull requests to zulip/zulip
In Zulip, topics are a way to organize conversations within channels (similar to channels in Slack or IRC) to make communication organized and efficient. Each message in a channel is tied to a specific topic, which acts like a subject line, keeping discussions organized and easy to follow, and to read one conversation at a time.
Currently in Zulip, the links to theses topics are based on:
- Channel ID
- Topic Name
Zulip basically allows users to rename these topics as per their choice. In addition to these, Zulip provides a feature to resolve a topic, which essentially adds a checkmark prefix to topic name. Changing the name of the topic, thus updates the topic links to contain this new name. Thus, the older topic links, which used to contain the older topic name are all invalidated and would be of no use.
This was one of the most requested features, including those from the RUST Community (#1029). Other feature requests for this feature include #21505, #15290, #21738, and #11699.
This project introduces a new with term at the end of the links. This term basically contains message ID of the last message of the topic opened. Now when you rename a topic, or type out the wrong topic names in the links, if there is a with operator, then the link is automatically corrected and the user is redirected to the conversation containing this message ID.
For example, let there be a topic - discussions in the channel core-team. Now, suppose when you open this topic, the id of the first message be 12. Then the topic link would be #narrow/stream/49-core-team/topic/discussions/with/12.
Now, if discussions is renamed to talks. Let's assume the id of the last message in this topic now be 14. Then the new link would be #narrow/stream/49-core-team/topic/talks/with/14. Since the older message ID of 12 still exists in this topic with updated name, the old link (#narrow/stream/49-core-team/topic/discussions/with/12) which contains the with term would still redirect to this updated link, and eventually the older link is corrected to the updated one.
- #30172 refactor: Extract method to create and update message lists in narrow.
- #30244 Preparatory commits to topic permalinks
- #30114 topics: Convert topic links to permalinks.
- #30876 topic permalinks follow up commits
- #30887 topic permalinks follow ups
- #30924 narrow_operators: Add
withoperator tofilter.is_conversation_view.
- #30958 narrow: Update
withoperator behaviour when message not accessible. - #31167 stream_topic_history: Update history to only store acked message ids.
- #31239 narrow: Make
withoperator behaviour consistent with API behaviour.
- #31152 narrow: Adjust topic channel-narrows to always contain
withoperator. - #30644 Convert #-mentions and topic links to topic permalinks.
- Possible bug fixes in this area.
Previously, Zulip's landing /for pages' screenshots, which used to represent conversations in a topic were generated using Figma. This would make it really difficult to maintain these images up to date owing to the constant developments taking place in Zulip. This was a feature request in #30016, and #30128.
These pages were zulip.com/for/research, zulip.com/for/events, zulip.com/for/education and zulip.com/for/business.
- This project introduces a script --
./tools/screenshots/generate-user-messages-screenshot --thread, which would generate message screenshots based on a.jsonfile you provide it, which contains the content of the conversation. Since the.jsonessentially remains the same, the screenshots for these pages can easily be updated by just running the script with proper.jsonfiles. - Updated screenshots in outdated
zulip.com/for/research,zulip.com/for/events,zulip.com/for/educationandzulip.com/for/businesspages.
- #30061 portico: Add script to auto-generate message screenshots /for/research.
- #30159 portico: Update screenshots for "for/X" pages.
- Previously in Zulip, Direct Message Groups were referred to as Huddles. This is in contrast to various other chat services. Hence, first part of this project revolves around migrating these ~900 instances of Huddles to Direct Message Groups.
- Previously in Zulip, the 1:1 DMs and Direct Message Groups were represented by separate models and tables. This is a huge blocker for implementing any feature that revolves around DMs such as pinning and hiding of Direct Message chats, since there need to be some consistency around 1:1 DMs and Direct Message Groups.
This is a feature request in #25713, which is a blocker for other features like #24023 and #11842.
- Migrated ~800 instances of
HuddlestoDirect Message Groups, spread across frontend, backend, models and table names. - Started work towards migrating 1:1 DMs to be represented by Direct Message Groups.
- #30377 refactor: Rename
huddletodirect message groupin web codebase. - #30730 refactor: Rename
huddletodirect_message_groupin non API. - #30741 refactor: Rename
HuddletoDirectMessageGroupin the model class. - #30766 refactor: Complete rename of
huddletodirect_message_groupin non api files. - #31390 direct_message_group: Add new
group_sizefield.
- Complete the remaining work pending in #25713.
In a large project like Zulip, we have >600 Django migrations. In such a project which grows at a really fast pace, we often need to rebase migraions in our existing branches. However, there are 2 problems with the existing tool for rebasing migrations in Zulip:
- We never know whether we need to rebase our branch's migrations and that there are conflicting migrations in our project, until we push our changes.
- Using the current tool to rebase migrations in our branch with >2 migrations, with the branch being >5 migrations behind is a huge pain. On the top of that, we must be really sure that our migrations are unapplied, before rebasing them.
This project tries to resolve this issue by using a new library - django-linear-migrations, as suggested in the CZO thread. However, the project was not ready to be used to Zulip, due to certain limitations. This project aimed at resolving those implementations:
- Allow user to rebase chains of >2 migrations in a single app (currently only 1 migrations is allowed to be rebased in an app).
- Automatically unapply migrations and rebase them if migrations already applied (currently, it throws an error asking the user to rebase them rather). , and getting it ready to be used in Zulip.
- #343: rebase-migration: Make it possible to handle chains of migrations.
- #346: rebase_migration: Unapply migrations while rebase.
- Getting these PRs merged, and getting Zulip ready to use this library.
Independent Bug Fixes and Features (Merged, Open and Closed).
- #28980 topics: Apply automatic follow/unmute when message moved to new topic.
- #29926 settings: Add synchronization in deactivating users.
- #29965 settings: Allow "resolve topic" permissions to be managed independently
- #28766 user_status: Allow users to set the status end time to clear the status.
- #29705 typing: Move the typing notifications to below the mark as read banner.
- #30271 narrow: Fix server error of operand of "id" operator at large values.
- #30753 recipient_row: Remove extra whitespace around recipient full name.
- #30773 popovers: Fix page reload on enter in move message modal.
- #30777 popovers: Skip updating url hash when clicked on "View user profile".
- #30850 user_group_settings: Disable dropdown if no permission to update it.
- #31017 settings: Add setting to control how animated images are played.
- #31089 lightbox: Update
canonical_url_of_mediato use URL pathname.
My journey at Google Summer of Code with Zulip has turned out to be one of the best moments during my 3 years of College. During this period, I got to learn a ton, ranging from writing good quality code which is easy to review, to reviewing other contributors' code.
Zulip has made me really confident in my Git skills and ability to solve problems. Working with Zulip over the past few months has instilled a lot of interest in coding and Software Engineering into me, and taught me a lot, which I have never learnt or enjoyed in my 3 years of college.
One aspect that I definitely feel I learnt from this summer is reusing existing components, and reading and understanding my code twice, before opening a PR. This has made realise me how important it is to write tests for even a really small functionality to be sure that the code works as expected, and not look at tests as just something to get the coverage to pass the CI.
Lastly, I would like to thank Prakhar Pratyush and Tim Abbott for guiding me through all my projects, teaching me about different angles to think about in a project, being patient with me, and helping me to improve the quality of code I write consistently. I would also like to thank Greg Price for the in depth analysis he used to provide while discussing about the APIs, especially while working on permalinks project. Lastly, I would thank my buddy Kunal Sharma, for providing initial review of all my pull requests during the summer.
Thanks to the maintainers for making Zulip such a healthy and great community.

