I have been working on a project with unity about chat bots using dialog flow,
the problem I am facing is as follows: I have to run some commands in order to retrieve the token from google in terminal then a C# script uses this token to run some functions but the problem is that the token expires every 5 minutes since I m consuming the API so is there a way to automate the process in a bash script file where It can run the commands and get the token then it is directly used in the C# script.
accessing agent
Getting the token
DialogflowAPIScript
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.Networking;
using JsonData;
public class DialogflowAPIScript : MonoBehaviour
{
void Start()
{
i0tBjGc2WlRT9GePIqe1_j5Xq9flXHMGJWnn5sEjNHyG1VfMFqtt3WapHAVo2-RwvPNKRTHI0BkF9OVUzZJ5OWJEILr64_ge1tgcbS7AA"));
StartCoroutine(PostRequest("https://dialogflow.googleapis.com/v2/projects/newagent-taqyfj/agent/sessions/34563:detectIntent",
"ya29.c.Ko4B0AeMSB_eB-0DumT7ubxKoJc47TMOKhgls589I-F8whsTbnZvAgFn6Ft-sqwcFPI1n_-CQIp4zk-e3Ip9lVvXvrJFOfPmoejayJhjHR9Gu36XsulR71_iHGnvb8m4aYbkBF9tnkA05cJahNyVZoK5SWR3EgAb4XofkMfp7Qt8vtnMa6J-Q89YZevUk3VfaA"));
}
void Update()
{
}
IEnumerator PostRequest(String url, String AccessToken)
{
UnityWebRequest postRequest = new UnityWebRequest(url, "POST");
RequestBody requestBody = new RequestBody();
requestBody.queryInput = new QueryInput();
requestBody.queryInput.text = new TextInput();
requestBody.queryInput.text.text = "hello";
requestBody.queryInput.text.languageCode = "en";
string jsonRequestBody = JsonUtility.ToJson(requestBody, true);
Debug.Log(jsonRequestBody);
byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(jsonRequestBody);
postRequest.SetRequestHeader("Authorization", "Bearer " + AccessToken);
postRequest.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);
postRequest.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
//postRequest.SetRequestHeader("Content-Type", "application/json");
yield return postRequest.SendWebRequest();
if (postRequest.isNetworkError || postRequest.isHttpError)
{
Debug.Log(postRequest.responseCode);
Debug.Log(postRequest.error);
}
else
{
Debug.Log("Response: " + postRequest.downloadHandler.text);
byte[] resultbyte = postRequest.downloadHandler.data;
string result = System.Text.Encoding.UTF8.GetString(resultbyte);
ResponseBody content = (ResponseBody)JsonUtility.FromJson<ResponseBody>(result);
Debug.Log(content.queryResult.fulfillmentText);
}
}
IEnumerator GetAgent(String AccessToken)
{
UnityWebRequest www = UnityWebRequest.Get("https://dialogflow.googleapis.com/v2/projects/newagent-taqyfj/agent");
www.SetRequestHeader("Authorization", "Bearer " + AccessToken);
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
Debug.Log(www.downloadHandler.text);
byte[] results = www.downloadHandler.data;
}
}
}
request RequestBody
using System.Collections.Generic;
namespace JsonData
{
v2/rest/v2/projects.agent.sessions/detectIntent#QueryParameters
public class RequestBody
{
public QueryInput queryInput;
public string inputAudio;
}
public class QueryInput
{
public TextInput text;
//public InputAudioConfig audioConfig;
}
public class InputAudioConfig
{
public AudioEncoding audioEncoding;
public int sampleRateHertz;
public String languageCode;
public String[] phraseHints;
}
public enum AudioEncoding
{
AUDIO_ENCODING_UNSPECIFIED,
AUDIO_ENCODING_LINEAR_16,
AUDIO_ENCODING_FLAC,
AUDIO_ENCODING_MULAW,
AUDIO_ENCODING_AMR,
AUDIO_ENCODING_AMR_WB,
AUDIO_ENCODING_OGG_OPUS,
AUDIO_ENCODING_SPEEX_WITH_HEADER_BYTE
}
public enum WebhookState
{
STATE_UNSPECIFIED,
WEBHOOK_STATE_ENABLED,
WEBHOOK_STATE_ENABLED_FOR_SLOT_FILLING
}
public class ResponseBody
{
public string responseId;
public QueryResult queryResult;
public Status webhookStatus;
}
public class QueryResult
{
public string queryText;
public string languageCode;
public int speechRecognitionConfidence;
public string action;
public Struct parameters;
public bool allRequiredParamsPresent;
public string fulfillmentText;
public Message[] fulfillmentMessages;
public string webhookSource;
public Struct webhookPayload;
public Context[] outputContexts;
public Intent intent;
public int intentDetectionConfidence;
public Struct diagnosticInfo;
}
[Serializable]
public class Status
{
public int code;
public string message;
public Object[] details;
}
[Serializable]
public class Intent
{
public string name;
public string displayName;
public WebhookState webhookState;
public int priority;
public bool isFallback;
}
public class Context
{
public string name;
}
public class Struct
{
public Dictionary<string, Value> fields;
}
public class Value
{
public NullValue null_value;
public double number_value;
public string string_value;
public bool bool_value;
public Struct struct_value;
public ListValue list_value;
public void ForBool(bool value){
this.bool_value = value;
}
public void ForString(string value)
{
this.string_value = value;
}
public void ForNumber(double number){
this.number_value = number;
}
public void ForNull()
{
this.null_value = NullValue.null_vaule;
}
public void ForStruct(Struct value){
this.struct_value = value;
}
public void ForList(ListValue value){
this.list_value = value;
}
}
public enum NullValue
{
null_vaule
}
public class ListValue{
public Value values;
}
public class Text{
public string[] text;
}
[Serializable]
public class Message{
public Text text;
}
}```
Related
I have a 'complex' object that I want to serialize with JSon.Convert. As 'complex' objects go it is rather simple: Here are the objects:
The main object:
public class CustomerContactRequest
{
private RequestHeaderArea header;
private RequestPayloadArea payload;
public CustomerContactRequest(string headerMessage, string npsGroup, string npsSection)
{
this.header = new RequestHeaderArea(headerMessage);
this.payload = new RequestPayloadArea(npsGroup, npsSection);
}
}
The 'header' Object:
public class RequestHeaderArea
{
private string headerMessage;
public string HeaderMessage { get { return headerMessage; } }
public RequestHeaderArea(string headerMessage)
{
this.headerMessage = headerMessage;
}
}
The Payload Area:
public class RequestPayloadArea
{
private string npsGroup;
private string npsSection;
public string NPSGroup { get { return npsGroup; } }
public string NPSSection { get { return npsSection; } }
public RequestPayloadArea(string npsGroup, string npsSection)
{
this.npsGroup = npsGroup;
this.npsSection = npsSection;
}
}
And Finally, the main process:
static void Main(string[] args)
{
CustomerContactRequest ccRequest = new CustomerContactRequest(
headerMessage: "test",
npsGroup: "1234567",
npsSection: "0000");
retrieveContactInfo(ccRequest);
}
static void retrieveContactInfo(CustomerContactRequest ccRequest)
{
string jsonRequest = JsonConvert.SerializeObject(ccRequest);
// code to call service
}
jsonRequest returns {} even though ccRequest contains the expected values. What am I missing?
I am expecting something like this (sans formatting):
{
"headerArea": {
"messageId": "test"
},
"payloadArea": {
"group": {
"Number": "1234567",
"Suffix": "0000"
}
}
}
Implementing Chris's answer my classes now look like below (main program did not change except that I added Formatted.Indented to the SerializeObject call to make it pretty):
CustomerContactRequest:
public class CustomerContactRequest
{
public RequestHeaderArea headerArea;
public RequestPayloadArea payloadArea;
public CustomerContactRequest(string headerMessage, string npsGroup, string npsSection)
{
this.headerArea = new RequestHeaderArea(headerMessage);
this.payloadArea = new RequestPayloadArea(npsGroup, npsSection);
}
}
RequestHeaderArea:
public class RequestHeaderArea
{
private string messageId;
public string MessageId { get { return messageId; } }
public RequestHeaderArea(string headerMessage)
{
this.messageId = headerMessage;
}
}
RequestPayloadArea:
public class RequestPayloadArea
{
public Group group;
public RequestPayloadArea(string npsGroup, string npsSection)
{
this.group = new Group(npsGroup, npsSection);
}
}
And a new class: Group:
public class Group
{
public string Number;
public string Suffix;
public Group(string npsGroup, string npsSection)
{
Number = npsGroup;
Suffix = npsSection;
}
}
Now my Json looks exactly as expected (see green text above)
SerializeObject ignores private members by default. You can either make them public, or by adding the SerializableAttribute to your CustomerContractRequest class.
I create a class named MyMainClass
namespace MyTest
{
private void frmMain_Load(object sender, EventArgs e)
{
MyMainClass myVar = new MyMainClass();
myVar.sub1.sb1A = "value 1A";
myVar.sub1.sb1B = "value 1B";
MessageBox.Show(myVar.sub2.wantPassString);
//I want to print the value "I've got value value 1A"
}
public class MyMainClass
{
public subClass1 sub1 = new subClass1();
public subClass2 sub2 = new subClass2();
public class subClass1
{
public string sb1A{get;set;}
public string sb1B{get;set;}
}
public class subClass2
{
public string sb2A{get;set;}
public string sb2B{get;set;}
// a1a is a value that I want to get from subClass1
string a1a = subClass1.sb1A;
public string wantPassString {get{return "I've got value " + a1a;}}
}
}
}
How can I pass the value from subClass1.sb1A to the string a1a or wantPassString in subClass2 ? when I call in frmMain_Load
The normal approach would be to pass the class through the constructor. This works:
public class MyMainClass
{
public MyMainClass()
{
sub1 = new subClass1();
sub2 = new subClass2(sub1);
}
public subClass1 sub1;
public subClass2 sub2;
public class subClass1
{
public string sb1A{get;set;}
public string sb1B{get;set;}
}
public class subClass2
{
public subClass2(subClass1 sub1)
{
this.sub1 = sub1;
}
public string sb2A{get;set;}
public string sb2B{get;set;}
subClass1 sub1;
public string wantPassString {get{return "I've got value " + sub1.sb1A;}}
}
}
Create a third class to hold the data.
public MainClass
{
private class sharedClass
{
internal string sb1A { get; set; }
}
public class subClass1
{
private readonly sharedClass _shared;
internal subClass1(sharedClass shared)
{
this._shared = shared;
}
public string sb1A
{
get
{
return this._shared.sb1A;
}
set
{
this._shared.sb1A = value;
}
public string sb1B{get;set;}
}
public class subClass2
{
private readonly sharedClass _shared;
public subClass2(shared s)
{
_shared = s;
}
public string sb2A{get;set;}
public string sb2B{get;set;}
public string wantPassString {get{return "I've got value " + _shared.sb1;}}
}
private readonly sharedClass _shared = new sharedClass();
private readonly subClass1 _subClass1;
private readonly subClass2 _subClass2;
public MainClass()
{
this._subClass1 = new subClass1(this._shared);
this._subClass2 = new subClass2(this._shared);
}
}
You can add additional property and method and pass it as a parameter:
public string sb2C{ get; set; }
public string getData(string strParam)
{
return sb2C= strParam;
}
Then on your frmMain_Load:
MessageBox.Show(myVar.sub2.getData(myVar.sub1.sb1B));
//This would also populate sb2C that will hold the data from the other class
I am serializing with xml, and I had it working with just a simple class, but when I made a secondary class, of which the simple class was just a component, the serialization stopped working. It fails with an "Error reflecting type" error at the serialization stage. The code is as follows:
public class CustomField
{
[XmlAttribute("FieldID")]
public string FieldID;
[XmlAttribute("FieldValue")]
public string FieldValue;
public CustomField() { }
public CustomField(string fieldID, string fieldValue)
{
this.FieldID = fieldID;
this.FieldValue = fieldValue;
}
}
[XmlType("Entry")]
public class CustomEntry
{
[XmlAttribute("Author")]
public string Author;
[XmlAttribute("Title")]
public string Title;
[XmlAttribute("Trial")]
public string Trial;
[XmlAttribute("Responses")]
public List<CustomField> Responses;
public CustomEntry() { }
}
public static class EntrySerializer
{
public static void SerializeObject(this CustomEntry entry, string file)
{
var serializer = new XmlSerializer(typeof(CustomEntry));
using (var stream = File.OpenWrite(file))
{
serializer.Serialize(stream, entry);
}
}
}
Is it a labeling issue with the Xml markers, or is it something else?
Try defining your serializer like this:
var serializer = new XmlSerializer(typeof(CustomEntry), new Type[] { typeof(CustomField) });
You need to inform the serializer of the additional types it is expecting to serialize.
I usually tag with XMLRoot (two places). I need to see sample of XML to give better answer.
[XmlRoot("CustomField")]
public class CustomField
{
[XmlAttribute("FieldID")]
public string FieldID;
[XmlAttribute("FieldValue")]
public string FieldValue;
public CustomField() { }
public CustomField(string fieldID, string fieldValue)
{
this.FieldID = fieldID;
this.FieldValue = fieldValue;
}
}
[XmlRoot("Entry")]
public class CustomEntry
{
[XmlAttribute("Author")]
public string Author;
[XmlAttribute("Title")]
public string Title;
[XmlAttribute("Trial")]
public string Trial;
[XmlAttribute("Responses")]
public List<CustomField> Responses;
public CustomEntry() { }
}
Create three small classes unrelated by inheritance—classes Building, Car and Bicycle. Write an interface ICarbonFootprint with a GetCarbonFootprint method. Have each of your classes implement that interface, so that its GetCarbonFootprint method calculates an appropriate carbon footprint for that class (check out a few websites that explain how to calculate carbon footprints). Write an app that creates objects of each of the three classes, places references to those objects in List, then iterates through the List, polymorphically invoking each object’s GetCarbonFootprint method. Constructor of Car initialize “gallon of gas”, and the Building constructor will initialize buiding-square-footage.
how to calculate carbon-footprint
One gallon of gas yields 20 pounds of CO2 for a car
Multiply the square footage by 50 for a building
None for a bicycle
My instructor's code:
public static void Main(string[] args)
{
ICarbonFootprint[] list = new ICarbonFootprint[3];
// add elements to list
list[0] = new Bicycle();
list[1] = new Building(2500);
list[2] = new Car(10);
// display carbon footprint of each object
for (int i = 0; i < list.Length; i++)
list[i].GetCarbonFootprint();
} // end Main
}
My code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Miller
{
class Program
{
static void Main(string[] args)
{
Bicycle bike = new Bicycle();
Building b = new Building();
Car car = new Car();
List<ICarbonFootprint> list = new List<ICarbonFootprint>();
list.Add(bike);
list.Add(b);
list.Add(car);
int totalCarbon = 0;
foreach (var item in list)
{
totalCarbon += item.GetCarbonFootprint();
Console.WriteLine("{0} has a footprint of: {1}", item, item.GetCarbonFootprint());
}
Console.WriteLine("Total footprint is: {0}", totalCarbon);
Console.ReadKey();
}
}
public class Bicycle : ICarbonFootprint
{
private string _make;
private string _model;
public string Make
{
get { return _make; }
set { _make = value; }
}
public string Model
{
get { return _model; }
set { _model = value; }
}
public int GetCarbonFootprint()
{
return 10;
}
public override string ToString()
{
return string.Format("Bike");
}
}
public class Building : ICarbonFootprint
{
private string _address;
public string Address
{
get { return _address; }
set { _address = value; }
}
public int GetCarbonFootprint()
{
return 2000;
}
public override string ToString()
{
return string.Format("Building");
}
}
public class Car : ICarbonFootprint
{
private string _make;
private string _model;
public string Make
{
get { return _make; }
set { _make = value; }
}
public string Model
{
get { return _model; }
set { _model = value; }
}
public int GetCarbonFootprint()
{
return 1500;
}
public override string ToString()
{
return string.Format("Car");
}
}
public interface ICarbonFootprint
{
int GetCarbonFootprint();
}
}
Me integrating my instructor's code (lines 12-23 changed AKA class Program was the only thing changed):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Miller
{
class Program
{
public static void Main(string[] args)
{
ICarbonFootprint[] list = new ICarbonFootprint[3];
// add elements to list
list[0] = new Bicycle();
list[1] = new Building(2500);
list[2] = new Car(10);
// display carbon footprint of each object
for (int i = 0; i < list.Length; i++)
list[i].GetCarbonFootprint();
} // end Main
}
public class Bicycle : ICarbonFootprint
{
private string _make;
private string _model;
public string Make
{
get { return _make; }
set { _make = value; }
}
public string Model
{
get { return _model; }
set { _model = value; }
}
public int GetCarbonFootprint()
{
return 10;
}
public override string ToString()
{
return string.Format("Bike");
}
}
public class Building : ICarbonFootprint
{
private string _address;
public string Address
{
get { return _address; }
set { _address = value; }
}
public int GetCarbonFootprint()
{
return 2000;
}
public override string ToString()
{
return string.Format("Building");
}
}
public class Car : ICarbonFootprint
{
private string _make;
private string _model;
public string Make
{
get { return _make; }
set { _make = value; }
}
public string Model
{
get { return _model; }
set { _model = value; }
}
public int GetCarbonFootprint()
{
return 1500;
}
public override string ToString()
{
return string.Format("Car");
}
}
public interface ICarbonFootprint
{
int GetCarbonFootprint();
}
}
So, replacing my code for class Program with my instructor's code, I received the following errors:
Program.cs(51,23,51,41): error CS1729: 'Miller.Building' does not contain a constructor that takes 1 arguments
Program.cs(52,23,52,34): error CS1729: 'Miller.Car' does not contain a constructor that takes 1 arguments
Now, because the last two days before Spring break were cancelled due to the weather (snow), we weren't able to discuss. My code seems to do what the directions ask, but I would like to get my instructor's code for class Program working with my code. Could someone help me with these errors possibly?
There are a few issues with your code.
First up you need to include the constructors to make the code compile.
For Building this would look like:
private int squareFootage;
public Building(int squareFootage)
{
this.squareFootage = squareFootage;
}
And for Car this would look like:
private int gasGallons;
public Car(int gasGallons)
{
this.gasGallons = gasGallons;
}
Next, you're not following the rules for calculating the carbon footprint.
They should be:
//Bicycle
public int GetCarbonFootprint()
{
return 0;
}
//Building
public int GetCarbonFootprint()
{
return 50 * squareFootage;
}
//Car
public int GetCarbonFootprint()
{
return 20 * gasGallons;
}
Finally, your instructor's code doesn't actually display any results. The code in the for loop should be changed to be Console.WriteLine(list[i].GetCarbonFootprint()); if this is a console app.
So, all up the code should look like this:
public static void Main(string[] args)
{
ICarbonFootprint[] list = new ICarbonFootprint[3];
// add elements to list
list[0] = new Bicycle();
list[1] = new Building(2500);
list[2] = new Car(10);
// display carbon footprint of each object
for (int i = 0; i < list.Length; i++)
Console.WriteLine(list[i].GetCarbonFootprint());
}
public class Bicycle : ICarbonFootprint
{
public string Make { get; set; }
public string Model { get; set; }
public int GetCarbonFootprint()
{
return 0;
}
}
public class Building : ICarbonFootprint
{
private int squareFootage;
public Building(int squareFootage)
{
this.squareFootage = squareFootage;
}
public string Address { get; set; }
public int GetCarbonFootprint()
{
return 50 * squareFootage;
}
}
public class Car : ICarbonFootprint
{
private int gasGallons;
public Car(int gasGallons)
{
this.gasGallons = gasGallons;
}
public string Make { get; set; }
public string Model { get; set; }
public int GetCarbonFootprint()
{
return 20 * gasGallons;
}
}
public interface ICarbonFootprint
{
int GetCarbonFootprint();
}
I've opted to short-cut the property definitions rather than implement them with fields.
The output is:
0
125000
200
You should write constructors for Building and Car like next:
public Building(int MyValue)
{
...
}
and your code will work fine.
Suggestion: Car and Bicycle shares properties, and the ICarbonFootprint implementation, so you can create a base class with an abstract method. Also the GetCarbonFootprint from ICarbonFootprint interface must be type of System.Double.
public interface ICarbonFootprint
{
int GetCarbonFootprint();
}
public class Building : ICarbonFootprint
{
public int BuildingSquareFootage { get; set; }
public string Address { get; set; }
public Building(int buildingSquareFootage, string address)
{
BuildingSquareFootage = buildingSquareFootage;
Address = address;
}
public int GetCarbonFootprint()
{
return BuildingSquareFootage * 50;
}
public override string ToString()
{
return string.Format("Building");
}
}
public abstract class CarBicycleBase : ICarbonFootprint
{
public string Make { get; set; }
public string Model { get; set; }
protected CarBicycleBase(string make, string model)
{
Make = make;
Model = model;
}
public abstract int GetCarbonFootprint();
}
public class Bicycle : CarBicycleBase
{
public Bicycle(string make, string model)
: base(make, model) { }
public override int GetCarbonFootprint()
{
return 0;
}
public override string ToString()
{
return string.Format("Bike");
}
}
public class Car : CarBicycleBase
{
public int GallonOfGas { get; set; }
public Car(int gallonOfGas, string make, string model)
: base(make, model)
{
GallonOfGas = gallonOfGas;
}
public override int GetCarbonFootprint()
{
return GallonOfGas * 20;
}
public override string ToString()
{
return string.Format("Car");
}
}
Example:
...
var list = new List<ICarbonFootprint>(3)
{
new Car(10, "...", "..."),
new Bicycle("...", "..."),
new Building(20, "...")
};
foreach (ICarbonFootprint item in list)
item.GetCarbonFootprint();
...
I hope it helps.
Request Class Structure:
public class QueryParams {
public List<QueryParam> QueryParam { get; set; }
}
public class QueryParam {
public string Parameter { get; set; }
}
Service is Expecting in below format:
<typ:queryParams>
<typ:queryParam>
<typ:parameter>BUSINESS_CATEGORY</typ:parameter>
</typ:queryParam>
<typ:queryParam>
<typ:parameter>CATEGORY</typ:parameter>
</typ:queryParam>
</typ:queryParams>
How i can form the request?
using QueryParams = System.Collections.Generic.List<QueryParam>;
public class QueryParam {
public string Parameter { get; set; }
public QueryParam(string para) {
Parameter = para;
}
}
public class Program
{
public static void Main()
{
var Qp = new QueryParams() {
new QueryParam("BUSINESS_CATEGORY"),
new QueryParam("CATEGORY")
};
string QpXml = ToXml(Qp);
// Use your XML from here on
}
private static string ToXml(QueryParams Qp) {
StringBuilder Sb = new StringBuilder();
Sb.AppendLine("<typ:queryParams>");
foreach (var q in Qp) {
Sb.AppendLine("<typ:queryParam>");
Sb.AppendLine("<typ:parameter>" + q.Parameter + "</typ:parameter>");
Sb.AppendLine("</typ:queryParam>");
}
Sb.AppendLine("</typ:queryParams>");
return Sb.ToString();
}
}
See this .NET Fiddle