-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(place-search): #29 add search place and show the static map #51
Merged
ronnygunawan
merged 4 commits into
teknologi-umum:main
from
oinpentuls:feat/add-search-places
Oct 24, 2022
Merged
Changes from 2 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
6a54610
feat(place-search): add search place and show the static map
oinpentuls 7b78820
refactor(place-search): bring back pse
oinpentuls f45c6b4
refactor(place-search): change command from /search_place to /map
oinpentuls 38c4f8d
merge with upstream
oinpentuls File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using BotNet.Services.GoogleMap; | ||
using BotNet.Services.RateLimit; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Telegram.Bot; | ||
using Telegram.Bot.Types; | ||
using Telegram.Bot.Types.Enums; | ||
|
||
namespace BotNet.Services.BotCommands { | ||
public static class SearchPlace { | ||
private static readonly RateLimiter SEARCH_PLACE_LIMITER = RateLimiter.PerChat(2, TimeSpan.FromMinutes(2)); | ||
|
||
public static async Task SearchPlaceAsync(ITelegramBotClient telegramBotClient, IServiceProvider serviceProvider, Message message, CancellationToken cancellationToken) { | ||
if (message.Entities?.FirstOrDefault() is { Type: MessageEntityType.BotCommand, Offset: 0, Length: int commandLength } | ||
&& message.Text![commandLength..].Trim() is string commandArgument) { | ||
|
||
if (commandArgument.Length > 0) { | ||
try { | ||
SEARCH_PLACE_LIMITER.ValidateActionRate(message.Chat.Id, message.From!.Id); | ||
|
||
try { | ||
string coords = await serviceProvider.GetRequiredService<GeoCode>().SearchPlaceAsync(commandArgument); | ||
string staticMapUrl = serviceProvider.GetRequiredService<StaticMap>().SearchPlace(commandArgument); | ||
|
||
await telegramBotClient.SendPhotoAsync( | ||
chatId: message.Chat.Id, | ||
photo: staticMapUrl, | ||
caption: coords, | ||
replyToMessageId: message.MessageId, | ||
cancellationToken: cancellationToken); | ||
} catch { | ||
await telegramBotClient.SendTextMessageAsync( | ||
chatId: message.Chat.Id, | ||
text: "<code>Lokasi tidak dapat ditemukan</code>", | ||
parseMode: ParseMode.Html, | ||
replyToMessageId: message.MessageId); | ||
} | ||
} catch (RateLimitExceededException exc) when (exc is { Cooldown: var cooldown }) { | ||
await telegramBotClient.SendTextMessageAsync( | ||
chatId: message.Chat.Id, | ||
text: $"Anda belum mendapat giliran. Coba lagi {cooldown}.", | ||
parseMode: ParseMode.Html, | ||
replyToMessageId: message.MessageId, | ||
cancellationToken: cancellationToken); | ||
} | ||
} | ||
} else { | ||
await telegramBotClient.SendTextMessageAsync( | ||
chatId: message.Chat.Id, | ||
text: "<code>Silakan masukkan lokasi di depan perinta /search_place</code>", | ||
parseMode: ParseMode.Html, | ||
replyToMessageId: message.MessageId, | ||
cancellationToken: cancellationToken); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
using System; | ||
using System.Net; | ||
using System.Text.Json; | ||
using System.Net.Http; | ||
using Microsoft.Extensions.Options; | ||
using BotNet.Services.GoogleMap.Models; | ||
using System.IO; | ||
using System.Threading.Tasks; | ||
|
||
namespace BotNet.Services.GoogleMap { | ||
|
||
/// <summary> | ||
/// This class intended to get geocoding from address. | ||
/// </summary> | ||
public class GeoCode { | ||
|
||
|
||
private readonly string? _apiKey; | ||
private string _uriTemplate = "https://maps.googleapis.com/maps/api/geocode/json"; | ||
private readonly HttpClientHandler _httpClientHandler; | ||
private readonly HttpClient _httpClient; | ||
|
||
|
||
public GeoCode(IOptions<GoogleMapOptions> options) { | ||
_apiKey = options.Value.ApiKey; | ||
_httpClientHandler = new(); | ||
_httpClient = new(_httpClientHandler); | ||
} | ||
|
||
/// <summary> | ||
/// The response of this api call is consist of 2 parts. | ||
/// Array of "results" and string of "status" | ||
/// | ||
/// Even though the results is array, the docs say normally the result will have only one element. | ||
/// So, we can grab the result like result[0] | ||
/// </summary> | ||
/// <param name="place">Place or address that you want to search</param> | ||
/// <returns>strings of coordinates</returns> | ||
/// <exception cref="HttpRequestException"></exception> | ||
public async Task<string> SearchPlaceAsync(string? place) { | ||
if (string.IsNullOrEmpty(place)) { | ||
return "Invalid place"; | ||
} | ||
|
||
if (string.IsNullOrEmpty(_apiKey)) { | ||
return "Api key is needed"; | ||
} | ||
|
||
Uri uri = new(_uriTemplate + $"?address={place}&key={_apiKey}"); | ||
HttpResponseMessage response = await _httpClient.GetAsync(uri.AbsoluteUri); | ||
|
||
if (response is not { StatusCode: HttpStatusCode.OK, Content.Headers.ContentType.MediaType: string contentType }) { | ||
throw new HttpRequestException("Unable to find location."); | ||
} | ||
|
||
if (response.Content is not object && contentType is not "application/json") { | ||
throw new HttpRequestException("Failed to parse result."); | ||
} | ||
|
||
Stream bodyContent = await response.Content!.ReadAsStreamAsync(); | ||
|
||
Response? body = await JsonSerializer.DeserializeAsync<Response>(bodyContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); | ||
|
||
if (body is null) { | ||
throw new HttpRequestException("Failed to parse result."); | ||
} | ||
|
||
if (body.Status is not "OK") { | ||
throw new HttpRequestException("Unable to find location."); | ||
} | ||
|
||
if (body.Results!.Count <= 0) { | ||
throw new HttpRequestException("No Result."); | ||
} | ||
|
||
Result? result = body.Results[0]; | ||
|
||
string lat = result.Geometry!.Location!.Lat.ToString(); | ||
string longitude = result.Geometry!.Location!.Lng.ToString(); | ||
string coordinates = $"lat: {lat}, long: {longitude}"; | ||
|
||
return coordinates; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
namespace BotNet.Services.GoogleMap { | ||
public class GoogleMapOptions { | ||
public string? ApiKey { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
namespace BotNet.Services.GoogleMap.Models { | ||
public class Geometry { | ||
|
||
public Coordinate? Location{ get; set; } | ||
|
||
public string? Location_Type { get; set; } | ||
|
||
public class Coordinate { | ||
public double Lat { get; set; } | ||
public double Lng { get; set; } | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace BotNet.Services.GoogleMap.Models { | ||
public enum LocationType { | ||
ROOFTOP, | ||
RANGE_INTERPOLATED, | ||
GEOMETRIC_CENTER, | ||
APPROXIMATE | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace BotNet.Services.GoogleMap.Models { | ||
|
||
/// <summary> | ||
/// Response for google map api geocoding | ||
/// </summary> | ||
public class Response { | ||
public List<Result>? Results { get; set; } | ||
public string? Status { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace BotNet.Services.GoogleMap.Models { | ||
|
||
public class Result { | ||
public string? Formatted_Address { get; set; } | ||
|
||
public Geometry? Geometry { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
namespace BotNet.Services.GoogleMap.Models { | ||
public enum StatusCode { | ||
OK, | ||
ZERO_RESULTS, | ||
OVER_DAILY_LIMIT, | ||
OVER_QUERY_LIMIT, | ||
REQUEST_DENIED, | ||
INVALID_REQUEST, | ||
UNKNOWN_ERROR | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
namespace BotNet.Services.GoogleMap.Models { | ||
public enum ZoomLevel { | ||
World = 1, | ||
LandMass = 5, | ||
City = 10, | ||
Streets = 15, | ||
Buildings = 20 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
namespace BotNet.Services.GoogleMap { | ||
public static class ServiceCollectionExtensions { | ||
public static IServiceCollection AddGoogleMaps(this IServiceCollection services) { | ||
services.AddTransient<GeoCode>(); | ||
services.AddTransient<StaticMap>(); | ||
|
||
return services; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
using System; | ||
using BotNet.Services.GoogleMap.Models; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace BotNet.Services.GoogleMap { | ||
|
||
/// <summary> | ||
/// Get static map image from google map api | ||
/// </summary> | ||
public class StaticMap { | ||
private readonly string? _apiKey; | ||
protected string mapPosition = "center"; | ||
protected int zoom = (int)ZoomLevel.Streets; | ||
protected string size = "600x300"; | ||
protected string marker = "color:red"; | ||
private string _uriTemplate = "https://maps.googleapis.com/maps/api/staticmap"; | ||
|
||
public StaticMap(IOptions<GoogleMapOptions> options) { | ||
_apiKey = options.Value.ApiKey; | ||
} | ||
|
||
/// <summary> | ||
/// Get static map image from google map api | ||
/// </summary> | ||
/// <param name="place">Place or address that you want to search</param> | ||
/// <returns>string of url</returns> | ||
public string SearchPlace(string? place) { | ||
if (string.IsNullOrEmpty(place)) { | ||
return "Invalid place"; | ||
} | ||
|
||
if (string.IsNullOrEmpty(_apiKey)) { | ||
return "Api key is needed"; | ||
} | ||
|
||
Uri uri = new(_uriTemplate + $"?{mapPosition}={place}&zoom={zoom}&size={size}&markers={marker}|{place}&key={_apiKey}"); | ||
|
||
return uri.ToString(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pake
/map
ajaThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
noted