public static async Task HandleCandidateCommand(IDialogContext context, Activity activity, string[] keywords) { // Supports either structured query or via user input. JObject ctx = activity.Value as JObject; Candidate c = null; if (ctx != null) { c = ctx.ToObject <Candidate>(); await SendCandidateDetailsMessage(context, c); } else if (keywords.Length > 0) { string name = string.Join(" ", keywords); c = new CandidatesDataController().GetCandidateByName(name); await SendCandidateDetailsMessage(context, c); } }
/// <summary> /// Helper method to create a simple task card and send it back as a message. /// </summary> /// <param name="context"></param> /// <param name="reqId"></param> /// <returns></returns> private async Task SendTopCandidatesMessage(IDialogContext context, string reqId) { // Create a message object. IMessageActivity reply = context.MakeMessage(); reply.Attachments = new List <Attachment>(); reply.Text = $"Okay, here are top candidates who have recently applied to your position"; // Create the task using the data controller. var candidates = new CandidatesDataController().GetTopCandidates(reqId); reply.AttachmentLayout = AttachmentLayoutTypes.Carousel; foreach (Candidate c in candidates) { var card = CardHelper.CreateSummaryCardForCandidate(c); reply.Attachments.Add(card.ToAttachment()); } // Send the message back to the user. await context.PostAsync(reply); }
/// <summary> /// Helper method to generate a the messaging extension response. /// /// Note that for this sample, we are returning generated positions for illustration purposes only. /// </summary> /// <returns></returns> public ComposeExtensionResponse CreateResponse() { ComposeExtensionResponse response = null; var query = activity.GetComposeExtensionQueryData(); JObject data = activity.Value as JObject; // Check if this is a task module invocation. if (data != null && data["type"] != null) { // Handle other types of Invoke activities here, e.g. CardActions if (data["type"].ToString() == TaskModuleCommandType && data["command"].ToString() == CreatePostingCommand) { response = CreateTaskModuleResponse(); } } else { //Check to make sure a query was actually made: if (query.CommandId == null || query.Parameters == null) { return(null); } else if (query.Parameters.Count > 0) { // query.Parameters has the parameters sent by client var results = new ComposeExtensionResult() { AttachmentLayout = "list", Type = "result", Attachments = new List <ComposeExtensionAttachment>(), }; if (query.CommandId == "searchPositions") { OpenPositionsDataController controller = new OpenPositionsDataController(); IEnumerable <OpenPosition> positions; if (query.Parameters[0].Name == "initialRun") { // Default query => list all positions = controller.ListOpenPositions(10); } else { // Basic search. string title = query.Parameters[0].Value.ToString().ToLower(); positions = controller.ListOpenPositions(10).Where(x => x.Title.ToLower().Contains(title)); } // Generate cards for the response. foreach (OpenPosition pos in positions) { var card = CardHelper.CreateCardForPosition(pos, true); var composeExtensionAttachment = card.ToAttachment().ToComposeExtensionAttachment(); results.Attachments.Add(composeExtensionAttachment); } } else if (query.CommandId == "searchCandidates") { string name = query.Parameters[0].Value.ToString(); CandidatesDataController controller = new CandidatesDataController(); foreach (Candidate c in controller.GetTopCandidates("ABCD1234")) { c.Name = c.Name.Split(' ')[0] + " " + CultureInfo.CurrentCulture.TextInfo.ToTitleCase(name); var card = CardHelper.CreateSummaryCardForCandidate(c); var composeExtensionAttachment = card.ToAttachment().ToComposeExtensionAttachment(CardHelper.CreatePreviewCardForCandidate(c).ToAttachment()); results.Attachments.Add(composeExtensionAttachment); } } response = new ComposeExtensionResponse() { ComposeExtension = results }; } } return(response); }
/// <summary> /// This is where you can process the incoming user message and decide what to do. /// </summary> /// <param name="context"></param> /// <param name="result"></param> /// <returns></returns> private async Task MessageReceivedAsync(IDialogContext context, IAwaitable <object> result) { var activity = await result as Activity; // Strip out all mentions. As all channel messages to a bot must @mention the bot itself, you must strip out the bot name at minimum. // This uses the extension SDK function GetTextWithoutMentions() to strip out ALL mentions var text = activity.GetTextWithoutMentions(); if (text == null) { await HandleSubmitAction(context, activity); } else { // Supports 5 commands: Help, Welcome (sent from HandleSystemMessage when bot is added), top candidates, schedule interview, and open positions. // This simple text parsing assumes the command is the first two tokens, and an optional parameter is the second. var split = text.Split(' '); // The user is asking for onen of the supported commands. if (split.Length >= 2) { var cmd = split[0].ToLower(); var keywords = split.Skip(2).ToArray(); // Parse the command and go do the right thing if (cmd.Contains("top") && keywords.Length > 0) { await SendTopCandidatesMessage(context, keywords[0]); } else if (cmd.Contains("schedule")) { // Supports either structured query or via user input. JObject ctx = activity.Value as JObject; // Check if this is a button press or a text command. if (ctx != null) { Candidate c = ctx.ToObject <Candidate>(); await SendScheduleInterviewMessage(context, c, c.ReqId); } else if (keywords.Length == 3) { string name = string.Join(" ", keywords.Take(2).ToArray()); string reqId = keywords[2]; // Takes 3 parameters: first name, last name, and then req ID await SendScheduleInterviewMessage(context, name, reqId); } else { await SendHelpMessage(context, "I'm sorry, I did not understand you :("); } } else if (cmd.Contains("open")) { await SendOpenPositionsMessage(context); } else if (cmd.Contains("resume")) { // Return "resume file" for the given candidate name. if (keywords.Length > 0) { string name = string.Join(" ", keywords).ToLower(); IMessageActivity reply = context.MakeMessage(); reply.Attachments = new List <Attachment>(); JObject card = new JObject(); card["description"] = $"Here is the resume for {name}"; card["sizeInBytes"] = 1500; Attachment attachment = new Attachment() { ContentType = "application/vnd.microsoft.teams.card.file.consent", Name = $"{name} resume.pdf", Content = card }; reply.Attachments.Add(attachment); await context.PostAsync(reply); } } else if (cmd.Contains("candidate")) { // Supports either structured query or via user input. JObject ctx = activity.Value as JObject; Candidate c = null; if (ctx != null) { c = ctx.ToObject <Candidate>(); await SendCandidateDetailsMessage(context, c); } else if (keywords.Length > 0) { string name = string.Join(" ", keywords); c = new CandidatesDataController().GetCandidateByName(name); await SendCandidateDetailsMessage(context, c); } } else if (cmd.Contains("new")) { await SendCreateNewJobPostingMessage(context); } else if (cmd.Contains("assign")) { string guid = split[1]; await UpdateMessage(context, guid); } else { await SendHelpMessage(context, "I'm sorry, I did not understand you :("); } } else { int magicCode; if (int.TryParse(text, out magicCode)) { // If the user is pasting a magic number, check if that's to get an auth token. // TODO: This shouldn't be necessary once we make some small fixes to the bot auth service. var oauthClient = activity.GetOAuthClient(); var token = await oauthClient.OAuthApi.GetUserTokenAsync(activity.From.Id, ConnectionName, magicCode : activity.Text).ConfigureAwait(false); if (token != null) { Microsoft.Graph.User current = await new GraphUtil(token.Token).GetMe(); await context.PostAsync($"Success! You are now signed in as {current.DisplayName} with {current.Mail}"); } } else if (text.Contains("help")) { // Respond with standard help message. await SendHelpMessage(context, "Sure, I can provide help info about me."); } else if (text.Contains("login")) { await SendOAuthCardAsync(context, activity); } else if (text.Contains("welcome") || text.Contains("hello") || text.Contains("hi")) { await SendHelpMessage(context, "## Welcome to the Contoso Talent Management app"); } else // Don't know what to say so this is the generic handling here. { await SendHelpMessage(context, "I'm sorry, I did not understand you :("); } } } context.Wait(MessageReceivedAsync); }