Skip to content

Instantly share code, notes, and snippets.

@t2-support-gists
Last active December 15, 2015 02:49
Show Gist options
  • Save t2-support-gists/5189858 to your computer and use it in GitHub Desktop.
Save t2-support-gists/5189858 to your computer and use it in GitHub Desktop.
SpeechCustom Csharp RESTFul App 1
******************************************************************************************
* Licensed by AT&T under 'Software Development Kit Tools Agreement.' 2013
* Copyright 2013 AT&T Intellectual Property. All rights reserved. http://developer.att.com
* For more information contact [email protected]<mailto:[email protected]>
******************************************************************************************
AT&T API Samples - Speech Custom app 1
--------------------------------
This application allows the user to send an audio file for speech to text custom
transcription, and get the transcribed text.
This file describes how to set up, configure and run the C# Applications of the
AT&T .Net Restful sample applications.
It covers all steps required to register the application on developer site and, based
on the generated API keys and secrets, create and run one's own full-fledged
sample applications.
1. Configuration
2. Installation
3. Parameters
4. Running the application
1. Configuration
Configuration consists of a few steps necessary to get an application registered
on developer site with the proper services and endpoints, depending on the type of
client-side application (autonomous/non-autonomous).
To register an application, go to https://developer.att.com/ and login with
your valid username and password. Next, choose "My Apps" from the bar at the top
of the page and click the "Setup a New Application" button.
Fill in the form, in particular all fields marked as "required".
NOTE: You MUST select Speech To Text Custom in the list of services under field 'Services' in
order to use this sample application code.
Having your application registered, you will get back an important pair of data:
an API key and Secret key. They are necessary to get your applications working
with the AT&T Platform APIs.
Initially your newly registered application is restricted to the "Sandbox"
environment only. To move it to production, you may promote it by clicking the
"Promote to production" button. Notice that you will get a different API key and
secret, so these values in your application should be adjusted accordingly.
Depending on the kind of authentication used, an application may be based on
either the Autonomous Client or the Web-Server Client OAuth flow.
2. Installation
** Requirements
To run the examples you need an IIS Server.
Download the application files from the download link published in AT&T portal
into webdomain of your IIS server.
3. Parameters
Each sample application contains an web.config file. This file
is located in the 'app' folder. This file holds configurable
parameters described in an easy-to-read format. Please modify the
web.config file using the comments specified within the file.
Note: If your application is promoted from Sandbox environment to Production
environment and you decide to use production application settings, you must
update parameters as per production application details.
4. Running the application
Suppose you copied the sample app files in your IIS server webroot/speechcustom/app1/ folder.
In order to run the sample application, type in'http://IIS_HOSTNAME:8080/speechcustom/app1/Default.aspx'
(assuming you're using a HOSTNAME machine with IIS Server and have not changed the
default port number, otherwise adjust accordingly) on your browser.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="Speech_App1" %>
<!DOCTYPE html>
<!--
Licensed by AT&T under 'Software Development Kit Tools Agreement.' 2013
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION: http://developer.att.com/sdk_agreement/
Copyright 2013 AT&T Intellectual Property. All rights reserved. http://developer.att.com
For more information contact [email protected]
-->
<!--[if lt IE 7]> <html class="ie6" lang="en"> <![endif]-->
<!--[if IE 7]> <html class="ie7" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="ie8" lang="en"> <![endif]-->
<!--[if gt IE 8]><!-->
<html lang="en">
<!--<![endif]-->
<head>
<title>AT&amp;T Sample Speech Application - Speech to Text Custom </title>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<meta id="viewport" name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="style/common.css" />
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-33466541-1']);
_gaq.push(['_trackPageview']);
(function () {
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl'
: 'http://www')
+ '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();
function enableNameParam(list, nameParam) {
var selectedValue = list.options[list.selectedIndex].value;
if (selectedValue == "GenericHints") {
document.getElementById("nameParam").disabled = false;
} else {
document.getElementById("nameParam").disabled = true;
var choices = document.getElementById("nameParam");
choices.options[0].selected = true;
}
}
</script>
</head>
<body>
<div id="pageContainer" class="pageContainer">
<div id="header">
<div class="logo" id="top">
</div>
<div id="menuButton" class="hide">
<a id="jump" href="#nav">Main Navigation</a>
</div>
<ul class="links" id="nav">
<li><a id="SourceLink" runat="server" target="_blank">Source<img src="images/source.png"
alt="" />
</a><span class="divider">|&nbsp;</span> </li>
<li><a id="DownloadLink" runat="server" target="_blank">Download<img src="images/download.png"
alt="" />
</a><span class="divider">|&nbsp;</span> </li>
<li><a id="HelpLink" runat="server" target="_blank">Help </a></li>
<li id="back"><a href="#top">Back to top</a></li>
</ul>
</div>
<form id="form1" runat="server">
<div id="content" class="content">
<div id="contentHeading" class="contentHeading">
<h1>
AT&amp;T Sample Application - Speech to Text Custom</h1>
<div id="introtext">
<div>
<b>Server Time:&nbsp;</b><%= String.Format("{0:ddd, MMMM dd, yyyy HH:mm:ss}", DateTime.UtcNow) + " UTC" %>
</div>
<div>
<b>Client Time:</b>
<script language="JavaScript" type="text/javascript">
var myDate = new Date();
document.write(myDate);
</script>
</div>
<div>
<b>User Agent:</b>
<script language="JavaScript" type="text/javascript">
document.write("" + navigator.userAgent);
</script>
</div>
</div>
</div>
<div class="formBox" id="formBox">
<div id="formContainer" class="formContainer">
<div id="formData">
<h3>
Speech Context:
</h3>
<asp:DropDownList ID="SpeechContext" runat="server" onchange="enableNameParam(this,'nameParam')">
</asp:DropDownList>
<h3>Name Parameter:</h3>
<asp:DropDownList ID="nameParam" name="nameParam" runat="server">
</asp:DropDownList>
<h3>
Audio File:
</h3>
<asp:DropDownList ID="audio_file" runat="server">
</asp:DropDownList>
<br />
<h3>
X-Arg:
</h3>
<asp:Label ID="x_arg" runat="server" name="x_arg"></asp:Label>
<br />
<h3>
MIME Data:
</h3>
<asp:TextBox ID="mimeData" type="text" runat="server" TextMode="MultiLine" Enabled="False" Rows="4" name="mimeData"></asp:TextBox>
<br />
<button id="SpeechToTextCustom" onserverclick="BtnSubmit_Click" runat="server" name="SpeechToTextCustom"
type="submit">
Submit</button>
</div>
</div>
</div>
<% if (!string.IsNullOrEmpty (speechSuccessMessage)){ %>
<div class="successWide" align="left">
<strong>SUCCESS:</strong>
<br />
Response parameters listed below.
</div>
<table id="kvp" class="kvp">
<thead>
<tr>
<th class="label">Parameter</th>
<th class="label">Value</th>
</tr>
</thead>
<tbody>
<tr>
<td class="cell" align="center"><em>ResponseId</em></td>
<td class="cell" align="center"><em><%= speechResponseData.Recognition.ResponseId %></em></td>
</tr>
<tr>
<td class="cell" align="center"><em>Status</em></td>
<td class="cell" align="center"><em><%= speechResponseData.Recognition.Status %></em></td>
</tr>
<%
if ((speechResponseData.Recognition.NBest != null) && (speechResponseData.Recognition.NBest.Count > 0)) {
foreach (NBest nbest in speechResponseData.Recognition.NBest){ %>
<tr>
<td class="cell" align="center"><em>Hypothesis</em></td>
<td class="cell" align="center"><em><%= nbest.Hypothesis %></em></td>
</tr>
<tr>
<td class="cell" align="center"><em>LanguageId</em></td>
<td class="cell" align="center"><em><%= nbest.LanguageId%></em></td>
</tr>
<tr>
<td class="cell" align="center"><em>Confidence</em></td>
<td class="cell" align="center"><em><%= nbest.Confidence %></em></td>
</tr>
<tr>
<td class="cell" align="center"><em>Grade</em></td>
<td class="cell" align="center"><em><%= nbest.Grade %></em></td>
</tr>
<tr>
<td class="cell" align="center"><em>ResultText</em></td>
<td class="cell" align="center"><em><%= nbest.ResultText %></em></td>
</tr>
<tr>
<td class="cell" align="center"><em>Words</em></td>
<td class="cell" align="center"><em><%= string.Join(", ", nbest.Words.ToArray())%></em></td>
</tr>
<tr>
<td class="cell" align="center"><em>WordScores</em></td>
<td class="cell" align="center"><em><%= string.Join(", ", nbest.WordScores.ToArray())%></em></td>
</tr>
<% if (nbest.NluHypothesis != null)
{ %>
<tr>
<td class="cell" align="center"><em>NluHypothesis</em></td>
<td class="cell" align="center"><em></em></td>
</tr>
<% foreach (outComposite comp in nbest.NluHypothesis.OutComposite.ToList())
{ %>
<tr>
<td class="cell" align="center"><em>Grammar</em></td>
<td class="cell" align="center"><em><%= comp.Grammar%></em></td>
</tr>
<tr>
<td class="cell" align="center"><em>Out</em></td>
<td class="cell" align="center"><em><%= comp.Out%></em></td>
</tr>
<%} %>
<%} %>
<%} %>
<%} %>
</tbody>
</table>
<% } %>
<% if (!string.IsNullOrEmpty(speechErrorMessage)){ %>
<div class="errorWide">
<strong>ERROR:</strong>
<br />
<%= speechErrorMessage %>
</div>
<% } %>
</div>
</form>
<div id="footer">
<div id="ft">
<div id="powered_by">
Powered by AT&amp;T Cloud Architecture
</div>
<p>
The Application hosted on this site are working examples intended to be used for
reference in creating products to consume AT&amp;T Services and not meant to be
used as part of your product. The data in these pages is for test purposes only
and intended only for use as a reference in how the services perform.
<br />
<br />
For download of tools and documentation, please go to <a href="https://developer.att.com/"
target="_blank">https://developer.att.com</a>
<br />
For more information contact <a href="mailto:[email protected]">[email protected]</a>
<br />
<br />
© 2014 AT&amp;T Intellectual Property. All rights reserved. <a href="https://developer.att.com/"
target="_blank">https://developer.att.com</a>
</p>
</div>
<!-- end of ft -->
</div>
<!-- end of footer -->
</div>
</body>
</html>
// <copyright file="Default.aspx.cs" company="AT&amp;T">
// Licensed by AT&amp;T under 'Software Development Kit Tools Agreement.' 2013
// TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION: http://developer.att.com/sdk_agreement/
// Copyright 2013 AT&amp;T Intellectual Property. All rights reserved. http://developer.att.com
// For more information contact [email protected]
// </copyright>
#region References
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Web.Script.Serialization;
using System.Web.UI.HtmlControls;
#endregion
/// <summary>
/// Speech application
/// </summary>
public partial class Speech_App1 : System.Web.UI.Page
{
#region Class variables and Data structures
/// <summary>
/// Temporary variables for processing
/// </summary>
private string fqdn, accessTokenFilePath;
/// <summary>
/// Temporary variables for processing
/// </summary>
private string apiKey, secretKey, accessToken, scope, refreshToken, refreshTokenExpiryTime, accessTokenExpiryTime, bypassSSL;
/// <summary>
/// variable for having the posted file.
/// </summary>
private string SpeechFilesDir;
/// <summary>
/// Gets or sets the value of refreshTokenExpiresIn
/// </summary>
private int refreshTokenExpiresIn;
private string xgrammer = string.Empty;
private string xdictionary = string.Empty;
private string xgrammerContent = string.Empty;
private string xdictionaryContent = string.Empty;
public string speechErrorMessage = string.Empty;
public string speechSuccessMessage = string.Empty;
public SpeechResponse speechResponseData = null;
/// <summary>
/// Access Token Types
/// </summary>
public enum AccessType
{
/// <summary>
/// Access Token Type is based on Client Credential Mode
/// </summary>
ClientCredential,
/// <summary>
/// Access Token Type is based on Refresh Token
/// </summary>
RefreshToken
}
#endregion
#region Events
/// <summary>
/// This function is called when the applicaiton page is loaded into the browser.
/// This function reads the web.config and gets the values of the attributes
/// </summary>
/// <param name="sender">Button that caused this event</param>
/// <param name="e">Event that invoked this function</param>
protected void Page_Load(object sender, EventArgs e)
{
BypassCertificateError();
this.ReadConfigFile();
this.SetContent();
}
/// <summary>
/// Method that calls SpeechToText api when user clicked on submit button
/// </summary>
/// <param name="sender">sender that invoked this event</param>
/// <param name="e">eventargs of the button</param>
protected void BtnSubmit_Click(object sender, EventArgs e)
{
try
{
bool IsValid = true;
IsValid = this.ReadAndGetAccessToken(ref speechErrorMessage);
if (IsValid == false)
{
speechErrorMessage = "Unable to get access token";
return;
}
var speechFile = this.SpeechFilesDir + audio_file.SelectedValue.ToString();
this.ConvertToSpeech(this.fqdn + "/speech/v3/speechToTextCustom",
this.accessToken, SpeechContext.SelectedValue.ToString(), x_arg.Text, speechFile);
}
catch (Exception ex)
{
speechErrorMessage = ex.Message;
return;
}
}
private void SetContent()
{
StreamReader streamReader = new StreamReader(this.xdictionary);
xdictionaryContent = streamReader.ReadToEnd();
mimeData.Text = "x-dictionary:" + Environment.NewLine + xdictionaryContent;
StreamReader streamReader1 = new StreamReader(this.xgrammer);
xgrammerContent = streamReader1.ReadToEnd();
mimeData.Text = mimeData.Text + Environment.NewLine + "x-grammar:" + Environment.NewLine + xgrammerContent;
streamReader.Close();
streamReader1.Close();
}
#endregion
#region Access Token Related Functions
/// <summary>
/// Read parameters from configuraton file
/// </summary>
/// <returns>true/false; true if all required parameters are specified, else false</returns>
private bool ReadConfigFile()
{
this.accessTokenFilePath = ConfigurationManager.AppSettings["AccessTokenFilePath"];
if (string.IsNullOrEmpty(this.accessTokenFilePath))
{
this.accessTokenFilePath = "~\\SpeechApp1AccessToken.txt";
}
this.fqdn = ConfigurationManager.AppSettings["FQDN"];
if (string.IsNullOrEmpty(this.fqdn))
{
speechErrorMessage = "FQDN is not defined in configuration file";
return false;
}
this.apiKey = ConfigurationManager.AppSettings["api_key"];
if (string.IsNullOrEmpty(this.apiKey))
{
speechErrorMessage = "api_key is not defined in configuration file";
return false;
}
this.secretKey = ConfigurationManager.AppSettings["secret_key"];
if (string.IsNullOrEmpty(this.secretKey))
{
speechErrorMessage = "secret_key is not defined in configuration file";
return false;
}
this.scope = ConfigurationManager.AppSettings["scope"];
if (string.IsNullOrEmpty(this.scope))
{
this.scope = "SPEECH";
}
string refreshTokenExpires = ConfigurationManager.AppSettings["refreshTokenExpiresIn"];
if (!string.IsNullOrEmpty(refreshTokenExpires))
{
this.refreshTokenExpiresIn = Convert.ToInt32(refreshTokenExpires);
}
else
{
this.refreshTokenExpiresIn = 24;
}
if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["SourceLink"]))
{
SourceLink.HRef = ConfigurationManager.AppSettings["SourceLink"];
}
else
{
SourceLink.HRef = "#"; // Default value
}
if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["DownloadLink"]))
{
DownloadLink.HRef = ConfigurationManager.AppSettings["DownloadLink"];
}
else
{
DownloadLink.HRef = "#"; // Default value
}
if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["HelpLink"]))
{
HelpLink.HRef = ConfigurationManager.AppSettings["HelpLink"];
}
else
{
HelpLink.HRef = "#"; // Default value
}
if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["SpeechFilesDir"]))
{
this.SpeechFilesDir = Request.MapPath(ConfigurationManager.AppSettings["SpeechFilesDir"]);
}
if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["xgrammer"]))
{
this.xgrammer = Request.MapPath(ConfigurationManager.AppSettings["xgrammer"]);
}
if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["xdictionary"]))
{
this.xdictionary = Request.MapPath(ConfigurationManager.AppSettings["xdictionary"]);
}
if (!IsPostBack)
{
if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["SpeechContext"]))
{
string[] speechContexts = ConfigurationManager.AppSettings["SpeechContext"].ToString().Split(';');
foreach (string speechContext in speechContexts)
{
SpeechContext.Items.Add(speechContext);
}
if (speechContexts.Length > 0)
SpeechContext.Items[0].Selected = true;
}
if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["NameParameters"]))
{
string[] nameParameters = ConfigurationManager.AppSettings["NameParameters"].ToString().Split(';');
foreach (string nameParameter in nameParameters)
{
nameParam.Items.Add(nameParameter);
}
if (nameParameters.Length > 0)
nameParam.Items[0].Selected = true;
}
if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["X-ArgGeneric"]))
{
x_arg.Text = ConfigurationManager.AppSettings["X-ArgGeneric"];
}
if (!string.IsNullOrEmpty(SpeechFilesDir))
{
string[] filePaths = Directory.GetFiles(this.SpeechFilesDir);
foreach (string filePath in filePaths)
{
audio_file.Items.Add(Path.GetFileName(filePath));
}
if (filePaths.Length > 0)
audio_file.Items[0].Selected = true;
}
}
return true;
}
/// <summary>
/// This function reads the Access Token File and stores the values of access token, expiry seconds
/// refresh token, last access token time and refresh token expiry time
/// This funciton returns true, if access token file and all others attributes read successfully otherwise returns false
/// </summary>
/// <param name="panelParam">Panel Details</param>
/// <returns>Returns boolean</returns>
private bool ReadAccessTokenFile(ref string message)
{
FileStream fileStream = null;
StreamReader streamReader = null;
try
{
fileStream = new FileStream(Request.MapPath(this.accessTokenFilePath), FileMode.OpenOrCreate, FileAccess.Read);
streamReader = new StreamReader(fileStream);
this.accessToken = streamReader.ReadLine();
this.accessTokenExpiryTime = streamReader.ReadLine();
this.refreshToken = streamReader.ReadLine();
this.refreshTokenExpiryTime = streamReader.ReadLine();
}
catch (Exception ex)
{
message = ex.Message;
return false;
}
finally
{
if (null != streamReader)
{
streamReader.Close();
}
if (null != fileStream)
{
fileStream.Close();
}
}
if ((this.accessToken == null) || (this.accessTokenExpiryTime == null) || (this.refreshToken == null) || (this.refreshTokenExpiryTime == null))
{
return false;
}
return true;
}
/// <summary>
/// This function validates the expiry of the access token and refresh token.
/// function compares the current time with the refresh token taken time, if current time is greater then returns INVALID_REFRESH_TOKEN
/// function compares the difference of last access token taken time and the current time with the expiry seconds, if its more, returns INVALID_ACCESS_TOKEN
/// otherwise returns VALID_ACCESS_TOKEN
/// </summary>
/// <returns>string, which specifies the token validity</returns>
private string IsTokenValid()
{
try
{
DateTime currentServerTime = DateTime.UtcNow.ToLocalTime();
if (currentServerTime >= DateTime.Parse(this.accessTokenExpiryTime))
{
if (currentServerTime >= DateTime.Parse(this.refreshTokenExpiryTime))
{
return "INVALID_ACCESS_TOKEN";
}
else
{
return "REFRESH_TOKEN";
}
}
else
{
return "VALID_ACCESS_TOKEN";
}
}
catch
{
return "INVALID_ACCESS_TOKEN";
}
}
/// <summary>
/// This function get the access token based on the type parameter type values.
/// If type value is 1, access token is fetch for client credential flow
/// If type value is 2, access token is fetch for client credential flow based on the exisiting refresh token
/// </summary>
/// <param name="type">Type as integer</param>
/// <param name="panelParam">Panel details</param>
/// <returns>Return boolean</returns>
private bool GetAccessToken(AccessType type, ref string message)
{
FileStream fileStream = null;
Stream postStream = null;
StreamWriter streamWriter = null;
// This is client credential flow
if (type == AccessType.ClientCredential)
{
try
{
DateTime currentServerTime = DateTime.UtcNow.ToLocalTime();
WebRequest accessTokenRequest = System.Net.HttpWebRequest.Create(string.Empty + this.fqdn + "/oauth/v4/token");
accessTokenRequest.Method = "POST";
string oauthParameters = string.Empty;
if (type == AccessType.ClientCredential)
{
oauthParameters = "client_id=" + this.apiKey + "&client_secret=" + this.secretKey + "&grant_type=client_credentials&scope=" + this.scope;
}
else
{
oauthParameters = "grant_type=refresh_token&client_id=" + this.apiKey + "&client_secret=" + this.secretKey + "&refresh_token=" + this.refreshToken;
}
accessTokenRequest.ContentType = "application/x-www-form-urlencoded";
UTF8Encoding encoding = new UTF8Encoding();
byte[] postBytes = encoding.GetBytes(oauthParameters);
accessTokenRequest.ContentLength = postBytes.Length;
postStream = accessTokenRequest.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
WebResponse accessTokenResponse = accessTokenRequest.GetResponse();
using (StreamReader accessTokenResponseStream = new StreamReader(accessTokenResponse.GetResponseStream()))
{
string jsonAccessToken = accessTokenResponseStream.ReadToEnd().ToString();
JavaScriptSerializer deserializeJsonObject = new JavaScriptSerializer();
AccessTokenResponse deserializedJsonObj = (AccessTokenResponse)deserializeJsonObject.Deserialize(jsonAccessToken, typeof(AccessTokenResponse));
this.accessToken = deserializedJsonObj.access_token;
this.accessTokenExpiryTime = currentServerTime.AddSeconds(Convert.ToDouble(deserializedJsonObj.expires_in)).ToString();
this.refreshToken = deserializedJsonObj.refresh_token;
DateTime refreshExpiry = currentServerTime.AddHours(this.refreshTokenExpiresIn);
if (deserializedJsonObj.expires_in.Equals("0"))
{
int defaultAccessTokenExpiresIn = 100; // In Yearsint yearsToAdd = 100;
this.accessTokenExpiryTime = currentServerTime.AddYears(defaultAccessTokenExpiresIn).ToLongDateString() + " " + currentServerTime.AddYears(defaultAccessTokenExpiresIn).ToLongTimeString();
}
this.refreshTokenExpiryTime = refreshExpiry.ToLongDateString() + " " + refreshExpiry.ToLongTimeString();
fileStream = new FileStream(Request.MapPath(this.accessTokenFilePath), FileMode.OpenOrCreate, FileAccess.Write);
streamWriter = new StreamWriter(fileStream);
streamWriter.WriteLine(this.accessToken);
streamWriter.WriteLine(this.accessTokenExpiryTime);
streamWriter.WriteLine(this.refreshToken);
streamWriter.WriteLine(this.refreshTokenExpiryTime);
// Close and clean up the StreamReader
accessTokenResponseStream.Close();
return true;
}
}
catch (WebException we)
{
string errorResponse = string.Empty;
try
{
using (StreamReader sr2 = new StreamReader(we.Response.GetResponseStream()))
{
errorResponse = sr2.ReadToEnd();
sr2.Close();
}
}
catch
{
errorResponse = "Unable to get response";
}
message = errorResponse + Environment.NewLine + we.ToString();
}
catch (Exception ex)
{
message = ex.Message;
return false;
}
finally
{
if (null != postStream)
{
postStream.Close();
}
if (null != streamWriter)
{
streamWriter.Close();
}
if (null != fileStream)
{
fileStream.Close();
}
}
}
else if (type == AccessType.RefreshToken)
{
try
{
DateTime currentServerTime = DateTime.UtcNow.ToLocalTime();
WebRequest accessTokenRequest = System.Net.HttpWebRequest.Create(string.Empty + this.fqdn + "/oauth/v4/token");
accessTokenRequest.Method = "POST";
string oauthParameters = "grant_type=refresh_token&client_id=" + this.apiKey + "&client_secret=" + this.secretKey + "&refresh_token=" + this.refreshToken;
accessTokenRequest.ContentType = "application/x-www-form-urlencoded";
UTF8Encoding encoding = new UTF8Encoding();
byte[] postBytes = encoding.GetBytes(oauthParameters);
accessTokenRequest.ContentLength = postBytes.Length;
postStream = accessTokenRequest.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
WebResponse accessTokenResponse = accessTokenRequest.GetResponse();
using (StreamReader accessTokenResponseStream = new StreamReader(accessTokenResponse.GetResponseStream()))
{
string accessTokenJSon = accessTokenResponseStream.ReadToEnd().ToString();
JavaScriptSerializer deserializeJsonObject = new JavaScriptSerializer();
AccessTokenResponse deserializedJsonObj = (AccessTokenResponse)deserializeJsonObject.Deserialize(accessTokenJSon, typeof(AccessTokenResponse));
this.accessToken = deserializedJsonObj.access_token.ToString();
DateTime accessTokenExpiryTime = currentServerTime.AddMilliseconds(Convert.ToDouble(deserializedJsonObj.expires_in.ToString()));
this.refreshToken = deserializedJsonObj.refresh_token.ToString();
fileStream = new FileStream(Request.MapPath(this.accessTokenFilePath), FileMode.OpenOrCreate, FileAccess.Write);
streamWriter = new StreamWriter(fileStream);
streamWriter.WriteLine(this.accessToken);
streamWriter.WriteLine(this.accessTokenExpiryTime);
streamWriter.WriteLine(this.refreshToken);
// Refresh token valids for 24 hours
DateTime refreshExpiry = currentServerTime.AddHours(24);
this.refreshTokenExpiryTime = refreshExpiry.ToLongDateString() + " " + refreshExpiry.ToLongTimeString();
streamWriter.WriteLine(refreshExpiry.ToLongDateString() + " " + refreshExpiry.ToLongTimeString());
accessTokenResponseStream.Close();
return true;
}
}
catch (WebException we)
{
string errorResponse = string.Empty;
try
{
using (StreamReader sr2 = new StreamReader(we.Response.GetResponseStream()))
{
errorResponse = sr2.ReadToEnd();
sr2.Close();
}
}
catch
{
errorResponse = "Unable to get response";
}
message = errorResponse + Environment.NewLine + we.ToString();
}
catch (Exception ex)
{
message = ex.Message;
return false;
}
finally
{
if (null != postStream)
{
postStream.Close();
}
if (null != streamWriter)
{
streamWriter.Close();
}
if (null != fileStream)
{
fileStream.Close();
}
}
}
return false;
}
/// <summary>
/// Neglect the ssl handshake error with authentication server
/// </summary>
private static void BypassCertificateError()
{
string bypassSSL = ConfigurationManager.AppSettings["IgnoreSSL"];
if ((!string.IsNullOrEmpty(bypassSSL))
&& (string.Equals(bypassSSL, "true", StringComparison.OrdinalIgnoreCase)))
{
ServicePointManager.ServerCertificateValidationCallback +=
delegate(Object sender1, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
};
}
}
/// <summary>
/// This function is used to read access token file and validate the access token
/// this function returns true if access token is valid, or else false is returned
/// </summary>
/// <param name="panelParam">Panel Details</param>
/// <returns>Returns Boolean</returns>
private bool ReadAndGetAccessToken(ref string responseString)
{
bool result = true;
if (this.ReadAccessTokenFile(ref responseString) == false)
{
result = this.GetAccessToken(AccessType.ClientCredential, ref responseString);
}
else
{
string tokenValidity = this.IsTokenValid();
if (tokenValidity == "REFRESH_TOKEN")
{
result = this.GetAccessToken(AccessType.RefreshToken, ref responseString);
}
else if (string.Compare(tokenValidity, "INVALID_ACCESS_TOKEN") == 0)
{
result = this.GetAccessToken(AccessType.ClientCredential, ref responseString);
}
}
if (this.accessToken == null || this.accessToken.Length <= 0)
{
return false;
}
else
{
return result;
}
}
#endregion
#region Speech Service Functions
/// <summary>
/// Content type based on the file extension.
/// </summary>
/// <param name="extension">file extension</param>
/// <returns>the Content type mapped to the extension"/> summed memory stream</returns>
private string MapContentTypeFromExtension(string extension)
{
Dictionary<string, string> extensionToContentTypeMapping = new Dictionary<string, string>()
{
{ ".amr", "audio/amr" }, { ".wav", "audio/wav" }, {".awb", "audio/amr-wb"}, {".spx", "audio/x-speex"}
};
if (extensionToContentTypeMapping.ContainsKey(extension))
{
return extensionToContentTypeMapping[extension];
}
else
{
throw new ArgumentException("invalid attachment extension");
}
}
/// <summary>
/// This function invokes api SpeechToText to convert the given wav amr file and displays the result.
/// </summary>
private void ConvertToSpeech(string parEndPoint, string parAccessToken, string parXspeechContext, string parXArgs, string parSpeechFilePath)
{
Stream postStream = null;
FileStream audioFileStream = null;
audioFileStream = new FileStream(parSpeechFilePath, FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(audioFileStream);
try
{
byte[] binaryData = reader.ReadBytes((int)audioFileStream.Length);
if (null != binaryData)
{
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(string.Empty + parEndPoint);
httpRequest.Headers.Add("Authorization", "Bearer " + parAccessToken);
httpRequest.Headers.Add("X-SpeechContext", parXspeechContext);
httpRequest.Headers.Add("Content-Language", "en-us");
httpRequest.ContentType = "multipart/x-srgs-audio; " + "boundary=" + boundary;
if (!string.IsNullOrEmpty(parXArgs))
{
httpRequest.Headers.Add("X-Arg", parXArgs);
}
string filenameArgument = "filename";
if (!string.IsNullOrEmpty(SpeechContext.SelectedValue))
{
if (string.Compare("GenericHints", SpeechContext.SelectedValue) == 0)
{
filenameArgument = nameParam.SelectedValue.ToString();
}
}
string contentType = this.MapContentTypeFromExtension(Path.GetExtension(parSpeechFilePath));
string data = string.Empty;
data += "--" +boundary + "\r\n" + "Content-Disposition: form-data; name=\"x-dictionary\"; " + filenameArgument + "=\"speech_alpha.pls\"\r\nContent-Type: application/pls+xml\r\n";
data += "\r\n" + xdictionaryContent + "\r\n\r\n\r\n";
data += "--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"x-grammar\"";
//data += "filename=\"prefix.srgs\" ";
data += "\r\nContent-Type: application/srgs+xml \r\n" + "\r\n" + xgrammerContent + "\r\n\r\n\r\n" + "--" + boundary + "\r\n";
data += "Content-Disposition: form-data; name=\"x-voice\"; " + filenameArgument + "=\"" + audio_file.SelectedValue + "\"";
data += "\r\nContent-Type: " + contentType + "\r\n\r\n";
UTF8Encoding encoding = new UTF8Encoding();
byte[] firstPart = encoding.GetBytes(data);
int newSize = firstPart.Length + binaryData.Length;
var memoryStream = new MemoryStream(new byte[newSize], 0, newSize, true, true);
memoryStream.Write(firstPart, 0, firstPart.Length);
memoryStream.Write(binaryData, 0, binaryData.Length);
byte[] postBytes = memoryStream.GetBuffer();
byte[] byteLastBoundary = encoding.GetBytes("\r\n\r\n" + "--" + boundary + "--");
int totalSize = postBytes.Length + byteLastBoundary.Length;
var totalMS = new MemoryStream(new byte[totalSize], 0, totalSize, true, true);
totalMS.Write(postBytes, 0, postBytes.Length);
totalMS.Write(byteLastBoundary, 0, byteLastBoundary.Length);
byte[] finalpostBytes = totalMS.GetBuffer();
httpRequest.ContentLength = totalMS.Length;
//httpRequest.ContentType = contentType;
httpRequest.Accept = "application/json";
httpRequest.Method = "POST";
httpRequest.KeepAlive = true;
postStream = httpRequest.GetRequestStream();
postStream.Write(finalpostBytes, 0, finalpostBytes.Length);
postStream.Close();
HttpWebResponse speechResponse = (HttpWebResponse)httpRequest.GetResponse();
using (StreamReader streamReader = new StreamReader(speechResponse.GetResponseStream()))
{
string speechRequestResponse = streamReader.ReadToEnd();
if (!string.IsNullOrEmpty(speechRequestResponse))
{
JavaScriptSerializer deserializeJsonObject = new JavaScriptSerializer();
SpeechResponse deserializedJsonObj = (SpeechResponse)deserializeJsonObject.Deserialize(speechRequestResponse, typeof(SpeechResponse));
if (null != deserializedJsonObj)
{
speechResponseData = new SpeechResponse();
speechResponseData = deserializedJsonObj;
speechSuccessMessage = "true";
//speechErrorMessage = speechRequestResponse;
}
else
{
speechErrorMessage = "Empty speech to text response";
}
}
else
{
speechErrorMessage = "Empty speech to text response";
}
streamReader.Close();
}
}
else
{
speechErrorMessage = "Empty speech to text response";
}
}
catch (WebException we)
{
string errorResponse = string.Empty;
try
{
using (StreamReader sr2 = new StreamReader(we.Response.GetResponseStream()))
{
errorResponse = sr2.ReadToEnd();
sr2.Close();
}
}
catch
{
errorResponse = "Unable to get response";
}
speechErrorMessage = errorResponse;
}
catch (Exception ex)
{
speechErrorMessage = ex.ToString();
}
finally
{
reader.Close();
audioFileStream.Close();
if (null != postStream)
{
postStream.Close();
}
}
}
#endregion
}
#region Access Token and Speech Response Data Structures
/// <summary>
/// Access Token Data Structure
/// </summary>
public class AccessTokenResponse
{
/// <summary>
/// Gets or sets Access Token ID
/// </summary>
public string access_token
{
get;
set;
}
/// <summary>
/// Gets or sets Refresh Token ID
/// </summary>
public string refresh_token
{
get;
set;
}
/// <summary>
/// Gets or sets Expires in milli seconds
/// </summary>
public string expires_in
{
get;
set;
}
}
/// <summary>
/// Speech Response to an audio file
/// </summary>
public class SpeechResponse
{
/// <summary>
/// Gets or sets the Recognition value returned by api
/// </summary>
public Recognition Recognition { get; set; }
}
/// <summary>
/// Recognition returned by the server for Speech to text request.
/// </summary>
public class Recognition
{
/// <summary>
/// Gets or sets a unique string that identifies this particular transaction.
/// </summary>
public string ResponseId { get; set; }
/// <summary>
/// Gets or sets NBest Complex structure that holds the results of the transcription. Supports multiple transcriptions.
/// </summary>
public List<NBest> NBest { get; set; }
/// <summary>
/// Gets or sets the Status of the transcription.
/// </summary>
public string Status { get; set; }
}
public class nluHypothesis
{
public outComposite[] OutComposite { get; set; }
}
public class outComposite
{
public string Grammar { get; set; }
public string Out { get; set; }
}
/// <summary>
/// Complex structure that holds the results of the transcription. Supports multiple transcriptions.
/// </summary>
public class NBest
{
/// <summary>
/// Gets or sets the transcription of the audio.
/// </summary>
public string Hypothesis { get; set; }
/// <summary>
/// Gets or sets the language used to decode the Hypothesis.
/// Represented using the two-letter ISO 639 language code, hyphen, two-letter ISO 3166 country code in lower case, e.g. �en-us�.
/// </summary>
public string LanguageId { get; set; }
/// <summary>
/// Gets or sets the confidence value of the Hypothesis, a value between 0.0 and 1.0 inclusive.
/// </summary>
public double Confidence { get; set; }
/// <summary>
/// Gets or sets a machine-readable string indicating an assessment of utterance/result quality and the recommended treatment of the Hypothesis.
/// The assessment reflects a confidence region based on prior experience with similar results.
/// accept - the hypothesis value has acceptable confidence
/// confirm - the hypothesis should be independently confirmed due to lower confidence
/// reject - the hypothesis should be rejected due to low confidence
/// </summary>
public string Grade { get; set; }
/// <summary>
/// Gets or sets a text string prepared according to the output domain of the application package.
/// The string will generally be a formatted version of the hypothesis, but the words may have been altered through
/// insertions/deletions/substitutions to make the result more readable or usable for the client.
/// </summary>
public string ResultText { get; set; }
/// <summary>
/// Gets or sets the words of the Hypothesis split into separate strings.
/// May omit some of the words of the Hypothesis string, and can be empty. Never contains words not in hypothesis string.
/// </summary>
public List<string> Words { get; set; }
/// <summary>
/// Gets or sets the confidence scores for each of the strings in the words array. Each value ranges from 0.0 to 1.0 inclusive.
/// </summary>
public List<double> WordScores { get; set; }
public nluHypothesis NluHypothesis { get; set; }
}
#endregion

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "app1", ".", "{07391EF4-B2EF-44A2-89EE-EC7E491EA534}"
ProjectSection(WebsiteProperties) = preProject
TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.0"
Debug.AspNetCompiler.VirtualPath = "/app1"
Debug.AspNetCompiler.PhysicalPath = "..\app1\"
Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\app1\"
Debug.AspNetCompiler.Updateable = "true"
Debug.AspNetCompiler.ForceOverwrite = "true"
Debug.AspNetCompiler.FixedNames = "false"
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.VirtualPath = "/app1"
Release.AspNetCompiler.PhysicalPath = "..\app1\"
Release.AspNetCompiler.TargetPath = "PrecompiledWeb\app1\"
Release.AspNetCompiler.Updateable = "true"
Release.AspNetCompiler.ForceOverwrite = "true"
Release.AspNetCompiler.FixedNames = "false"
Release.AspNetCompiler.Debug = "False"
VWDPort = "64812"
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{07391EF4-B2EF-44A2-89EE-EC7E491EA534}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{07391EF4-B2EF-44A2-89EE-EC7E491EA534}.Debug|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
<?xml version="1.0"?>
<!-- For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433 -->
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
<customErrors mode="Off"></customErrors>
</system.web>
<appSettings>
<!-- Set this parameter value to "true", if you need to bypass the SSL certificate. Default FALSE -->
<add key="IgnoreSSL" value="false"/>
<!-- This is mandatory parameter, set the value as per your registered application
'API key' field value. -->
<add key="api_key" value=""/>
<!-- This is mandatory parameter, set the value as per your registered application
'Secret key' field value. -->
<add key="secret_key" value=""/>
<!-- This is mandatory parameter, set it to the end point URI of AT&T Service. -->
<add key="FQDN" value=""></add>
<!-- Scope of the ATT service that will be invoked by the Application -->
<add key="scope" value="STTC"/>
<!-- This is optional parameter, which points to the file path, where application
stores access token information. If the parameter is not configured, it will take
the default value as ~\\SpeechApp1AccessToken.txt)
example: value="~\\Token.txt" -->
<add key="AccessTokenFilePath" value =""/>
<!-- This is mandatory parameter, which points to the directory which contains
only speech files. The filenames of this directory will be listed in drop down list.
example: value="~\\<SpeechFilesDirPath>\\" -->
<add key="SpeechFilesDir" value =""/>
<!-- This is optional key, which specifies the expiry time of refresh token in Hrs. Default value is 24Hrs.
example: value="24"-->
<add key="refreshTokenExpiresIn" value=""/>
<!-- This is optional key, the value of the this key is sent as a X-Agr hearder.
which should contain name value pair separated by semicolan Ex: name=value,name1=value1 -->
<add key="X-ArgGeneric" value="GrammarPenaltyPrefix=1.1,GrammarPenaltyGeneric=2.0,GrammarPenaltyAltgram=4.1"/>
<!-- This is mandatory key, the value of the this key is used to populate Speech Context drop down list.
The value of this key should contain list of speech context values separated by semicolan -->
<add key="SpeechContext" value="GrammerList;GenericHints"/>
<!-- This is mandatory key, the value of the this key is used to populate Name Parameter drop down list.
The value of this key should contain list of name parameter values separated by semicolan -->
<add key="NameParameters" value="x-grammar;x-grammar-prefix;x-grammar-altgram"/>
<!-- This is mandatory parameter, which points to the directory which contains
only speech files. The filenames of this directory will be listed in drop down list.
example: value="~\\<TTSFilesDirPath>\\" -->
<add key="xdictionary" value =""/>
<add key="xgrammer" value =""/>
<!-- These are optional keys. the values are used for hyperlink -->
<add key="SourceLink" value=""/>
<add key="DownloadLink" value=""/>
<add key="HelpLink" value=""/>
</appSettings>
</configuration>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment