@@ -20,6 +20,7 @@ import {
2020 MessageGenerationOptionsFromContent ,
2121 MessageType ,
2222 MessageUserReceipt ,
23+ VoteAggregation ,
2324 WAMediaUpload ,
2425 WAMessage ,
2526 WAMessageContent ,
@@ -37,6 +38,7 @@ import {
3738 getAudioDuration ,
3839 MediaDownloadOptions
3940} from "./messages-media" ;
41+ import { sha256 } from "./crypto" ;
4042
4143type MediaUploadData = {
4244 media : WAMediaUpload ;
@@ -707,6 +709,74 @@ export const updateMessageWithReaction = (
707709 msg . reactions = reactions ;
708710} ;
709711
712+ /** Update the message with a new poll update */
713+ export const updateMessageWithPollUpdate = (
714+ msg : Pick < WAMessage , "pollUpdates" > ,
715+ update : proto . IPollUpdate
716+ ) => {
717+ const authorID = getKeyAuthor ( update . pollUpdateMessageKey ) ;
718+
719+ const reactions = ( msg . pollUpdates || [ ] ) . filter (
720+ r => getKeyAuthor ( r . pollUpdateMessageKey ) !== authorID
721+ ) ;
722+ if ( update . vote ?. selectedOptions ?. length ) {
723+ reactions . push ( update ) ;
724+ }
725+
726+ msg . pollUpdates = reactions ;
727+ } ;
728+
729+ /**
730+ * Aggregates all poll updates in a poll.
731+ * @param msg the poll creation message
732+ * @param meId your jid
733+ * @returns A list of options & their voters
734+ */
735+ export function getAggregateVotesInPollMessage ( {
736+ message,
737+ pollUpdates
738+ } : Pick < WAMessage , "pollUpdates" | "message" > ) {
739+ const opts =
740+ message ?. pollCreationMessage ?. options ||
741+ message ?. pollCreationMessageV2 ?. options ||
742+ message ?. pollCreationMessageV3 ?. options ||
743+ [ ] ;
744+ const voteHashMap = opts . reduce (
745+ ( acc , opt ) => {
746+ const hash = sha256 ( Buffer . from ( opt . optionName || "" ) ) . toString ( ) ;
747+ acc [ hash ] = {
748+ name : opt . optionName || "" ,
749+ voters : [ ]
750+ } ;
751+ return acc ;
752+ } ,
753+ { } as { [ _ : string ] : VoteAggregation }
754+ ) ;
755+
756+ for ( const update of pollUpdates || [ ] ) {
757+ const { vote } = update ;
758+ if ( ! vote ) {
759+ continue ;
760+ }
761+
762+ for ( const option of vote . selectedOptions || [ ] ) {
763+ const hash = option . toString ( ) ;
764+ let data = voteHashMap [ hash ] ;
765+ if ( ! data ) {
766+ voteHashMap [ hash ] = {
767+ name : "Unknown" ,
768+ voters : [ ]
769+ } ;
770+ data = voteHashMap [ hash ] ;
771+ }
772+
773+ voteHashMap [ hash ] ! . voters . push ( getKeyAuthor ( update . pollUpdateMessageKey ) ) ;
774+ }
775+ }
776+
777+ return Object . values ( voteHashMap ) ;
778+ }
779+
710780/** Given a list of message keys, aggregates them by chat & sender. Useful for sending read receipts in bulk */
711781export const aggregateMessageKeysNotFromMe = ( keys : proto . IMessageKey [ ] ) => {
712782 const keyMap : {
0 commit comments