function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Daniel Watson 21Daniel Watson 21 

ConnectApi.ConnectApiException: Must have value for exactly one of the following: username, id

I am not sure if this is a new change from v43.0 but I am unable to get my Apex to post to chatter.

I have an "Administrator" case RecordType and if it has children case, once and update is processed on the child case, a chatter post will be posted to the parent with an @menttion to the owner.

CODE:
if (Trigger.isUpdate) {
            if (newCase.ParentId != null) { 					// If case has a parent case
            	for (Case c : ParentAdminCases) { //<-- bulk soql'ed outside of trigger loop.
            		if(c.ParentId == newCase.ParentId) {		// If cases parent is of type admin.
            			ConnectApi.FeedItemInput feedItemInput = new ConnectApi.FeedItemInput();
						ConnectApi.MentionSegmentInput mentionSegmentInput = new ConnectApi.MentionSegmentInput();
						ConnectApi.MessageBodyInput messageBodyInput = new ConnectApi.MessageBodyInput();
						ConnectApi.TextSegmentInput textSegmentInput = new ConnectApi.TextSegmentInput();
						
						messageBodyInput.messageSegments = new List<ConnectApi.MessageSegmentInput>();
						
						mentionSegmentInput.id = newCase.Parent.OwnerId; // Set @mention
						messageBodyInput.messageSegments.add(mentionSegmentInput);
						
						textSegmentInput.text = 'Blah blah blah blha';
						messageBodyInput.messageSegments.add(textSegmentInput);
						
						feedItemInput.body = messageBodyInput;
						feedItemInput.feedElementType = ConnectApi.FeedElementType.FeedItem;
						feedItemInput.subjectId = newCase.ParentId; 
						
						ConnectApi.FeedElement feedElement = ConnectApi.ChatterFeeds.postFeedElement(Network.getNetworkId(), feedItemInput);
						
            			break;
            		}
            	}
            }
        }
My code compiles, but when I attempt to edit the child case I get the error in the description:
  • ConnectApi.ConnectApiException: Must have value for exactly one of the following: username, id
and am unbale to save the child record.

Other threads I have poured over seem to hint that it is a user permissions issue, but I am testing with the supper admin in a sandbox, so not sure what else I would need access to.

Seems like over the versions of the API there has been a varieance of signatures for the postFeedElement() method, so wondering if my issue is there.

Any advice would be much apreciated.

Thanks!
Best Answer chosen by Daniel Watson 21
PawanKumarPawanKumar
Hi Daniel,

Thanks for trying my suggestion. I was just trying to troubleshoot your issue. I have just hardcode value and working fine. 

----------------------
ConnectApi.FeedItemInput feedItemInput = new ConnectApi.FeedItemInput();
ConnectApi.MentionSegmentInput mentionSegmentInput = new ConnectApi.MentionSegmentInput();
ConnectApi.MessageBodyInput messageBodyInput = new ConnectApi.MessageBodyInput();
ConnectApi.TextSegmentInput textSegmentInput = new ConnectApi.TextSegmentInput();

messageBodyInput.messageSegments = new List<ConnectApi.MessageSegmentInput>();

mentionSegmentInput.id = '00590000001QrPW'; // Set @mention
messageBodyInput.messageSegments.add(mentionSegmentInput);

textSegmentInput.text = 'Blah blah blah blha';
messageBodyInput.messageSegments.add(textSegmentInput);

feedItemInput.body = messageBodyInput;
feedItemInput.feedElementType = ConnectApi.FeedElementType.FeedItem;
feedItemInput.subjectId = '5009000000BM6pN'; 

ConnectApi.FeedElement feedElement = ConnectApi.ChatterFeeds.postFeedElement(Network.getNetworkId(), feedItemInput);
------------------

Above code is working with hard-coded values. so the only problem I see is the expression [newCase.Parent.OwnerId] is returning null. so debug this line and see you are getting any value. or shorter way is just put below line just for troubleshooting.

 mentionSegmentInput.id = newCase.OwnerId; // this line will not null at all.
 

All Answers

PawanKumarPawanKumar
I think the problem is here.
feedItemInput.subjectId = newCase.ParentId;

The Connect API doesn't support impersonation (posting a feed item as a different user). It's not possible to call ConnectApi.ChatterFeeds.postFeedItem() and have the feed item posted as John Doe unless John Doe is the current, logged-in user. In your code, you're using the userId as the third parameter, which is the subjectId -- that's the parent of the feed item, not the author of the feed item.

Please try as below and see if it works for you. 
feedItemInput.subjectId = userinfo.getuserid()​;

Please mark it best if it helps you. Thanks.

Regards,
Pawan Kumar
Daniel Watson 21Daniel Watson 21
Pawan, Thanks for your response.

I updated my code with your sugestion, feedItemInput.subjectId = UserInfo.getUserId(); and still recieved the same "ConnectApi.ConnectApiException: Must have value for exactly one of the following: username, id" error.

Seconondly though, from my understnding of this Chatter REST API documentation (https://developer.salesforce.com/docs/atlas.en-us.chatterapi.meta/chatterapi/connect_requests_feed_item_input.htm), the subjectId of the feedItemInput class is the record that the FeedItem will be posted to. As a part of the requirnment, I need the feed Item to be posted to the childs Cases parent Case.

Thanks for any additional assistance.
PawanKumarPawanKumar
Hi Daniel,

Thanks for trying my suggestion. I was just trying to troubleshoot your issue. I have just hardcode value and working fine. 

----------------------
ConnectApi.FeedItemInput feedItemInput = new ConnectApi.FeedItemInput();
ConnectApi.MentionSegmentInput mentionSegmentInput = new ConnectApi.MentionSegmentInput();
ConnectApi.MessageBodyInput messageBodyInput = new ConnectApi.MessageBodyInput();
ConnectApi.TextSegmentInput textSegmentInput = new ConnectApi.TextSegmentInput();

messageBodyInput.messageSegments = new List<ConnectApi.MessageSegmentInput>();

mentionSegmentInput.id = '00590000001QrPW'; // Set @mention
messageBodyInput.messageSegments.add(mentionSegmentInput);

textSegmentInput.text = 'Blah blah blah blha';
messageBodyInput.messageSegments.add(textSegmentInput);

feedItemInput.body = messageBodyInput;
feedItemInput.feedElementType = ConnectApi.FeedElementType.FeedItem;
feedItemInput.subjectId = '5009000000BM6pN'; 

ConnectApi.FeedElement feedElement = ConnectApi.ChatterFeeds.postFeedElement(Network.getNetworkId(), feedItemInput);
------------------

Above code is working with hard-coded values. so the only problem I see is the expression [newCase.Parent.OwnerId] is returning null. so debug this line and see you are getting any value. or shorter way is just put below line just for troubleshooting.

 mentionSegmentInput.id = newCase.OwnerId; // this line will not null at all.
 
This was selected as the best answer
Daniel Watson 21Daniel Watson 21
AH HA!

I Remember running into this issue a long time ago now... Thank you, as soon as I commented out the line refering to the multiple relationship lookup, I.E.
//mentionSegmentInput.id = newCase.Parent.OwnerId;
//messageBodyInput.messageSegments.add(mentionSegmentInput);
it began to work... I feel a little silly that I missed the null shellout...

I should be able to take it from here. Thanks so much for your fresh point of view on this!

Accepting your answer!