BalloteerbetaTelegram voting bot for groups and DAOs. Admins create proposals in DM, voters receive private ballots, and the group only sees the final result (quorum + weighted).
1. Add bot
Add @balloteer_bot to your Telegram group and send /start in the group. First person = admin.
2. Members join
Members DM the bot and send /join. Admin gets an approval DM and can set weight (1, 3, custom).
3. Admin creates vote
Admin (in DM) runs /new → title → options → quorum → duration → attachment → choose community.
4. Private voting
Bot DMs every approved voter with buttons (options). They can also run /myvote to change.
5. Close & publish
When deadline hits or admin runs /close, bot posts the final result to the group.
real commands from your current bot code
/start
In a group: creates/updates the community and sets the first user as admin. Also posts the “how it works” message. In DM: explains how to request access (/join) and what admins can do.
Code: calls ensureCommunity(), links admin, initializes voter record.
/join
User sends /join in private. The bot looks at communities and DMs every admin with an approval message. Admin can approve (1 weight, 3 weight, custom) or reject. Until the admin processes, processed = false.
Admin sees inline buttons: approve_..._1, approve_..._3, custom_..., reject_....
/new
Starts a guided flow for admins: title → options → quorum → duration → attachment → choose community. At the end it sends an announcement to the group and DMs all approved voters with a ballot keyboard.
Proposal object is saved in communities[groupId].proposals with status = "open".
Example flow: /new → "Budget approval Q4" → "Approve, Reject" → "30" (quorum) or "skip" → "60" (minutes) → "skip" (no file) → pick community → published
/close
Lists all open proposals of the communities that the admin owns. Admin picks one, bot finalizes it and posts the result in the group using the same formatter as auto-close (with quorum + breakdown).
Uses finalizeProposal() → calls formatResultsSummaryForGroup() and sends to the group.
/myvote
Shows the user all open proposals where they are an approved voter with a weight. User taps the proposal and receives the same inline buttons to change the choice. If they already voted, the bot subtracts the old weight and adds the new one.
Good for: “I didn’t get the DM”, “I want to update my vote”, “I joined later”.
/setweight
Interactive admin-only flow. Admin chooses the community → chooses the approved voter → sends the new weight → sends a reason. Bot updates the voter record and DMs the voter saying the weight changed.
Stored in memory as pendingSetWeight[adminId] with steps CHOOSE_COMMUNITY, CHOOSE_USER, ASK_WEIGHT, ASK_REASON.
/help
Simple command to remind the group/admin/users what they can run. Useful for teams that won't open the web guide.
/connect
First time: Opens a secure link to create your private Solana wallet via Privy (takes ~10 seconds). After creation: Shows your wallet address. Your wallet is 100% private — only you have access. Required for future on-chain voting features.
Uses Privy authentication with Telegram. Wallet info stored securely. No private keys are ever shared with the bot or stored on our servers.