public async Task <bool?> Handle(InlineQuery data, object context = default, CancellationToken cancellationToken = default) { var queryParts = new StringSegment(data.Query).Split(new[] { ' ' }).FirstOrDefault().Split(new[] { ':' }); if (!PollEx.TryGetPollId(queryParts.ElementAtOrDefault(1), out var pollId, out var format)) { return(null); } var poll = (await myRaidService.GetOrCreatePollAndMessage(new PollMessage(data) { BotId = myBot.BotId, PollId = pollId }, myUrlHelper, format, cancellationToken))?.Poll; if (poll == null) { return(null); } var result = await GetResult(poll, cancellationToken); result ??= new InlineQueryResultArticle("NobodyToInvite", "Nobody to invite", new TextBuilder().Sanitize($"Nobody to invite").ToTextMessageContent()) { ThumbUrl = myUrlHelper.AssetsContent(@"static_assets/png/btn_close_normal.png").ToString() }; await myBot.AnswerInlineQueryWithValidationAsync(data.Id, new[] { result }, cacheTime : 0, isPersonal : true, cancellationToken : cancellationToken); return(true); }
public async Task <bool?> Handle(InlineQuery data, object context = default, CancellationToken cancellationToken = default) { var location = data.Location; var queryParts = data.Query.Split(' ', StringSplitOptions.RemoveEmptyEntries); var poll = default(Poll); var pollQuery = new List <string>(queryParts.Length); var searchQuery = new List <string>(queryParts.Length); var query = pollQuery; foreach (var queryPart in queryParts) { switch (queryPart) { case string locationPart when OpenLocationCode.IsValid(locationPart): location = OpenLocationCode.Decode(locationPart) is var code ? new Location { Longitude = (float)code.CenterLongitude, Latitude = (float)code.CenterLatitude } : location; break; case string part when Regex.Match(part, PATTERN) is Match match && match.Success: if (int.TryParse(match.Groups["pollId"].Value, out var pollId)) { poll = myRaidService.GetTemporaryPoll(pollId); } query = searchQuery; break; default: query.Add(queryPart); break; } } Portal[] portals; if (searchQuery.Count == 0) { portals = await myIngressClient.GetPortals(0.200, location, cancellationToken); } else { portals = await myIngressClient.Search(searchQuery, location, cancellationToken); } var results = new List <InlineQueryResultBase>(Math.Min(portals.Length, MAX_PORTALS_PER_RESPONSE) + 2); if ((poll == null) && (pollQuery.Count != 0)) { var voteFormat = await myDb.Set <Settings>().GetFormat(data.From.Id, cancellationToken); for (var i = 0; i < portals.Length && i < MAX_PORTALS_PER_RESPONSE; i++) { poll = new Poll(data) { Title = string.Join(" ", pollQuery), AllowedVotes = voteFormat, Portal = portals[i], ExRaidGym = false }; await myRaidService.GetPollId(poll, cancellationToken); results.Add(new InlineQueryResultArticle(poll.GetInlineId(), poll.GetTitle(myUrlHelper), poll.GetMessageText(myUrlHelper, disableWebPreview: poll.DisableWebPreview())) { Description = poll.AllowedVotes?.Format(new StringBuilder("Create a poll ")).ToString(), HideUrl = true, ThumbUrl = poll.GetThumbUrl(myUrlHelper).ToString(), ReplyMarkup = poll.GetReplyMarkup() }); if (i == 0) { poll.Id = -poll.Id; poll.ExRaidGym = true; results.Add(new InlineQueryResultArticle(poll.GetInlineId(), poll.GetTitle(myUrlHelper) + " (EX Raid Gym)", poll.GetMessageText(myUrlHelper, disableWebPreview: poll.DisableWebPreview())) { Description = poll.AllowedVotes?.Format(new StringBuilder("Create a poll ")).ToString(), HideUrl = true, ThumbUrl = poll.GetThumbUrl(myUrlHelper).ToString(), ReplyMarkup = poll.GetReplyMarkup() }); } } } else { for (var i = 0; i < portals.Length && i < MAX_PORTALS_PER_RESPONSE; i++) { var portal = portals[i]; var title = portal.Name is string name && !string.IsNullOrWhiteSpace(name) ? name : portal.Guid; if (portal.EncodeGuid() is string portalGuid) { InlineQueryResultArticle Init(InlineQueryResultArticle article, InlineKeyboardButton createButton) { const int thumbnailSize = 64; article.Description = portal.Address; article.ReplyMarkup = new InlineKeyboardMarkup(createButton); article.ThumbUrl = portal.GetImage(myUrlHelper, thumbnailSize)?.AbsoluteUri; article.ThumbHeight = thumbnailSize; article.ThumbWidth = thumbnailSize; return(article); } var portalContent = new StringBuilder() .Bold((builder, mode) => builder.Sanitize(portal.Name)).NewLine() .Sanitize(portal.Address) .Link("\u200B", portal.Image) .ToTextMessageContent(); results.Add(Init( new InlineQueryResultArticle($"portal:{portal.Guid}", title, portalContent), InlineKeyboardButton.WithSwitchInlineQuery("Create a poll", $"{PREFIX}{portalGuid} {poll?.Title}"))); if (i == 0) { var exRaidPortalContent = new StringBuilder() .Sanitize("☆ ") .Bold((builder, mode) => builder.Sanitize(portal.Name)) .Sanitize(" (EX Raid Gym)").NewLine() .Sanitize(portal.Address) .Link("\u200B", portal.Image) .ToTextMessageContent(); results.Add(Init( new InlineQueryResultArticle($"portal:{portal.Guid}+", $"☆ {title} (EX Raid Gym)", exRaidPortalContent), InlineKeyboardButton.WithSwitchInlineQuery("Create a poll ☆ (EX Raid Gym)", $"{PREFIX}{portalGuid}+ {poll?.Title}"))); } } } } if (searchQuery.Count == 0) { results.Add( new InlineQueryResultArticle("EnterGymName", "Enter a Gym's Title", new InputTextMessageContent("Enter a Gym's Title to search")) { Description = "to search", ThumbUrl = default(Portal).GetImage(myUrlHelper)?.AbsoluteUri }); } if (results.Count == 0) { var search = string.Join(" ", searchQuery); results.Add(new InlineQueryResultArticle("NothingFound", "Nothing found", new StringBuilder($"Nothing found by request ").Code((builder, mode) => builder.Sanitize(search, mode)).ToTextMessageContent()) { Description = $"Request {search}", ThumbUrl = myUrlHelper.AssetsContent(@"static_assets/png/btn_close_normal.png").AbsoluteUri }); } await myBot.AnswerInlineQueryWithValidationAsync(data.Id, results, cacheTime : 0, isPersonal : true, cancellationToken : cancellationToken); await myDb.SaveChangesAsync(cancellationToken); return(true); }
public async Task <bool?> Handle(InlineQuery data, object context = default, CancellationToken cancellationToken = default) { var results = new List <InlineQueryResult>(); var query = data.Query; string encodedId = null; if (Regex.Match(query, PATTERN) is { Success : true } match) { encodedId = match.Groups["Id"].Value; query = query.Remove(match.Index, match.Length); } query = query.Trim(); var matchedZones = myDateTimeZoneProvider.Ids.Where(id => { // check tz id if (id.Contains(query, StringComparison.OrdinalIgnoreCase)) { return(true); } // check Region name return(myTimeZoneService.TryGetRegion(id, out var region) && ( region.EnglishName.Contains(query, StringComparison.OrdinalIgnoreCase) || region.NativeName.Contains(query, StringComparison.OrdinalIgnoreCase))); }).ToList(); InlineKeyboardMarkup replyMarkup = null; if (myTimeZoneNotifyService.DecodeId(encodedId, out var chatId, out var messageId)) { (_, replyMarkup) = await myTimeZoneNotifyService.GetSettingsMessage(new Chat { Id = chatId, Type = ChatType.Sender }, messageId, cancellationToken); } var instant = myClock.GetCurrentInstant(); int.TryParse(data.Offset, out var offset); for (var index = offset; index < matchedZones.Count && index < offset + PAGE_SIZE; index++) { var id = matchedZones[index]; if (myDateTimeZoneProvider.GetZoneOrNull(id) is { } timeZone) { var title = $"{timeZone.Id} ({timeZone.GetUtcOffset(instant)})"; var builder = new TextBuilder() .Append($"{title}\x00A0") // trailing space is necessary to allow edit it further to the same message .NewLine(); string countryString = null; if (myTimeZoneService.TryGetRegion(timeZone.Id, out var country)) { countryString = $"{country.EnglishName} {country.NativeName}"; builder.Sanitize(countryString).NewLine(); } results.Add(new InlineQueryResultArticle($"{PREFIX}:{encodedId}:{timeZone.Id}", title, builder.ToTextMessageContent()) { Description = countryString, ReplyMarkup = replyMarkup }); } } string nextOffset = default; if (results.Count == 0 && offset == 0) { results.Add(new InlineQueryResultArticle("NothingFound", "Nothing found", new TextBuilder($"Nothing found by request ").Code(builder => builder.Sanitize(query)).ToTextMessageContent()) { Description = $"Request {query}", ThumbUrl = myUrlHelper.AssetsContent(@"static_assets/png/btn_close_normal.png").AbsoluteUri }); } else { nextOffset = (offset + PAGE_SIZE).ToString(); } await myBot.AnswerInlineQueryWithValidationAsync(data.Id, results, nextOffset : nextOffset, cacheTime : 0, isPersonal : true, cancellationToken : cancellationToken); return(true); }
public async Task <bool?> Handle(InlineQuery data, object context = default, CancellationToken cancellationToken = default) { IReadOnlyCollection <InlineQueryResultBase> inlineQueryResults; string query = null; Portal portal = null; bool exRaidGym = false; string switchPmParameter = null; foreach (var queryPart in data.Query.Split(' ', StringSplitOptions.RemoveEmptyEntries)) { switch (queryPart) { case string _ when queryPart.StartsWith(GymInlineQueryHandler.PREFIX): var guid = queryPart.Substring(GymInlineQueryHandler.PREFIX.Length); if (guid.EndsWith('+')) { guid = guid.Substring(0, guid.Length - 1); exRaidGym = true; } var portalGuid = PortalEx.DecodeGuid(guid); portal = await myIngressClient.Get(portalGuid, data.Location, cancellationToken); break; default: query += (query == null ? default(char?) : ' ') + queryPart; break; } } if (string.IsNullOrWhiteSpace(data.Query)) // check whole query for sharing branch { inlineQueryResults = await myShareInlineQueryHandler.GetActivePolls(data.From, cancellationToken); } else if (string.IsNullOrWhiteSpace(query)) { inlineQueryResults = new[] { new InlineQueryResultArticle($"EnterPollTopic", "Enter a topic", new InputTextMessageContent("Enter a topic to create a poll")) { Description = "to create a poll", ThumbUrl = myUrlHelper.AssetsContent("static_assets/png/POI_Submission_Illustration_02.png").ToString() } }; } else { var pollId = await myRaidService.GetPollId(new Poll(data) { Title = query, Portal = portal }, cancellationToken); switchPmParameter = portal == null ? $"{SwitchToGymParameter}{pollId}" : null; ICollection <VoteEnum> voteFormats = await myDb.Set <Settings>().GetFormats(data.From.Id, cancellationToken).ToListAsync(cancellationToken); if (voteFormats.Count == 0) { voteFormats = VoteEnumEx.DefaultVoteFormats; } inlineQueryResults = voteFormats .Select(format => new Poll { Id = exRaidGym ? -pollId : pollId, Title = query, AllowedVotes = format, Portal = portal, ExRaidGym = exRaidGym }) .Select((fakePoll, i) => new InlineQueryResultArticle(fakePoll.GetInlineId(i), fakePoll.GetTitle(myUrlHelper), fakePoll.GetMessageText(myUrlHelper, disableWebPreview: fakePoll.DisableWebPreview())) { Description = fakePoll.AllowedVotes?.Format(new StringBuilder("Create a poll ")).ToString(), HideUrl = true, ThumbUrl = fakePoll.GetThumbUrl(myUrlHelper).ToString(), ReplyMarkup = fakePoll.GetReplyMarkup() }) .ToArray(); } await myBot.AnswerInlineQueryWithValidationAsync(data.Id, inlineQueryResults, switchPmText : switchPmParameter != null? "Link the poll to a gym" : null, switchPmParameter : switchPmParameter, cacheTime : 0, cancellationToken : cancellationToken); await myDb.SaveChangesAsync(cancellationToken); return(true); }
public async Task <bool?> Handle(InlineQuery data, object context = default, CancellationToken cancellationToken = default) { var location = await myDb.Set <UserSettings>().GetLocation(data, cancellationToken); var queryParts = data.Query.Split(' ', StringSplitOptions.RemoveEmptyEntries); var poll = default(Poll); List <VoteLimit> limits = default; var pollQuery = new List <string>(queryParts.Length); var searchQuery = new List <string>(queryParts.Length); var query = pollQuery; foreach (var queryPart in queryParts) { switch (queryPart) { case { } locationPart when OpenLocationCode.IsValid(locationPart): location = OpenLocationCode.Decode(locationPart) is var code ? new Location { Longitude = (float)code.CenterLongitude, Latitude = (float)code.CenterLatitude } : location; break; case { } part when Regex.Match(part, PATTERN) is { Success: true } match: if (int.TryParse(match.Groups["pollId"].ValueSpan, out var pollId)) { poll = myRaidService .GetTemporaryPoll(pollId) .InitImplicitVotes(data.From, myBot.BotId); } query = searchQuery; break; case { } part when myGeneralInlineQueryHandler.ProcessLimitQueryString(ref limits, part): break; default: query.Add(queryPart); break; } } Portal[] portals; if (searchQuery.Count == 0) { portals = await myIngressClient.GetPortals(0.200, location, cancellationToken); } else { portals = await myIngressClient.Search(searchQuery, location, near : true, cancellationToken); } var results = new List <InlineQueryResult>(Math.Min(portals.Length, MAX_PORTALS_PER_RESPONSE) + 2); if (poll == null && pollQuery.Count != 0) { var voteFormat = await myDb.Set <Settings>().GetFormat(data.From.Id, cancellationToken); poll = await new Poll(data) { Title = string.Join(" ", pollQuery), AllowedVotes = voteFormat, ExRaidGym = false, Limits = limits }.DetectRaidTime(myTimeZoneService, () => Task.FromResult(location), async ct => myClock.GetCurrentInstant().InZone(await myGeoCoder.GetTimeZone(data, ct)), cancellationToken); for (var i = 0; i < portals.Length && i < MAX_PORTALS_PER_RESPONSE; i++) { var portalPoll = new Poll(poll) { Portal = portals[i], Limits = poll.Limits ?? limits }.InitImplicitVotes(data.From, myBot.BotId); await myRaidService.GetPollId(portalPoll, data.From, cancellationToken); results.Add(myGeneralInlineQueryHandler.GetInlineResult(portalPoll)); if (i == 0) { portalPoll.Id = -portalPoll.Id; portalPoll.ExRaidGym = true; results.Add(myGeneralInlineQueryHandler.GetInlineResult(portalPoll)); } } } else { for (var i = 0; i < portals.Length && i < MAX_PORTALS_PER_RESPONSE; i++) { var portal = portals[i]; var title = portal.Name is { } name&& !string.IsNullOrWhiteSpace(name) ? name : portal.Guid; if (portal.EncodeGuid() is { } portalGuid) { InlineQueryResultArticle Init(InlineQueryResultArticle article, InlineKeyboardButton createButton) { const int thumbnailSize = 64; article.Description = portal.Address; article.ReplyMarkup = new InlineKeyboardMarkup(createButton); article.ThumbUrl = portal.GetImage(myUrlHelper, thumbnailSize)?.AbsoluteUri; article.ThumbHeight = thumbnailSize; article.ThumbWidth = thumbnailSize; return(article); } var portalContent = new TextBuilder() .Bold(builder => builder.Sanitize(portal.Name)).NewLine() .Sanitize(portal.Address) .Link("\u200B", portal.Image) .ToTextMessageContent(); results.Add(Init( new InlineQueryResultArticle($"portal:{portal.Guid}", title, portalContent), InlineKeyboardButton.WithSwitchInlineQuery("Create a poll", $"{PREFIX}{portalGuid} {poll?.Title}"))); if (i == 0) { var exRaidPortalContent = new TextBuilder() .Sanitize("☆ ") .Bold(builder => builder.Sanitize(portal.Name)) .Sanitize(" (EX Raid Gym)").NewLine() .Sanitize(portal.Address) .Link("\u200B", portal.Image) .ToTextMessageContent(); results.Add(Init( new InlineQueryResultArticle($"portal:{portal.Guid}+", $"☆ {title} (EX Raid Gym)", exRaidPortalContent), InlineKeyboardButton.WithSwitchInlineQuery("Create a poll ☆ (EX Raid Gym)", $"{PREFIX}{portalGuid}+ {poll?.Title}"))); } } } } if (searchQuery.Count == 0) { results.Add( new InlineQueryResultArticle("EnterGymName", "Enter a Gym's Title", new InputTextMessageContent("Enter a Gym's Title to search")) { Description = "to search", ThumbUrl = default(Portal).GetImage(myUrlHelper)?.AbsoluteUri }); } if (results.Count == 0) { var search = string.Join(" ", searchQuery); results.Add(new InlineQueryResultArticle("NothingFound", "Nothing found", new TextBuilder($"Nothing found by request ").Code(builder => builder.Sanitize(search)).ToTextMessageContent()) { Description = $"Request {search}", ThumbUrl = myUrlHelper.AssetsContent(@"static_assets/png/btn_close_normal.png").AbsoluteUri }); } await myBot.AnswerInlineQueryWithValidationAsync(data.Id, results, cacheTime : 0, isPersonal : true, cancellationToken : cancellationToken); await myDb.SaveChangesAsync(cancellationToken); return(true); }
public async Task <bool?> Handle(InlineQuery data, object context = default, CancellationToken cancellationToken = default) { IReadOnlyCollection <InlineQueryResult> inlineQueryResults; Task <Location> location = null; async Task <Location> GetLocation() => await(location ??= myDb.Set <UserSettings>().GetLocation(data, cancellationToken)); string query = null; Portal portal = null; bool exRaidGym = false; string switchPmParameter = null; List <VoteLimit> limits = default; foreach (var queryPart in data.Query.Split(' ', StringSplitOptions.RemoveEmptyEntries)) { switch (queryPart) { case { } when queryPart.StartsWith(GymInlineQueryHandler.PREFIX): var guid = queryPart.Substring(GymInlineQueryHandler.PREFIX.Length); if (guid.EndsWith('+')) { guid = guid.Substring(0, guid.Length - 1); exRaidGym = true; } var portalGuid = PortalEx.DecodeGuid(guid); portal = await myIngressClient.Get(portalGuid, await GetLocation(), cancellationToken); break; case { } when ProcessLimitQueryString(ref limits, queryPart): break; default: query += (query == null ? default(char?) : ' ') + queryPart; break; } } if (string.IsNullOrWhiteSpace(data.Query)) // check whole query for sharing branch { inlineQueryResults = await myShareInlineQueryHandler.GetActivePolls(data.From, cancellationToken); } else if (string.IsNullOrWhiteSpace(query)) { inlineQueryResults = new[] { new InlineQueryResultArticle($"EnterPollTopic", "Enter a topic", new InputTextMessageContent("Enter a topic to create a poll")) { Description = "to create a poll", ThumbUrl = myUrlHelper.AssetsContent("static_assets/png/POI_Submission_Illustration_02.png").ToString() } }; } else { var poll = await new Poll(data) { Title = query, Portal = portal, Limits = limits } .DetectRaidTime(myTimeZoneService, GetLocation, async ct => myClock.GetCurrentInstant().InZone(await myGeoCoder.GetTimeZone(data, ct)), cancellationToken); var pollId = await myRaidService.GetPollId(poll, data.From, cancellationToken); switchPmParameter = portal == null ? $"{SwitchToGymParameter}{pollId}" : null; ICollection <VoteEnum> voteFormats = await myDb.Set <Settings>().GetFormats(data.From.Id).ToListAsync(cancellationToken); if (voteFormats.Count == 0) { voteFormats = VoteEnumEx.DefaultVoteFormats; } inlineQueryResults = voteFormats .Select(format => new Poll(poll) { Id = exRaidGym ? -pollId : pollId, AllowedVotes = format, ExRaidGym = exRaidGym }.InitImplicitVotes(data.From, myBot.BotId)) .Select((fakePoll, i) => GetInlineResult(fakePoll, i)) .ToArray(); } await myBot.AnswerInlineQueryWithValidationAsync(data.Id, inlineQueryResults, switchPmText : switchPmParameter != null? "Link the poll to a gym" : null, switchPmParameter : switchPmParameter, cacheTime : 0, cancellationToken : cancellationToken); await myDb.SaveChangesAsync(cancellationToken); return(true); }