I'm building a Web Api and I need to get data from a Google Analytics report.
I need to get data from a Google Analytics view.
But I think I'm facing an issue with the credentials.
Here is the code I'm using.
var filepath = "XXXXXXXXXXXXXXXXx";
var viewid = "XXXXXXXXXX";
GoogleCredential credentials;
using (var stream = new FileStream(filepath, FileMode.Open, FileAccess.Read))
{
string[] scopes = { AnalyticsReportingService.Scope.AnalyticsReadonly };
var googleCredential = GoogleCredential.FromStream(stream);
credentials = googleCredential.CreateScoped(scopes);
}
var reportingService = new AnalyticsReportingService(
new BaseClientService.Initializer
{
HttpClientInitializer = credentials
});
var dateRange = new DateRange
{
StartDate = "2018-06-01",
EndDate = "2018-06-25"
};
var sessions = new Metric
{
Expression = "ga:pageviews",
Alias = "Sessions"
};
var date = new Dimension { Name = "ga:date" };
var reportRequest = new ReportRequest
{
DateRanges = new List<DateRange> { dateRange },
Dimensions = new List<Dimension> { date },
Metrics = new List<Metric> { sessions },
ViewId = viewid
};
var getReportsRequest = new GetReportsRequest
{
ReportRequests = new List<ReportRequest> { reportRequest }
};
var batchRequest = reportingService.Reports.BatchGet(getReportsRequest);
var response = batchRequest.Execute();
foreach (var x in response.Reports.First().Data.Rows)
{
Console.WriteLine(string.Join(", ", x.Dimensions) + " " + string.Join(", ", x.Metrics.First().Values));
}
I'm getting the following issue:
Google.GoogleApiException: 'Google.Apis.Requests.RequestError
User does not have any Google Analytics account. [403]
Errors [
Message[User does not have any Google Analytics account.] Location[ - ]
Reason[forbidden] Domain[global]
Thanks,
Andrés
Make sure the credentials´ user has access to the Google Analytics account you are trying to access.
You must grant it access in the analytics page, just as you would for any other user.
Related
How to stop my livestream in YouTube while completed my live telecast using c#
How to stop the livestream Using c# Code, can you please give some suggestion
string[] scopes = { "https://www.googleapis.com/auth/youtube", "https://www.googleapis.com/auth/youtube.upload" };
var creadentails = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = YTPublishSettings.PublisherClientId,
ClientSecret = YTPublishSettings.PublisherClientSecret,
},
scopes, "user", default).Result;
if (creadentails.Token.IsExpired(SystemClock.Default))
creadentails.RefreshTokenAsync(CancellationToken.None).Wait();
var secrets = new ClientSecrets
{
ClientId = YTPublishSettings.PublisherClientId,
ClientSecret = YTPublishSettings.PublisherClientSecret,
};
var token = new TokenResponse { RefreshToken = creadentails.Token.RefreshToken };
var credentials = new UserCredential(new GoogleAuthorizationCodeFlow(
new GoogleAuthorizationCodeFlow.Initializer { ClientSecrets = secrets }),
"user", token);
var service = new YouTubeService(new BaseClientService.Initializer
{
HttpClientInitializer = credentials,
ApplicationName = "**************",
});
var broadcast = new LiveStream
{
Cdn = new CdnSettings
{
FrameRate = "35fps",
IngestionType = "rtmp",
Resolution = "720p"
},
Snippet = new LiveStreamSnippet
{
Description = Description,
Title = Title,
},
};
var request = service.LiveStreams.Delete(YTPublishSettings.PublisherId);
var response = request.Execute();
return new YouTubeStreamDeleteStatus()
{
success = "Deleted",
};
How can end My YouTube live stream API in c#?
I have create a c# custom application to create chat using one-on-one chat using user principal name. I want to show the response header into the Textbox when the user click the create button. I have follow the article below Get Response Header data from Post Call to get the response but currently I'm having some errors.
Coding part of Create Chat
private async void button2_Click(object sender, EventArgs e)
{
var scopes = new[] { "Directory.Read.All", "Directory.ReadWrite.All", "User.Read", "User.Read.All", "User.ReadBasic.All", "User.ReadWrite" };
{
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "5exxxx3-376a-43b1-9xxx0c-ef3xxxf8bx0";
// Value from app registration
var clientId = "35xxx-5c92-4xxx9-8500-635xxxe8af";
// using Azure.Identity;
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
var userName = "ng.xxxxxi.com";
var password = "Aaxxxxxx";
// https://learn.microsoft.com/dotnet/api/azure.identity.usernamepasswordcredential
var userNamePasswordCredential = new UsernamePasswordCredential(
userName, password, tenantId, clientId, options);
GraphServiceClient graphClient = new GraphServiceClient(userNamePasswordCredential, scopes);
var chat = new Chat
{
ChatType = ChatType.OneOnOne,
Members = new ChatMembersCollectionPage()
{
new AadUserConversationMember
{
Roles = new List<String>()
{
"owner"
},
AdditionalData = new Dictionary<string, object>()
{
{"user#odata.bind", "https://graph.microsoft.com/v1.0/users[comboBox2.Text]"}
}
},
new AadUserConversationMember
{
Roles = new List<String>()
{
"owner"
},
AdditionalData = new Dictionary<string, object>()
{
{"user#odata.bind", "https://graph.microsoft.com/v1.0/users/[comboBox3.Text]"}
}
}
}
};
var requestUrl = graphClient.Chats.Request().RequestUrl;
var content = "json_content";
var hrm = new HttpRequestMessage(HttpMethod.Post, requestUrl);
hrm.Content = new StringContent(content, System.Text.Encoding.UTF8, "aplication/json");
// Authenticate (add access token)
await graphClient.AuthenticationProvider.AuthenticateRequestAsync(hrm);
// Send the request and get the response.
var response = await graphClient.HttpProvider.SendAsync(hrm);
if (!response.IsSuccessStatusCode)
{
throw new ServiceException(
new Error
{
Code = response.StatusCode.ToString(),
Message = await response.Content.ReadAsStringAsync()
});
}
else
{
// read header values
var headerValues = response.Headers.GetValues(textBox2.Text);
}
await graphClient.Chats
.Request()
.AddAsync(chat);
}
}
I am creating a service to service application with Google API's and I'm having issues authenticating.
Perhaps it's my lack of understanding of the RS256 protocol as I have looked through the questions on here and not understanding what I'm doing wrong. The following code has been used in the past using HmacSha256, but when I try to do the same with RSA, I get exception errors.
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
public static string Generate(string user, string privatekey)
{
{
DateTime Expiry = DateTime.Today.AddMinutes(45);
int expiryTimeStamp = (int)(Expiry - new DateTime(1970, 1, 1)).TotalSeconds;
int iat = (int)(DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds;
var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(privatekey));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.RsaSha256Signature);
var header = new JwtHeader(credentials);
var payload = new JwtPayload
{
{ "iss", user }, //Service user unique email
{ "scope", "https://www.googleapis.com/auth/admin.reports.usage.readonly" }, //Scope of data
{ "aud", "https://oauth2.googleapis.com/token" },
{ "exp", expiryTimeStamp },
{ "iat", iat },
};
var secToken = new JwtSecurityToken(header, payload);
var handler = new JwtSecurityTokenHandler();
var tokenString = handler.WriteToken(secToken);
return tokenString;
}
}
}
Any help getting this working would be really appreciated!
Thanks!
I'm trying to create a web app (hosted on Azure) for clients to be able to submit work items to our team services page. Basically a support ticket page so they don't have to call to explain their backlog all the time.
Below is the class and method i've made to create work items, following Microsoft's sample code, with some obvious changes for privacy reasons. This method is triggered by a button click, and so far I cannot get it to create any work items.
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using Newtonsoft.Json;
namespace customapp
{
public class CreateWorkItem
{
public void CreateWorkItemMethod()
{
string personalAccessToken = "xxxxxxxxx";
string credentials = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "xxx", personalAccessToken)));
Object[] patchDocument = new Object[1];
patchDocument[0] = new { op = "add", path = "/fields/System.Title", value = "Test" };
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
var patchValue = new StringContent(JsonConvert.SerializeObject(patchDocument), Encoding.UTF8, "application/json-patch+json");
var method = new HttpMethod("PATCH");
var request = new HttpRequestMessage(method, "https://example.visualstudio.com/exampleproject/_apis/wit/workitems/$Support&20Ticket?api-version=1.0") { Content = patchValue };
var response = client.SendAsync(request).Result;
if (response.IsSuccessStatusCode)
{
var result = response.Content.ReadAsStringAsync().Result;
}
}}}}
In the url for the PATCH I am using the team project's ID (in place of /exampleproject you see below). Our site is set up to have an overall project, let's call it ""Master", and inside is a team project for each client, for example "ClientProject". So basically I want to create a "Support Ticket" work item in Master->ClientProject->Backlog/Board.
Using Master\\areapath instead (not Master\areapath).
Sample body:
[
{
"op": "add",
"path": "/fields/System.Title",
"value": "PBIAPI2"
},
{
"op": "add",
"path": "/fields/System.AreaPath",
"value": "Scrum2015\\SharedArea"
}
]
On the other hand, it’s better to create work item by using VSTS/TFS API with Microsoft Team Foundation Server Extended Client package.
Simple sample code:
var u = new Uri("https://[account].visualstudio.com");
VssCredentials c = new VssCredentials(new Microsoft.VisualStudio.Services.Common.VssBasicCredential(string.Empty, "[personal access token]"));
var connection = new VssConnection(u, c);
var workitemClient = connection.GetClient<WorkItemTrackingHttpClient>();
var workitemtype = "Product Backlog Item";
string teamProjectName = "Scrum2015";
var document = new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchDocument();
document.Add(
new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
{
Path = "/fields/Microsoft.VSTS.Common.Discipline",
Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
Value = "development"
});
document.Add(
new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
{
Path = "/fields/System.Title",
Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
Value = string.Format("{0} {1}", "RESTAPI", 6)
});
document.Add(new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
{
Path = "/fields/System.AreaPath",
Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
Value =string.Format("{0}\\{1}",teamProjectName, "SharedArea")
});
document.Add(
new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
{
Path = "/fields/System.AssignedTo",
Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
Value = "[user account]"
});
document.Add(
new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
{
Path = "/fields/System.Description",
Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
Value = "destest"
});
var workitem= workitemClient.CreateWorkItemAsync(document, teamProjectName, workitemtype).Result;
The method must be POST and Uri correct for consume the Api tfs is :
https://dev.azure.com/{organization}/{proyect}/_apis/wit/workitems/${type}?api-version=5.0
Check in :
https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work%20items/create?view=azure-devops-rest-5.0
The next code function for me.
static void Main(string[] args)
{
CreateWorkItem();
}
public static void CreateWorkItem()
{
string _tokenAccess = "************"; //Click in security and get Token and give full access https://azure.microsoft.com/en-us/services/devops/
string type = "Bug";
string organization = "type your organization";
string proyect = "type your proyect";
string _UrlServiceCreate = $"https://dev.azure.com/{organization}/{proyect}/_apis/wit/workitems/${type}?api-version=5.0";
dynamic WorkItem = new List<dynamic>() {
new
{
op = "add",
path = "/fields/System.Title",
value = "Sample Bug test"
}
};
var WorkItemValue = new StringContent(JsonConvert.SerializeObject(WorkItem), Encoding.UTF8, "application/json-patch+json");
var JsonResultWorkItemCreated = HttpPost(_UrlServiceCreate, _tokenAccess, WorkItemValue);
}
public static string HttpPost(string urlService, string token, StringContent postValue)
{
try
{
string request = string.Empty;
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", token))));
using (HttpRequestMessage httpRequestMessage = new HttpRequestMessage(new HttpMethod("POST"), urlService) { Content = postValue })
{
var httpResponseMessage = httpClient.SendAsync(httpRequestMessage).Result;
if (httpResponseMessage.IsSuccessStatusCode)
request = httpResponseMessage.Content.ReadAsStringAsync().Result;
}
}
return request;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
Now I'm using C# MVC to implement an API, and the API data is from remote MongoDB. I found when I was testing my API, it had MongoDB connection timeout error appeared sometimes. Does anyone know how to solve this problem?
This is the connection code
var settings = new MongoClientSettings
{
Credentials = new[] { MongoCredential.CreateMongoCRCredential("database", "user", "pw") },
Server = new MongoServerAddress("XXX.XXX.XXX", XXXXX),
ConnectTimeout = TimeSpan.FromSeconds(1800),
MaxConnectionIdleTime = TimeSpan.FromSeconds(1800),
};
//Get a Reference to the Client Object
var mongoClient = new MongoClient(settings);
var mongoServer = mongoClient.GetServer();
var database = mongoServer.GetDatabase("MongoDB");
Now I changed my code as follow, but I still encounter the same problem
var settings = new MongoClientSettings
{
Credentials = new[] { MongoCredential.CreateMongoCRCredential("database", "user", "pw") },
Server = new MongoServerAddress("XXX.XXX.XXX.XXX", XXXXX),
ConnectTimeout = TimeSpan.FromSeconds(1800),
MaxConnectionIdleTime = TimeSpan.FromSeconds(1800)
};
var mongoClient = new MongoClient(settings);
var database = mongoClient.GetDatabase(ConfigurationManager.AppSettings["mongoDBdatabase"]);
return database;
and get the data by the following code:
var database = Mongo.TestConnectDB();
var collection = database.GetCollection<BsonDocument>("User");
var builder = Builders<BsonDocument>.Filter;
var filter = builder.Eq("_id", ObjectId.Parse(id));
var cursor = await collection.FindAsync(filter);
var friendList = new List<MongoModels.User.Circle.Friend>();
while (await cursor.MoveNextAsync())
{
var user = cursor.Current;
friendList=BsonSerializer.Deserialize<MongoModels.User>(user.First()).circle.friend;
}