如何使用 botframework 网络渠道授权 gmail 阅读我的收件箱
How to authorize gmail to read my inbox using botframework web channel
我正在尝试使用 gmail 服务来读取收件箱数据并在我的聊天机器人中显示它们。我想使用我的 gmail 帐户进行身份验证。当我在机器人模拟器中测试聊天机器人工作正常时,当我在网络上部署时问题就开始了。我无法在网络上进行身份验证。
string jsonPath2 = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath + "client_secret_webapp.json";
UserCredential credential;
string[] Scopes = { GmailService.Scope.GmailReadonly };
string credPath = System.Environment.GetFolderPath(
System.Environment.SpecialFolder.Personal);
using (var stream = new FileStream(jsonPath2, FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
// This OAuth 2.0 access scope allows for read-only access to the authenticated
// user's account, but not other types of account access.
new[] { GmailService.Scope.GmailReadonly,},
"xxxx@gmail.com",
CancellationToken.None,
new FileDataStore(this.GetType().ToString())
);
}
var gmailService = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = this.GetType().ToString()
});
log.Info("ApplicationName" + ApplicationName);
var emailListRequest = gmailService.Users.Messages.List("xxxxx@gmail.com");
emailListRequest.LabelIds = "INBOX";
emailListRequest.MaxResults = 1;
emailListRequest.Q = "is:unread";
emailListRequest.IncludeSpamTrash = false;
if (emailListResponse != null && emailListResponse.Messages != null)
{
//loop through each email and get what fields you want...
foreach (var email in emailListResponse.Messages)
{
var emailInfoRequest = gmailService.Users.Messages.Get("xxxxxx@gmail.com", email.Id);
var emailInfoResponse = emailInfoRequest.Execute();
if (emailInfoResponse != null)
{
String from = "";
String date = "";
String subject = "";
String body = "";
//loop through the headers to get from,date,subject, body
foreach (var mParts in emailInfoResponse.Payload.Headers)
{
if (mParts.Name == "Date")
{
date = mParts.Value;
}
else if (mParts.Name == "From")
{
from = mParts.Value;
}
else if (mParts.Name == "Subject")
{
subject = mParts.Value;
}
if (date != "" && from != "")
{
if (emailInfoResponse.Payload.Parts == null && emailInfoResponse.Payload.Body != null)
body = DecodeBase64String(emailInfoResponse.Payload.Body.Data);
else
body = GetNestedBodyParts(emailInfoResponse.Payload.Parts, "");
}
}
await context.PostAsync("Email list for: Date " + date + " ::::::::::: From: " + from + " :::::::::::: Subject " + subject + " : ::::::::::::: Body : " + body + " Email.id eshte " + email.Id);
}
}
}
}
static String DecodeBase64String(string s)
{
var ts = s.Replace("-", "+");
ts = ts.Replace("_", "/");
var bc = Convert.FromBase64String(ts);
var tts = Encoding.UTF8.GetString(bc);
return tts;
}
static String GetNestedBodyParts(IList<MessagePart> part, string curr)
{
string str = curr;
if (part == null)
{
return str;
}
else
{
foreach (var parts in part)
{
if (parts.Parts == null)
{
if (parts.Body != null && parts.Body.Data != null)
{
var ts = DecodeBase64String(parts.Body.Data);
str += ts;
}
}
else
{
return GetNestedBodyParts(parts.Parts, str);
}
}
return str;
}
}
private static byte[] FromBase64ForUrlString(string base64ForUrlInput)
{
int padChars = (base64ForUrlInput.Length % 4) == 0 ? 0 : (4 - (base64ForUrlInput.Length % 4));
StringBuilder result = new StringBuilder(base64ForUrlInput, base64ForUrlInput.Length + padChars);
result.Append(String.Empty.PadRight(padChars, '='));
result.Replace('-', '+');
result.Replace('_', '/');
return Convert.FromBase64String(result.ToString());
}
client_id.json
{"installed":{"client_id":"xxxxxxx- yyyyyy.apps.googleusercontent.com","project_id":"reademailbot","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"yyyyyyyyyyy","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
已编辑:
我尝试添加以下代码:
var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new
ClientSecrets
{
ClientId = "xx-
xxxxxxxxx.apps.googleusercontent.com",
ClientSecret = "xxxxxxxxxxxxxxxxxxxxx-lLO"
},
new[] {
GmailService.Scope.GmailReadonly,
GmailService.Scope.MailGoogleCom,
GmailService.Scope.GmailMetadata
},
"user",
CancellationToken.None,
new
FileDataStore("Drive.Auth.Store")).Result;
var gmailService = new Google.Apis.Gmail.v1.GmailService(new
BaseClientService.Initializer()
{
HttpClientInitializer = credential,
});
但是当我在网络上尝试时我仍然有问题:
Error: redirect_uri_mismatch
The redirect URI in the request, http://127.0.0.1:52158/authorize/, does not match the ones authorized for the OAuth client. To update the authorized redirect URIs, visit: https://console.developers.google.com/apis/credentials/oauthclient/673194113721-45u2pgl6m2l74ecf13c51fmmihrsu3jh.apps.googleusercontent.com?project=673194113721
编辑 2:
string[] Scopes = { GmailService.Scope.GmailReadonly };
string ApplicationName = "IkanbiBot";
var secrets = new ClientSecrets
{
ClientId = ConfigurationSettings.AppSettings["GMailClientId"],
ClientSecret = ConfigurationSettings.AppSettings["GMailClientSecret"]
};
var token = new Google.Apis.Auth.OAuth2.Responses.TokenResponse { RefreshToken = ConfigurationSettings.AppSettings["GmailRefreshToken"] };
var credential = new UserCredential(new GoogleAuthorizationCodeFlow(
new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = secrets
}), "xxxx@gmail.com", token);
var gmailService = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = this.GetType().ToString()
});
log4net.ILog log2 = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
await context.PostAsync("Aplication name is ..." + ApplicationName);
await context.PostAsync("secret name is ..." + secrets.ClientId + "_____ and .... " + secrets.ClientSecret + " ++++ token is " + token.RefreshToken);
var emailListRequest = gmailService.Users.Messages.List("xxxxx@gmail.com");
emailListRequest.LabelIds = "INBOX";
emailListRequest.MaxResults = 1;
emailListRequest.Q = "is:unread";
emailListRequest.IncludeSpamTrash = false;
// Get our emails
// Get our emails
var emailListResponse = emailListRequest.Execute();
//get our emails
log2.Info(emailListResponse.Messages);
await context.PostAsync("emailListResponse is ..." + emailListResponse.Messages.Count);
if (emailListResponse != null && emailListResponse.Messages != null)
{
//loop through each email and get what fields you want...
foreach (var email in emailListResponse.Messages)
{
var emailInfoRequest = gmailService.Users.Messages.Get("botikanbi@gmail.com", email.Id);
var emailInfoResponse = emailInfoRequest.Execute();
if (emailInfoResponse != null)
{
String from = "";
String date = "";
String subject = "";
String body = "";
//loop through the headers to get from,date,subject, body
foreach (var mParts in emailInfoResponse.Payload.Headers)
{
if (mParts.Name == "Date")
{
date = mParts.Value;
}
else if (mParts.Name == "From")
{
from = mParts.Value;
}
else if (mParts.Name == "Subject")
{
subject = mParts.Value;
}
if (date != "" && from != "")
{
if (emailInfoResponse.Payload.Parts == null && emailInfoResponse.Payload.Body != null)
body = DecodeBase64String(emailInfoResponse.Payload.Body.Data);
else
body = GetNestedBodyParts(emailInfoResponse.Payload.Parts, "");
}
}
await context.PostAsync("Email list for: Date " + date + " ::::::::::: From: " + from + " :::::::::::: Subject " + subject + " : ::::::::::::: Body : " + body + " Email.id eshte " + email.Id);
}
}
}
}
static String DecodeBase64String(string s)
{
var ts = s.Replace("-", "+");
ts = ts.Replace("_", "/");
var bc = Convert.FromBase64String(ts);
var tts = Encoding.UTF8.GetString(bc);
return tts;
}
static String GetNestedBodyParts(IList<MessagePart> part, string curr)
{
string str = curr;
if (part == null)
{
return str;
}
else
{
foreach (var parts in part)
{
if (parts.Parts == null)
{
if (parts.Body != null && parts.Body.Data != null)
{
var ts = DecodeBase64String(parts.Body.Data);
str += ts;
}
}
else
{
return GetNestedBodyParts(parts.Parts, str);
}
}
return str;
}
}
private static byte[] FromBase64ForUrlString(string base64ForUrlInput)
{
int padChars = (base64ForUrlInput.Length % 4) == 0 ? 0 : (4 - (base64ForUrlInput.Length % 4));
StringBuilder result = new StringBuilder(base64ForUrlInput, base64ForUrlInput.Length + padChars);
result.Append(String.Empty.PadRight(padChars, '='));
result.Replace('-', '+');
result.Replace('_', '/');
return Convert.FromBase64String(result.ToString());
}
}
}
现在我正在使用这段代码。我从机器人那里得到答案直到:
"secret name is ..." + secrets.ClientId + “_____ 和 ....” + secrets.ClientSecret + “++++ 令牌是” + token.RefreshToken
但是当尝试阅读电子邮件时停止 :(
你能帮我看看这是怎么回事吗?
有几种方法可以验证 google。
- 移动
- 网络
- 服务帐号
- 本机应用程序。
您为上述每种身份验证类型创建的客户端是不同的。使用它们的代码也不同。
GoogleWebAuthorizationBroker.AuthorizeAsync
用于验证已安装的应用程序。它不适用于 Web 应用程序。
对于 Web 应用程序,您应该遵循 Web applications (ASP.NET MVC) 并使用 GoogleAuthorizationCodeFlow
private static readonly IAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = "PUT_CLIENT_ID_HERE",
ClientSecret = "PUT_CLIENT_SECRET_HERE"
},
Scopes = new[] { GmailService.Scope.GmailReadonly },
DataStore = new FileDataStore(this.GetType().ToString()
});
redirect_uri_mismatch
为了使用 api 您的客户端必须正确设置。在 google 开发人员控制台中,您只需在客户端的设置中添加正确的重定向 uri 即可。它必须完全匹配 http://127.0.0.1:52158/authorize/
确保 visual studio 不会在您身上创建随机端口号。
我正在尝试使用 gmail 服务来读取收件箱数据并在我的聊天机器人中显示它们。我想使用我的 gmail 帐户进行身份验证。当我在机器人模拟器中测试聊天机器人工作正常时,当我在网络上部署时问题就开始了。我无法在网络上进行身份验证。
string jsonPath2 = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath + "client_secret_webapp.json";
UserCredential credential;
string[] Scopes = { GmailService.Scope.GmailReadonly };
string credPath = System.Environment.GetFolderPath(
System.Environment.SpecialFolder.Personal);
using (var stream = new FileStream(jsonPath2, FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
// This OAuth 2.0 access scope allows for read-only access to the authenticated
// user's account, but not other types of account access.
new[] { GmailService.Scope.GmailReadonly,},
"xxxx@gmail.com",
CancellationToken.None,
new FileDataStore(this.GetType().ToString())
);
}
var gmailService = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = this.GetType().ToString()
});
log.Info("ApplicationName" + ApplicationName);
var emailListRequest = gmailService.Users.Messages.List("xxxxx@gmail.com");
emailListRequest.LabelIds = "INBOX";
emailListRequest.MaxResults = 1;
emailListRequest.Q = "is:unread";
emailListRequest.IncludeSpamTrash = false;
if (emailListResponse != null && emailListResponse.Messages != null)
{
//loop through each email and get what fields you want...
foreach (var email in emailListResponse.Messages)
{
var emailInfoRequest = gmailService.Users.Messages.Get("xxxxxx@gmail.com", email.Id);
var emailInfoResponse = emailInfoRequest.Execute();
if (emailInfoResponse != null)
{
String from = "";
String date = "";
String subject = "";
String body = "";
//loop through the headers to get from,date,subject, body
foreach (var mParts in emailInfoResponse.Payload.Headers)
{
if (mParts.Name == "Date")
{
date = mParts.Value;
}
else if (mParts.Name == "From")
{
from = mParts.Value;
}
else if (mParts.Name == "Subject")
{
subject = mParts.Value;
}
if (date != "" && from != "")
{
if (emailInfoResponse.Payload.Parts == null && emailInfoResponse.Payload.Body != null)
body = DecodeBase64String(emailInfoResponse.Payload.Body.Data);
else
body = GetNestedBodyParts(emailInfoResponse.Payload.Parts, "");
}
}
await context.PostAsync("Email list for: Date " + date + " ::::::::::: From: " + from + " :::::::::::: Subject " + subject + " : ::::::::::::: Body : " + body + " Email.id eshte " + email.Id);
}
}
}
}
static String DecodeBase64String(string s)
{
var ts = s.Replace("-", "+");
ts = ts.Replace("_", "/");
var bc = Convert.FromBase64String(ts);
var tts = Encoding.UTF8.GetString(bc);
return tts;
}
static String GetNestedBodyParts(IList<MessagePart> part, string curr)
{
string str = curr;
if (part == null)
{
return str;
}
else
{
foreach (var parts in part)
{
if (parts.Parts == null)
{
if (parts.Body != null && parts.Body.Data != null)
{
var ts = DecodeBase64String(parts.Body.Data);
str += ts;
}
}
else
{
return GetNestedBodyParts(parts.Parts, str);
}
}
return str;
}
}
private static byte[] FromBase64ForUrlString(string base64ForUrlInput)
{
int padChars = (base64ForUrlInput.Length % 4) == 0 ? 0 : (4 - (base64ForUrlInput.Length % 4));
StringBuilder result = new StringBuilder(base64ForUrlInput, base64ForUrlInput.Length + padChars);
result.Append(String.Empty.PadRight(padChars, '='));
result.Replace('-', '+');
result.Replace('_', '/');
return Convert.FromBase64String(result.ToString());
}
client_id.json
{"installed":{"client_id":"xxxxxxx- yyyyyy.apps.googleusercontent.com","project_id":"reademailbot","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"yyyyyyyyyyy","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
已编辑:
我尝试添加以下代码:
var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new
ClientSecrets
{
ClientId = "xx-
xxxxxxxxx.apps.googleusercontent.com",
ClientSecret = "xxxxxxxxxxxxxxxxxxxxx-lLO"
},
new[] {
GmailService.Scope.GmailReadonly,
GmailService.Scope.MailGoogleCom,
GmailService.Scope.GmailMetadata
},
"user",
CancellationToken.None,
new
FileDataStore("Drive.Auth.Store")).Result;
var gmailService = new Google.Apis.Gmail.v1.GmailService(new
BaseClientService.Initializer()
{
HttpClientInitializer = credential,
});
但是当我在网络上尝试时我仍然有问题:
Error: redirect_uri_mismatch
The redirect URI in the request, http://127.0.0.1:52158/authorize/, does not match the ones authorized for the OAuth client. To update the authorized redirect URIs, visit: https://console.developers.google.com/apis/credentials/oauthclient/673194113721-45u2pgl6m2l74ecf13c51fmmihrsu3jh.apps.googleusercontent.com?project=673194113721
编辑 2:
string[] Scopes = { GmailService.Scope.GmailReadonly };
string ApplicationName = "IkanbiBot";
var secrets = new ClientSecrets
{
ClientId = ConfigurationSettings.AppSettings["GMailClientId"],
ClientSecret = ConfigurationSettings.AppSettings["GMailClientSecret"]
};
var token = new Google.Apis.Auth.OAuth2.Responses.TokenResponse { RefreshToken = ConfigurationSettings.AppSettings["GmailRefreshToken"] };
var credential = new UserCredential(new GoogleAuthorizationCodeFlow(
new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = secrets
}), "xxxx@gmail.com", token);
var gmailService = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = this.GetType().ToString()
});
log4net.ILog log2 = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
await context.PostAsync("Aplication name is ..." + ApplicationName);
await context.PostAsync("secret name is ..." + secrets.ClientId + "_____ and .... " + secrets.ClientSecret + " ++++ token is " + token.RefreshToken);
var emailListRequest = gmailService.Users.Messages.List("xxxxx@gmail.com");
emailListRequest.LabelIds = "INBOX";
emailListRequest.MaxResults = 1;
emailListRequest.Q = "is:unread";
emailListRequest.IncludeSpamTrash = false;
// Get our emails
// Get our emails
var emailListResponse = emailListRequest.Execute();
//get our emails
log2.Info(emailListResponse.Messages);
await context.PostAsync("emailListResponse is ..." + emailListResponse.Messages.Count);
if (emailListResponse != null && emailListResponse.Messages != null)
{
//loop through each email and get what fields you want...
foreach (var email in emailListResponse.Messages)
{
var emailInfoRequest = gmailService.Users.Messages.Get("botikanbi@gmail.com", email.Id);
var emailInfoResponse = emailInfoRequest.Execute();
if (emailInfoResponse != null)
{
String from = "";
String date = "";
String subject = "";
String body = "";
//loop through the headers to get from,date,subject, body
foreach (var mParts in emailInfoResponse.Payload.Headers)
{
if (mParts.Name == "Date")
{
date = mParts.Value;
}
else if (mParts.Name == "From")
{
from = mParts.Value;
}
else if (mParts.Name == "Subject")
{
subject = mParts.Value;
}
if (date != "" && from != "")
{
if (emailInfoResponse.Payload.Parts == null && emailInfoResponse.Payload.Body != null)
body = DecodeBase64String(emailInfoResponse.Payload.Body.Data);
else
body = GetNestedBodyParts(emailInfoResponse.Payload.Parts, "");
}
}
await context.PostAsync("Email list for: Date " + date + " ::::::::::: From: " + from + " :::::::::::: Subject " + subject + " : ::::::::::::: Body : " + body + " Email.id eshte " + email.Id);
}
}
}
}
static String DecodeBase64String(string s)
{
var ts = s.Replace("-", "+");
ts = ts.Replace("_", "/");
var bc = Convert.FromBase64String(ts);
var tts = Encoding.UTF8.GetString(bc);
return tts;
}
static String GetNestedBodyParts(IList<MessagePart> part, string curr)
{
string str = curr;
if (part == null)
{
return str;
}
else
{
foreach (var parts in part)
{
if (parts.Parts == null)
{
if (parts.Body != null && parts.Body.Data != null)
{
var ts = DecodeBase64String(parts.Body.Data);
str += ts;
}
}
else
{
return GetNestedBodyParts(parts.Parts, str);
}
}
return str;
}
}
private static byte[] FromBase64ForUrlString(string base64ForUrlInput)
{
int padChars = (base64ForUrlInput.Length % 4) == 0 ? 0 : (4 - (base64ForUrlInput.Length % 4));
StringBuilder result = new StringBuilder(base64ForUrlInput, base64ForUrlInput.Length + padChars);
result.Append(String.Empty.PadRight(padChars, '='));
result.Replace('-', '+');
result.Replace('_', '/');
return Convert.FromBase64String(result.ToString());
}
}
}
现在我正在使用这段代码。我从机器人那里得到答案直到: "secret name is ..." + secrets.ClientId + “_____ 和 ....” + secrets.ClientSecret + “++++ 令牌是” + token.RefreshToken 但是当尝试阅读电子邮件时停止 :(
你能帮我看看这是怎么回事吗?
有几种方法可以验证 google。
- 移动
- 网络
- 服务帐号
- 本机应用程序。
您为上述每种身份验证类型创建的客户端是不同的。使用它们的代码也不同。
GoogleWebAuthorizationBroker.AuthorizeAsync
用于验证已安装的应用程序。它不适用于 Web 应用程序。
对于 Web 应用程序,您应该遵循 Web applications (ASP.NET MVC) 并使用 GoogleAuthorizationCodeFlow
private static readonly IAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = "PUT_CLIENT_ID_HERE",
ClientSecret = "PUT_CLIENT_SECRET_HERE"
},
Scopes = new[] { GmailService.Scope.GmailReadonly },
DataStore = new FileDataStore(this.GetType().ToString()
});
redirect_uri_mismatch
为了使用 api 您的客户端必须正确设置。在 google 开发人员控制台中,您只需在客户端的设置中添加正确的重定向 uri 即可。它必须完全匹配 http://127.0.0.1:52158/authorize/
确保 visual studio 不会在您身上创建随机端口号。