using System.Collections.Generic;
using System.Threading.Tasks;
using System.Text.Json.Serialization;
public static async Task Main()
var request = new GoogleActionWebhookRequest
handler = new GoogleActionWebhookRequest.Handler
intent = new GoogleActionWebhookRequest.Intent
session = new GoogleActionWebhookRequest.Session
var response = await ProcessGoogleAction(request);
var serializerOptions = new JsonSerializerOptions
Console.WriteLine("Request from Google Aciton is:\n");
Console.WriteLine(JsonSerializer.Serialize(request, serializerOptions));
Console.WriteLine("\n===================================\n");
Console.WriteLine("Webhook Response to Google Aciton is:\n");
Console.WriteLine(JsonSerializer.Serialize(response, serializerOptions));
public static async Task<GoogleActionWebhookResponse> ProcessGoogleAction(GoogleActionWebhookRequest request)
var speech = await GetSpeechText(request.handler.name);
var response = new GoogleActionWebhookResponse()
prompt = new GoogleActionWebhookResponse.Prompt
firstSimple = new GoogleActionWebhookResponse.Prompt.Simple
scene = new GoogleActionWebhookResponse.Scene
next = new GoogleActionWebhookResponse.Scene.Next
session = new GoogleActionWebhookResponse.Session
private static async Task<string> GetSpeechText(string handler)
return await GetTopPostsText();
public const string RedditPostsUrl = "https://www.reddit.com/r/{0}/.json?limit={1}";
private static async Task<string> GetTopPostsText()
var url = String.Format(RedditPostsUrl, "wallstreetbets", 3);
using (var client = new HttpClient())
var httpResponse = await client.GetAsync(url);
string json = await httpResponse.Content.ReadAsStringAsync();
var serializerOptions = new JsonSerializerOptions
Converters = { new DynamicJsonConverter() }
var jsonData = JsonSerializer.Deserialize<dynamic>(json, serializerOptions);
var children = jsonData.data.children;
foreach (var child in children)
string title = child.data.title;
text += "\nPost " + postNumber + ": '" + title + "'.";
public class GoogleActionWebhookRequest
public Handler handler { get; set; }
public Intent intent { get; set; }
public Session session { get; set; }
public string name { get; set; }
public string name { get; set; }
public string query { get; set; }
public string id { get; set; }
public class GoogleActionWebhookResponse
public Session session { get; set; }
public Prompt prompt { get; set; }
public Scene scene { get; set; }
public string id { get; set; }
public Simple firstSimple { get; set; }
public string speech { get; set; }
public string text { get; set; }
public string name { get; set; }
public Next next { get; set; }
public string name { get; set; }
public class DynamicJsonConverter : JsonConverter<dynamic>
public override dynamic Read(ref Utf8JsonReader reader,
JsonSerializerOptions options)
if (reader.TokenType == JsonTokenType.True)
if (reader.TokenType == JsonTokenType.False)
if (reader.TokenType == JsonTokenType.Number)
if (reader.TryGetInt64(out long l))
return reader.GetDouble();
if (reader.TokenType == JsonTokenType.String)
if (reader.TryGetDateTime(out DateTime datetime))
return reader.GetString();
if (reader.TokenType == JsonTokenType.StartObject)
using JsonDocument documentV = JsonDocument.ParseValue(ref reader);
return ReadObject(documentV.RootElement);
if (reader.TokenType == JsonTokenType.StartArray)
using JsonDocument documentV = JsonDocument.ParseValue(ref reader);
return ReadList(documentV.RootElement);
JsonDocument document = JsonDocument.ParseValue(ref reader);
return document.RootElement.Clone();
private object ReadObject(JsonElement jsonElement)
IDictionary<string, object> expandoObject = new ExpandoObject();
foreach (var obj in jsonElement.EnumerateObject())
var value = ReadValue(obj.Value);
expandoObject[k] = value;
private object ReadValue(JsonElement jsonElement)
switch (jsonElement.ValueKind)
case JsonValueKind.Object:
result = ReadObject(jsonElement);
case JsonValueKind.Array:
result = ReadList(jsonElement);
case JsonValueKind.String:
result = jsonElement.GetString();
case JsonValueKind.Number:
if (jsonElement.TryGetInt64(out long l))
if (jsonElement.TryGetDouble(out double d))
case JsonValueKind.False:
case JsonValueKind.Undefined:
throw new ArgumentOutOfRangeException();
private object ReadList(JsonElement jsonElement)
IList<object> list = new List<object>();
foreach (var item in jsonElement.EnumerateArray())
list.Add(ReadValue(item));
return list.Count == 0 ? null : list;
public override void Write(Utf8JsonWriter writer,
JsonSerializerOptions options)
throw new NotImplementedException();