private static async Task <IActionResult> UpdatePlanMessage(IBinder binder, InteractiveMessagePayload payload, Plan plan, string ephemeralText) { if (payload.OriginalMessage != null) { // Message publique var message = new UpdateMessageRequest { Text = payload.OriginalMessage.Text, Channel = payload.Channel.Id, Timestamp = payload.MessageTimestamp, Attachments = { await MessageHelpers.GetPlanAttachment(binder, plan) } }; await SlackHelper.UpdateMessage(binder, payload.Team.Id, message); return(Utils.Ok()); } else { // Message ephémère var message = new SlackMessage { Text = ephemeralText, Attachments = { await MessageHelpers.GetPlanAttachment(binder, plan) }, ReplaceOriginal = true }; message.Attachments.Add(MessageHelpers.GetRemoveMessageAttachment()); return(Utils.Ok(message)); } }
private static async Task RecordVotes(IBinder binder, DialogSubmissionPayload payload) { var votesTable = await binder.GetTable("votes"); var plansTable = await binder.GetTable("plans"); var vote = await votesTable.Retrieve <Vote>(Utils.GetPartitionKeyWithAddon(payload.PartitionKey, payload.State), payload.User.Id) ?? new Vote(payload.Team.Id, payload.Channel.Id, payload.State, payload.User.Id); vote.Proposal1 = payload.Submission["proposal1"]; vote.Proposal2 = payload.Submission["proposal2"]; vote.Proposal3 = payload.Submission["proposal3"]; var result = await votesTable.ExecuteAsync(TableOperation.InsertOrReplace(vote)); if (result.IsError()) { await MessageHelpers.PostErrorMessage(binder, payload); return; } // TODO: Afficher les résultats en temps réel? var plan = await plansTable.Retrieve <Plan>(payload.PartitionKey, payload.State); var message = new PostEphemeralRequest { User = payload.User.Id, Channel = payload.Channel.Id, Text = $"Merci! Vos votes pour le vidéo du {plan.Date:d MMMM} ont bien été reçus.", Attachments = { MessageHelpers.GetRemoveMessageAttachment() } }; await SlackHelper.PostEphemeral(binder, payload.Team.Id, message); }
public static async Task <IActionResult> OnNext( [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "slack/commands/next")] HttpRequest req, [Table("plans")] CloudTable plansTable, IBinder binder, ExecutionContext context) { Utils.SetCulture(); var body = await SlackHelper.ReadSlackRequest(req, context); var parameters = SlackHelper.ParseBody(body); var partitionKey = Utils.GetPartitionKey(parameters["team_id"], parameters["channel_id"]); var futurePlansQuery = new TableQuery <Plan>() .Where( TableQuery.CombineFilters( TableQuery.GenerateFilterCondition("PartitionKey", "eq", partitionKey), "and", TableQuery.GenerateFilterConditionForDate("Date", "ge", DateTime.Now)) ); var futurePlans = await plansTable.ExecuteQueryAsync(futurePlansQuery); var attachmentTasks = futurePlans.OrderBy(x => x.Date).Select(x => MessageHelpers.GetPlanAttachment(binder, x)); var message = new SlackMessage { Text = futurePlans.Any() ? "Voici les Lunch & Watch planifiés :" : "Aucun Lunch & Watch n'est à l'horaire. Utilisez `/edu:plan` pour en planifier un!", Attachments = (await Task.WhenAll(attachmentTasks)).ToList() }; message.Attachments.Add(MessageHelpers.GetRemoveMessageAttachment()); return(Utils.Ok(message)); }
private static async Task <IActionResult> DeleteProposal(IBinder binder, InteractiveMessagePayload payload, Proposal proposal) { var proposals = await binder.GetTable("proposals"); if (proposal != null) { // Bloquer la suppression d'une proposition plannifiée if (!string.IsNullOrWhiteSpace(proposal.PlannedIn)) { var plan = await binder.GetTableRow <Plan>("plans", payload.PartitionKey, proposal.PlannedIn); if (plan != null) { return(Utils.Ok(new SlackMessage { Text = $"Ce vidéo est déjà planifié pour le {plan.Date:dddd d MMMM}.", Attachments = { MessageHelpers.GetRemoveMessageAttachment() } })); } } var result = await proposals.ExecuteAsync(TableOperation.Delete(proposal)); if (result.IsError()) { await MessageHelpers.PostErrorMessage(binder, payload); return(Utils.Ok()); } // Notifier le owner si c'est pas lui qui supprime sa proposition if (proposal.ProposedBy != payload.User.Id) { await SlackHelper.PostMessage(binder, payload.Team.Id, new PostMessageRequest { Channel = proposal.ProposedBy, Text = $"<@{payload.User.Id}> vient de supprimer votre proposition de vidéo dans <#{payload.Channel.Id}>:", Attachments = { await MessageHelpers.GetProposalAttachment(binder, proposal, allowActions: false) } }); } } // NOTE: Présentement la seule place qu'on peut supprimer une proposition c'est à partir de la liste de toutes les propositions. // Si ça change, va falloir ajouter plus de logique ici pour recréer le bon type de message. var allProposals = await ProposalHelpers.GetActiveProposals(proposals, payload.PartitionKey); var message = await MessageHelpers.GetListMessage(binder, allProposals, payload.Channel.Id); message.ReplaceOriginal = true; return(Utils.Ok(message)); }
private static async Task <IActionResult> ProcessProposalAction(IBinder binder, InteractiveMessagePayload payload) { var proposals = await binder.GetTable("proposals"); var action = payload.Actions.First(); if (action.Name == "delete") { var proposal = await proposals.Retrieve <Proposal>(payload.PartitionKey, action.Value); return(await DeleteProposal(binder, payload, proposal)); } if (action.Name == "done" || action.Name == "incomplete") { var proposalIdentifier = action.Value.Split('/'); var proposal = await proposals.Retrieve <Proposal>(proposalIdentifier[0], proposalIdentifier[1]); if (proposal == null) { return(Utils.Ok(new SlackMessage { Text = "Oups! Ce vidéo ne semble plus exister.", Attachments = { MessageHelpers.GetRemoveMessageAttachment() } })); } if (action.Name == "incomplete") { var newProposal = new Proposal { PartitionKey = proposal.PartitionKey, RowKey = payload.MessageTimestamp, ProposedBy = proposal.ProposedBy, Team = proposal.Team, Channel = proposal.Channel, Name = proposal.Name, Part = proposal.Part + 1, Url = proposal.Url, Notes = proposal.Notes }; await proposals.ExecuteAsync(TableOperation.Insert(newProposal)); } return(Utils.Ok(new SlackMessage { Text = $"Souhaitez-vous planifier le prochain Lunch & Watch pour <#{proposal.Channel}>?", Attachments = { new MessageAttachment { CallbackId = "dialog_action", Actions = new List <MessageAction>{ new MessageAction { Type = "button", Text = "Oui", Name = "plan", Value = proposal.PartitionKey }, new MessageAction { Type = "button", Text = "Non merci", Name = "cancel" } } } }, ReplaceOriginal = true })); } return(Utils.Ok()); }
private static async Task <IActionResult> ProcessPlanAction(IBinder binder, InteractiveMessagePayload payload) { var plans = await binder.GetTable("plans"); var action = payload.Actions.First(); var plan = await plans.Retrieve <Plan>(payload.PartitionKey, action.Value); if (plan == null) { return(Utils.Ok(new SlackMessage { Text = "Oups! Ce Lunch & Watch ne semble plus exister.", Attachments = { MessageHelpers.GetRemoveMessageAttachment() } })); } if (action.Name == "volunteer") { if (!string.IsNullOrWhiteSpace(plan.Owner)) { var message = new PostEphemeralRequest { User = payload.User.Id, Channel = payload.Channel.Id, Text = $"<@{plan.Owner}> est déjà responsable de ce Lunch & Watch.", Attachments = new List <MessageAttachment> { MessageHelpers.GetRemoveMessageAttachment() } }; await SlackHelper.PostEphemeral(binder, payload.Team.Id, message); return(await UpdatePlanMessage(binder, payload, plan, "")); } plan.Owner = payload.User.Id; var result = await plans.ExecuteAsync(TableOperation.Replace(plan)); if (result.IsError()) { await MessageHelpers.PostErrorMessage(binder, payload); return(await UpdatePlanMessage(binder, payload, plan, "")); } if (plan.Date.Date == DateTime.Today && DateTime.Now.TimeOfDay >= TimeSpan.Parse("11:30")) { var message = await MessageHelpers.GetPrepareVideoReminder(binder, plan); await SlackHelper.PostMessage(binder, plan.Team, message); } return(await UpdatePlanMessage(binder, payload, plan, "Merci!")); } if (action.Name == "vote") { if (!string.IsNullOrWhiteSpace(plan.Video)) { return(Utils.Ok(new SlackMessage { Text = "Le vidéo a déjà été sélectionné pour ce Lunch & Watch.", Attachments = { MessageHelpers.GetRemoveMessageAttachment() } })); } try { var dialogRequest = new OpenDialogRequest { TriggerId = payload.TriggerId, Dialog = await DialogHelpers.GetVoteDialog(binder, payload.PartitionKey, action.Value, payload.User.Id) }; await SlackHelper.OpenDialog(binder, payload.Team.Id, dialogRequest); } catch (NoAvailableVideosException) { return(Utils.Ok(new SlackMessage { Text = "Oups! Aucun vidéo n'a été proposé. Proposez un vidéo avec /edu:propose.", Attachments = { MessageHelpers.GetRemoveMessageAttachment() } })); } } return(Utils.Ok()); }