code: func (b *Bslack) populateReceivedMessage(ev *slack.MessageEvent) (*config.Message, error) {
  	// Use our own func because rtm.GetChannelInfo doesn't work for private channels.
  	channel, err := b.channels.getChannelByID(ev.Channel)
  	if err != nil {
  		return nil, err
  	}
  
  	rmsg := &config.Message{
  		Text:     ev.Text,
  		Channel:  channel.Name,
  		Account:  b.Account,
  		ID:       ev.Timestamp,
  		Extra:    make(map[string][]interface{}),
  		ParentID: ev.ThreadTimestamp,
  		Protocol: b.Protocol,
  	}
  	if b.useChannelID {
  		rmsg.Channel = "ID:" + channel.ID
  	}
  
  	// Handle 'edit' messages.
  	if ev.SubMessage != nil && !b.GetBool(editDisableConfig) {
  		rmsg.ID = ev.SubMessage.Timestamp
  		if ev.SubMessage.ThreadTimestamp != ev.SubMessage.Timestamp {
  			b.Log.Debugf("SubMessage %#v", ev.SubMessage)
  			rmsg.Text = ev.SubMessage.Text + b.GetString(editSuffixConfig)
  		}
  	}
  
  	// For edits, only submessage has thread ts.
  	// Ensures edits to threaded messages maintain their prefix hint on the
  	// unthreaded end.
  	if ev.SubMessage != nil {
  		rmsg.ParentID = ev.SubMessage.ThreadTimestamp
  	}
  
  	if err = b.populateMessageWithUserInfo(ev, rmsg); err != nil {
  		return nil, err
  	}
  	return rmsg, err
  }
docs: // populateReceivedMessage shapes the initial Matterbridge message that we will forward to the
  // router before we apply message-dependent modifications.