diff --git a/bindings/group.go b/bindings/group.go index a1f32b34e9c613bbb4357f6c2705ee930a7d3c01..e0da4aff7b437dac7de98d07957a0da14b6888d9 100644 --- a/bindings/group.go +++ b/bindings/group.go @@ -124,8 +124,8 @@ func (g *GroupChat) Send(groupIdBytes, message []byte) (*GroupSendReport, error) return nil, errors.Errorf("Failed to unmarshal group ID: %+v", err) } - round, timestamp, err := g.m.Send(groupID, message) - return &GroupSendReport{round, timestamp}, err + round, timestamp, msgID, err := g.m.Send(groupID, message) + return &GroupSendReport{round, timestamp, msgID}, err } // GetGroups returns an IdList containing a list of group IDs that the user is a @@ -239,6 +239,7 @@ func (ngr *NewGroupReport) Unmarshal(b []byte) error { type GroupSendReport struct { roundID id.Round timestamp time.Time + messageID group.MessageID } // GetRoundID returns the ID of the round that the send occurred on. @@ -257,6 +258,11 @@ func (gsr *GroupSendReport) GetTimestampMS() int64 { return int64(ts) } +// GetMessageID returns the ID of the round that the send occurred on. +func (gsr *GroupSendReport) GetMessageID() []byte { + return gsr.messageID[:] +} + //// // Group Structure //// diff --git a/cmd/group.go b/cmd/group.go index b973fb5c7f2b7addcb12a26c2a59b7b4c1524c22..1c7365921187bc6fda2754b2950498709c5f46f9 100644 --- a/cmd/group.go +++ b/cmd/group.go @@ -218,7 +218,7 @@ func sendGroup(groupIdString string, msg []byte, gm *groupChat.Manager) { jww.INFO.Printf("Sending to group %s message %q", groupID, msg) - rid, timestamp, err := gm.Send(groupID, msg) + rid, timestamp, _, err := gm.Send(groupID, msg) if err != nil { jww.FATAL.Panicf("Sending message to group %s: %+v", groupID, err) } diff --git a/groupChat/send.go b/groupChat/send.go index 868d420134b6ebb79c0687f58648311af6445559..e626e1959dea8a47c44f462c38fba7b68521353d 100644 --- a/groupChat/send.go +++ b/groupChat/send.go @@ -37,15 +37,15 @@ const ( // Send sends a message to all group members using Client.SendManyCMIX. The // send fails if the message is too long. -func (m *Manager) Send(groupID *id.ID, message []byte) (id.Round, time.Time, +func (m *Manager) Send(groupID *id.ID, message []byte) (id.Round, time.Time, group.MessageID, error) { // Get the current time stripped of the monotonic clock timeNow := netTime.Now().Round(0) // Create a cMix message for each group member - messages, err := m.createMessages(groupID, message, timeNow) + messages, msgID, err := m.createMessages(groupID, message, timeNow) if err != nil { - return 0, time.Time{}, errors.Errorf(newCmixMsgErr, err) + return 0, time.Time{}, group.MessageID{}, errors.Errorf(newCmixMsgErr, err) } param := params.GetDefaultCMIX() @@ -53,28 +53,38 @@ func (m *Manager) Send(groupID *id.ID, message []byte) (id.Round, time.Time, rid, _, err := m.net.SendManyCMIX(messages, param) if err != nil { - return 0, time.Time{}, + return 0, time.Time{}, group.MessageID{}, errors.Errorf(sendManyCmixErr, m.gs.GetUser().ID, groupID, err) } jww.DEBUG.Printf("Sent message to %d members in group %s at %s.", len(messages), groupID, timeNow) - return rid, timeNow, nil + return rid, timeNow, msgID, nil } // createMessages generates a list of cMix messages and a list of corresponding // recipient IDs. func (m *Manager) createMessages(groupID *id.ID, msg []byte, timestamp time.Time) ( - []message.TargetedCmixMessage, error) { + []message.TargetedCmixMessage, group.MessageID, error) { + + //make the message ID + cmixMsg := format.NewMessage(m.store.Cmix().GetGroup().GetP().ByteLen()) + _, intlMsg, err := newMessageParts(cmixMsg.ContentsSize()) + if err != nil { + return nil, group.MessageID{},errors.WithMessage(err,"Failed to make message parts for message ID") + } + messageID := group.NewMessageID(groupID, setInternalPayload(intlMsg, timestamp, m.gs.GetUser().ID, msg)) g, exists := m.gs.Get(groupID) if !exists { - return []message.TargetedCmixMessage{}, + return []message.TargetedCmixMessage{}, group.MessageID{}, errors.Errorf(newNoGroupErr, groupID) } - return m.newMessages(g, msg, timestamp) + NewMessages, err := m.newMessages(g, msg, timestamp) + + return NewMessages, messageID, err } // newMessages is a private function that allows the passing in of a timestamp diff --git a/groupChat/send_test.go b/groupChat/send_test.go index 8fd29ba8c60719ef6f0ca2eff8c1d39049ef1c42..2d6940c3a69dbe3b894481e738d6fbb1d7974e45 100644 --- a/groupChat/send_test.go +++ b/groupChat/send_test.go @@ -30,7 +30,7 @@ func TestManager_Send(t *testing.T) { messageBytes := []byte("Group chat message.") sender := m.gs.GetUser().DeepCopy() - _, _, err := m.Send(g.ID, messageBytes) + _, _, _, err := m.Send(g.ID, messageBytes) if err != nil { t.Errorf("Send() returned an error: %+v", err) } @@ -110,7 +110,7 @@ func TestManager_Send_CmixMessageError(t *testing.T) { expectedErr := strings.SplitN(newCmixMsgErr, "%", 2)[0] // Send message - _, _, err := m.Send(g.ID, make([]byte, 400)) + _, _, _, err := m.Send(g.ID, make([]byte, 400)) if err == nil || !strings.Contains(err.Error(), expectedErr) { t.Errorf("Send() failed to return the expected error."+ "\nexpected: %s\nreceived: %+v", expectedErr, err) @@ -125,7 +125,7 @@ func TestManager_Send_SendManyCMIXError(t *testing.T) { expectedErr := strings.SplitN(sendManyCmixErr, "%", 2)[0] // Send message - _, _, err := m.Send(g.ID, []byte("message")) + _, _, _, err := m.Send(g.ID, []byte("message")) if err == nil || !strings.Contains(err.Error(), expectedErr) { t.Errorf("Send() failed to return the expected error."+ "\nexpected: %s\nreceived: %+v", expectedErr, err) @@ -145,7 +145,7 @@ func TestManager_createMessages(t *testing.T) { testMsg := []byte("Test group message.") sender := m.gs.GetUser() - messages, err := m.createMessages(g.ID, testMsg, netTime.Now()) + messages, _, err := m.createMessages(g.ID, testMsg, netTime.Now()) if err != nil { t.Errorf("createMessages() returned an error: %+v", err) } @@ -205,7 +205,7 @@ func TestManager_createMessages_InvalidGroupIdError(t *testing.T) { m, _ := newTestManagerWithStore(prng, 10, 0, nil, nil, t) // Read message and make sure the error is expected - _, err := m.createMessages( + _, _, err := m.createMessages( id.NewIdFromString("invalidID", id.Group, t), nil, time.Time{}) if err == nil || !strings.Contains(err.Error(), expectedErr) { t.Errorf("createMessages() did not return the expected error."+