Overview:
Questions and Answers feature has been on Yammer for a while. Instead of a normal post, one can post a question in Yammer for replies by other group members, and amongst the replies received to that question, the poster of the question or the group admin can also mark an answer as the best answer to the question.
The best answer shows up right under the question, making it easy to get right to the information they need.
For organizations that are trying to migrate to Yammer from other discussion posts or forums, it also becomes desirable to migrate questions along with the respective best marked answer to retain originality. This blog post is targeted for such cases.
This article provides steps to implement Yammer Q&A using Yammer API .
Prerequisites
To post Yammer Question & Answer we need a Yammer App client id and Yammer developer token.
Generic instructions about how to register Yammer Applications are available here: https://developer.yammer.com/docs/app-registration
- Once the App is registered, Yammer provides a Client ID, Client Secret, redirect URL and a link to ‘Generate a Developer token for this application’.
- Once the app is created Client Id and Client secret will be generated.
- Now Click on “Generate a developer token for this application” link to generate Yammer Developer Token for this app that can used to connect to Yammer API.
As mentioned in the instruction, copy, and save the following information,
- Yammer App Client ID
- Yammer App Developer Token
Post Question and Answer in Yammer
Below is the empirical sequence of steps to be implemented:
- Step 1: Get the user id by using user email.
- Step 2: Get the user token by using user id.
- Step 3: Post Yammer Question and get the post id.
- Step 4: Post question reply post.
- Step 5: Mark the reply post as “Best Answer”.
Step 1: Get the User ID by using user email
The below function retrieves the user id (User Yammer ID) by using user email and Yammer developer token.
String UserID= GetYammerUserByEmail(YammerUserEmail, YammerDeveloperToken)
public static string GetYammerUserByEmail(string UserEmail, string YammerDeveloperToken)
{
string EndPointURL = "https://www.yammer.com/api/v1/users/by_email.json?email=" + UserEmail;
try{
string ResultJson = null;
HttpWebRequest YammerRequest = HttpWebRequest.Create(EndPointURL) as HttpWebRequest;
YammerRequest.Method = "GET";
YammerRequest.ContentType = "application/json; odata=verbose";
YammerRequest.Accept = "application/json; odata=verbose";
YammerRequest.ContentLength = 0;
YammerRequest.Headers.Add("Authorization", string.Concat("Bearer ", YammerDeveloperToken));
using (HttpWebResponse response = YammerRequest.GetResponse() as HttpWebResponse)
{
Encoding encode = Encoding.GetEncoding("utf-8");
StreamReader reader = new StreamReader(response.GetResponseStream(), encode);
ResultJson = reader.ReadToEnd();
YammerUser[] returnedObject = JsonConvert.DeserializeObject<YammerUser[]>(ResultJson);
return returnedObject[0].Id.ToString ();
}
}
catch (Exception ex)
{return null;}
}
Step 2: Get the user token by using User ID
After the User Id is fetched, pass it to the below function to get the user token.
string UserToken = GetUserTokenByEmail(UserID, YammerAppDevToken, YammerAppClientID);
public static string GetUserTokenByEmail(string UserID, string YammerDeveloperToken, string YammerClientID)
{
string EndPointURL = "https://www.yammer.com/api/v1/oauth.json?user_id=" + UserID.ToString() + "&consumer_key=" + YammerClientID;
try{
string YammerMessageJson = null;
HttpWebRequest YammerRequest = HttpWebRequest.Create(EndPointURL) as HttpWebRequest;
YammerRequest.Method = "POST";
YammerRequest.ContentType = "application/json; odata=verbose";
YammerRequest.Accept = "application/json; odata=verbose";
YammerRequest.ContentLength = 0;
YammerRequest.Headers.Add("Authorization", string.Concat("Bearer ", YammerDeveloperToken));
using (HttpWebResponse response = YammerRequest.GetResponse() as HttpWebResponse)
{
Encoding encode = Encoding.GetEncoding("utf-8");
StreamReader reader = new StreamReader(response.GetResponseStream(), encode);
YammerMessageJson = reader.ReadToEnd();
YammerUserToken UserToken = JsonConvert.DeserializeObject<YammerUserToken>(YammerMessageJson);
return UserToken.Token.ToString();
}
}
catch (WebException ex)
{ return null;}
}
Step 3: Post Yammer Question and get the thread ID
Post the question using user token; pass the Yammer group id where the question along with its User token and message (question) body has to be posted.
In request body specify message_type=question to post a thread as question.
String QuestionThreadId =PostQuestion(YammerGroupId, UserToken, MessageBody);
public static string CreateRootPostInYammerBlog(string YammerGroupID, string UserToken, string MessageBody)
{
string ResponseJson = null;
try{
string EndPointURL = "https://www.yammer.com/api/v1/messages.json";
string YammerNetworkID = UserToken.Split('-').FirstOrDefault();
var data = new StringBuilder();
data.Append("group_id=" + YammerGroupID);
data.Append("&message_type=question");
data.Append("&network_id=" + YammerNetworkID);
data.Append("&body=" + HttpUtility.UrlEncode(MessageBody));
HttpWebRequest YammerRequest = HttpWebRequest.Create(EndPointURL) as HttpWebRequest;
YammerRequest.Headers.Add("Authorization", string.Concat("Bearer ", UserToken));
YammerRequest.Host = "www.yammer.com";
YammerRequest.Method = "POST";
YammerRequest.ContentType = "application/x-www-form-urlencoded";
byte[] ByteData = UTF8Encoding.UTF8.GetBytes(data.ToString());
YammerRequest.ContentLength = ByteData.Length;
Stream YammerRequestStream = YammerRequest.GetRequestStream();
YammerRequestStream.Write(ByteData, 0, ByteData.Length);
YammerRequest.Accept = "application/json; odata=verbose";
string json = string.Empty;
using (HttpWebResponse response = YammerRequest.GetResponse() as HttpWebResponse)
{
Encoding encode = Encoding.GetEncoding("utf-8");
StreamReader reader = new StreamReader(response.GetResponseStream(), encode);
ResponseJson = reader.ReadToEnd();
YammerMessagesColl returnedObject = JsonConvert.DeserializeObject<YammerMessagesColl>(ResponseJson);
return returnedObject.messages[0].thread_id.ToString();
}
}
catch (Exception ex)
{return null;}
}
Step 4: Post question reply post
Now post the reply post for above posted question. Here, pass the above question post id (QuestionThreadId).
Message ReplyPostId = PostReply(YammerGroupId,UserToken,MessageBody,QuestionThreadId);
public static string PostReply(string YammerGroupId, String UserToken, string MessageBody, string QuestionThreadId)
{
string ResponseJson = null;
try
{
string EndPointURL = "https://www.yammer.com/api/v1/messages.json";
string YammerNetworkID = UserToken.Split('-').FirstOrDefault();
var data = new StringBuilder();
data.Append("group_id=" + GroupID);
data.Append("&network_id=" + YammerNetworkID);
data.Append("&replied_to_id=" + QuestionThreadId);
data.Append("&body=" + HttpUtility.UrlEncode(MessageBody));
HttpWebRequest YammerRequest = HttpWebRequest.Create(EndPointURL) as HttpWebRequest;
YammerRequest.Headers.Add("Authorization", string.Concat("Bearer ", accessToken));
YammerRequest.Host = "www.yammer.com";
YammerRequest.Method = "POST";
YammerRequest.ContentType = "application/x-www-form-urlencoded";
YammerRequest.Accept = "application/json; odata=verbose";
byte[] ByteData = UTF8Encoding.UTF8.GetBytes(data.ToString());
YammerRequest.ContentLength = ByteData.Length;
Stream YammerRequestStream = YammerRequest.GetRequestStream();
YammerRequestStream.Write(ByteData, 0, ByteData.Length);
HttpWebResponse YammerResponse = YammerRequest.GetResponse() as HttpWebResponse;
using (HttpWebResponse response = YammerRequest.GetResponse() as HttpWebResponse)
{
Encoding encode = Encoding.GetEncoding("utf-8");
StreamReader reader = new StreamReader(response.GetResponseStream(), encode);
ResponseJson = reader.ReadToEnd();
YammerMessagesColl returnedObject = JsonConvert.DeserializeObject<YammerMessagesColl>(ResponseJson);
return returnedObject.messages[0].id;
}
}
catch (Exception ex)
{
return null;
}
Step 5 : Mark an answer (reply post) as “Best Answer”
A reply post can be now marked as “Best Answer” and will be pinned right under the question.
Note that only an author (person who posted the question) of the question or a group admin can mark an answer (reply post) as a best answer.
In the below example, we will use the author access token to programmatically mark an answer as the “Best Answer”.
In the below function we will pass Question post id (QuestionThreadId), Reply post id (ReplyPostId) and author access token (UserToken) as a parameter.
MarkAsBestAnswer(QuestionThreadId, ReplyPostId, UserToken);
public static string MarkAsBestAnswer(string QuestionThreadId, string ReplyPostId, string UserToken)
{
try
{
String EndPointURL= "https://www.yammer.com/api/v1/questions/"+QuestionThreadId+"/mark_best_reply";
string ResponseJson = null;
HttpWebRequest YammerRequest = HttpWebRequest.Create(EndPointURL) as HttpWebRequest;
YammerRequest.Method = "POST";
YammerRequest.ContentType = "application/json";
YammerRequest.Accept = "application/json; odata=verbose";
YammerRequest.ContentLength = 0;
YammerRequest.Headers.Add("Authorization", string.Concat("Bearer ", UserToken));
string jsonstr = "{\"best_reply_id\":" + ReplyPostId + "}";
byte[] bytes = Encoding.UTF8.GetBytes(jsonstr);
YammerRequest.ContentLength = bytes.Length;
using (var streamWriter = new StreamWriter(YammerRequest.GetRequestStream()))
{
streamWriter.Write(jsonstr);
streamWriter.Flush();
streamWriter.Close();
}
using (HttpWebResponse response = YammerRequest.GetResponse() as HttpWebResponse)
{
Encoding encode = Encoding.GetEncoding("utf-8");
StreamReader reader = new StreamReader(response.GetResponseStream(), encode);
ResponseJson = reader.ReadToEnd();
return ResponseJson;
}
}
catch (Exception ex)
{
return null;
}
}
Note: If the best answer is needed to be marked by using admin token, then get the admin token by passing the admin user email (same way as we get the user token in the step 2) and pass the admin token to the above “MarkAsBestAnswer “ function as a parameter like below
MarkAsBestAnswer(QuestionThreadId, ReplyPostId, AdminToken);
How to fetch the best answer using the above method
First you have to fetch the questions using the bellow endpoint https://www.yammer.com/api/v1/questions/“+QuestionThreadId
Once you get the JSON response you have to check the “best_reply_id” to get the id of the best reply
Hi, what exactly is the QuestionThreadId here? Is it the thread_id field from a response of a /api/v1/messages endpoint?
Yes. You are correct