Access multiple user's Google Fit data from server side periodically - c#

I am trying to access steps count of all users who are resisted in my website.
I have setup a cronjob every day at a fixed time. I have created a service account credintials and downloaded its json
public async Task<IActionResult> GoogleFit(string email)
{
var scopes = new[] { FitnessService.Scope.FitnessActivityRead };
var credentials = GoogleCredential.FromJson(System.IO.File.ReadAllText(jsonPath))
.CreateScoped(scopes);
var fitnessService = new FitnessService(new BaseClientService.Initializer()
{
HttpClientInitializer = credentials,
ApplicationName = "App name"
});
var dataSources = await fitnessService.Users.DataSources.List(email).ExecuteAsync();
var foundData = dataSources.DataSource.FirstOrDefault(x => x.Type == "raw")?.DataStreamId;
if (foundData == null)
{
return NotFound("No data source");
}
var start = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0, DateTimeKind.Utc);
var end = start.AddDays(1);
DateTime unixStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
long unixTimeStart = (long)(start - unixStart).TotalSeconds;
long unixTimeEnd = (long)(end - unixStart).TotalSeconds;
var result = await fitnessService.Users.Dataset.Aggregate(new AggregateRequest()
{
AggregateBy = new List<AggregateBy>
{
new AggregateBy
{
DataSourceId = foundData,
DataTypeName = "com.google.step_count.delta"
}
},
BucketByTime = new BucketByTime
{
DurationMillis = 86400000
},
StartTimeMillis = unixTimeStart,
EndTimeMillis = unixTimeEnd
}, email).ExecuteAsync();
return Ok(result);
}
This is the api i use to test, when i give a email i get the
The service fitness has thrown an exception.
HttpStatusCode is Forbidden.
Google.Apis.Requests.RequestError
The caller does not have permission [403]
Errors [
Message[The caller does not have permission] Location[ - ] Reason[forbidden] Domain[global]
]
Also if i pass "me" instead of email in var dataSources = await fitnessService.Users.DataSources.List(email).ExecuteAsync();
i get no error but dataSources count is 0

Related

How to create event with videoconference in Google Meet in C# using Google Calendar API?

Well.. I'm trying this code to create an Event
CalendarService service;
GoogleCredential credential;
try
{
string[] scopes = new string[] { CalendarService.Scope.Calendar };
using (var stream = new FileStream(#"C:\Prueba\meet.json", FileMode.Open, FileAccess.Read))
{
credential = GoogleCredential.FromStream(stream)
.CreateScoped(scopes);
}
service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential
});
Event calendarEvent = new Event();
DateTime start = DateTime.Now;
calendarEvent.Kind = "";
calendarEvent.Summary = "prueba";
calendarEvent.Status = "confirmed";
calendarEvent.Visibility = "public";
calendarEvent.Description = "prueba";
calendarEvent.Creator = new Event.CreatorData
{
Email = "email#example.com", //email#example.com
Self = true
};
calendarEvent.Organizer = new Event.OrganizerData
{
Email = "email#example.com",
Self = true
};
calendarEvent.Start = new EventDateTime
{
DateTime = start,
TimeZone = "America/Mexico_City"
};
calendarEvent.End = new EventDateTime
{
DateTime = start.AddHours(1),
TimeZone = "America/Mexico_City"
};
calendarEvent.Recurrence = new String[] { "RRULE:FREQ=DAILY;COUNT=1" };
calendarEvent.Sequence = 0;
calendarEvent.HangoutLink = "";
calendarEvent.ConferenceData = new ConferenceData
{
CreateRequest = new CreateConferenceRequest
{
RequestId = "1234abcdef",
ConferenceSolutionKey = new ConferenceSolutionKey
{
Type = "hangoutsMeet"
},
Status = new ConferenceRequestStatus
{
StatusCode = "success"
}
},
EntryPoints = new List<EntryPoint>
{
new EntryPoint
{
EntryPointType = "video",
Uri = "",
Label = ""
}
},
ConferenceSolution = new ConferenceSolution
{
Key = new ConferenceSolutionKey
{
Type = "hangoutsMeet"
},
Name = "Google Meet",
IconUri = ""
},
ConferenceId = ""
};
//calendarEvent.EventType = "default";
EventsResource.InsertRequest request = service.Events.Insert(calendarEvent, "email#example.com");
request.ConferenceDataVersion = 0;
Event createEvent = request.Execute();
string url = createEvent.HangoutLink;
}
catch (Exception ex)
{
}
The source code is here
When I execute the line 116: Event createEvent = request.Execute();
I get this error: Google.Apis.Requests.RequestError Invalid conference type value. [400] Errors [Message[Invalid conference type value.] Location[ - ] Reason[invalid] Domain[global]
I don't know what means this error o with line I wrong
Could anyone help me with an example to create an event using classes C# from Google API Calendar?
As described in the C# library documentation for createRequest:
Either conferenceSolution and at least one entryPoint, or createRequest is required.
This means that you should use only CreateConferenceRequest as this conference is brand new (if it already existed then you would be wanting to use ConferenceSolution along with EntryPoints ). Therefore, simply remove ConferenceSolution and EntryPoints to leave just CreateConferenceRequest which as specified in the documentation is used for generating a new conference and attach it to the event.

Error in the opening of a new push notification channel

My application used to work just fine, but yesterday starts to give me an error when I try to open a push notification channel via Google Drive .NET SDK, the error is:
Failed to create channel [400]
Message[Failed to create channel]
Location[ - ]
Reason[invalidArgument]
Domain[global]
You can see my code here:
public async Task<Channel> StartWebHookWatch(TokenResponse token, string userId, string channelId, string pageToken, string urlCallBack)
{
var service = GetDriveService(token);
var expireDate = DateTime.UtcNow.AddSeconds(604800); // 1 Week
var channel = new Channel()
{
Id = channelId, // Just a Guid created with "Guid.NewGuid().ToString();"
Token = userId, // Just a Id to bind the channel With My appUser
Type = "web_hook",
Address = urlCallBack, // Authorized Url
Expiration = (long)expireDate.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalMilliseconds
};
return await service.Changes.Watch(channel, pageToken).ExecuteAsync();
}
private DriveService GetDriveService(TokenResponse token)
{
return new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = new UserCredential(
new GoogleAuthorizationCodeFlow(
new GoogleAuthorizationCodeFlow.Initializer() { ClientSecrets = ClientSecret }),
ClientSecret.ClientId, token),
ApplicationName = AppName
});
}
I just did a lot of tests and I don't find even a clue what is the problem...
I appreciate some help to solve this, Thank you, guys.

C# post JSON data to REST API

I am new to REST API JSON but have been able to consume a few API with asp.net. Here is the problem I am currently facing.
I have been able to send JSON data to an API using this method.
public void PostData()
{
string sName = sysName.Text;
string sDescrip = sysDescrip.Text;
var httpclient = new HttpClient();
httpclient.BaseAddress = new Uri("http://33.248.292.99:8094/bizzdesk/sysconfig/api/");
var sys = new Bizsys(){name= sName, description= sDescrip};
httpclient.PostAsJsonAsync("system", sys);
}
it work just fine.
Now I modify the code in order to accommodate more values thus:
var httpclient = new HttpClient();
// ArrayList paramList = new ArrayList();
httpclient.BaseAddress = new Uri("http://179.683.197.115:9091/tua-slte/api/organisations/");
var org = new Organisation() { id=1, name = "inno", abbreviation = "abx", type="school", sort = 7, isShow = true, createdBy=8, createdDate = "10/04/2017", editedBy = 11, editDate="11/04/2017"};
var bas = new Basic() { id=1, username = "inno", password = "123", firstName="Innocent", lastName="Ujata", email = "ea#bizz.co", mobile = "123456", photo="10201001", loginIp="127.0.0.1", loginDate="10/04/2017", locked=false, organisation = org, createdDate = "10/04/2017", editedBy = 11, editDate="11/04/2017", admin=true};
var org2 = new Organisation2() { id=1, name = "inno", abbreviation = "abx", type="school", sort = 7, isShow = true, createdBy=17, createdDate = "10/04/2017", editedBy = 09, editDate="11/04/2017"};
var hq = new HeadQuarter() { zonId=09, organisation = org2, zonCode = "123", zonName = "Abuja", zonAddress = "123456", zonCity = "Abuja", zonPostalCode = "120076", zonEmail = "answers", zonPhoneNumber = "0908765", zonFaxNumber = "1212", zonState = "FCT", createdBy=17, createdDate = "10/04/2017", editedBy = 11, editDate="11/04/2017", version=1};
var examp = new RootObject() {basic=bas, headQuarter=hq };
var status = httpclient.PostAsJsonAsync("register", examp);
return status;
It keep returning this:
Id = 19, Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}"
I hard coded the data to see it work first before making it dynamic.
I have tried using await async method too the result is the same.
all the questions and answers I have seen here are not similar.
What does that mean, and what am I getting wrong?
You are calling an async method, but not awaiting it's results.
Change:
var status = httpclient.PostAsJsonAsync("register", examp);
to
var status = await httpclient.PostAsJsonAsync("register", examp);
Extension method PostAsJsonAsync returns Task<HttpResponseMessage>. You grab this task and see it's details. If you want to return status code of completed request, you should await for task completion and then grab status code from response message:
private async Task<HttpStatusCode> PostSomethingAsync()
{
...
var response = await httpclient.PostAsJsonAsync("register", examp);
return response.StatusCode;
}
Or you can synchronously wait for request completion:
private HttpStatusCode PostSomething()
{
...
var response = httpclient.PostAsJsonAsync("register", examp).Result;
return response.StatusCode;
}
That's cause you are not awaiting the call like
var status = await httpclient.PostAsJsonAsync("register", examp);
Or, use ConfigureAwait()
var status = httpclient.PostAsJsonAsync("register", examp).ConfigureAwait(false);

Request had insufficient authentication scopes [403] when creating a cluster with Google Cloud Dataproc

In Google Cloud Platform the DataProc API is enabled. I am using the same key I use to access GCS and Big query to create a new cluster per this example. I get a Request had insufficient authentication scopes error on the following line.
Operation createOperation =
service.Projects.Regions.Clusters.Create(newCluster, project, dataprocGlobalRegion).Execute();
My complete code:
public static class DataProcClient
{
public static void Test()
{
string project = ConfigurationManager.AppSettings["Google.ProjectName"]; ;
string dataprocGlobalRegion = "global";
string zone = "us-east1-b";
string machineType = "n1-standard-4";
string clusterName = "sample-cluster";
int numWorkers = 2;
String serviceAccountEmail= ConfigurationManager.AppSettings["Google.ServiceAccountEmail"];
String certificateFile = ConfigurationManager.AppSettings["KeyDirectory"] + ConfigurationManager.AppSettings["Google.CertificateFile"];
X509Certificate2 certificate = new X509Certificate2(certificateFile, "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { StorageService.Scope.DevstorageFullControl }
}.FromCertificate(certificate));
DataprocService service = new DataprocService(
new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Dataproc Sample",
});
// Create a new cluster:
Cluster newCluster = new Cluster
{
ClusterName = clusterName,
Config = new ClusterConfig
{
GceClusterConfig = new GceClusterConfig
{
ZoneUri = String.Format(
"https://www.googleapis.com/compute/v1/projects/{0}/zones/{1}",
project, zone),
},
MasterConfig = new InstanceGroupConfig
{
NumInstances = 1,
MachineTypeUri = String.Format(
"https://www.googleapis.com/compute/v1/projects/{0}/zones/{1}/machineTypes/{2}",
project, zone, machineType),
},
WorkerConfig = new InstanceGroupConfig
{
NumInstances = numWorkers,
MachineTypeUri = String.Format(
"https://www.googleapis.com/compute/v1/projects/{0}/zones/{1}/machineTypes/{2}",
project, zone, machineType),
},
},
};
Operation createOperation =
service.Projects.Regions.Clusters.Create(newCluster, project, dataprocGlobalRegion).Execute();
// Poll the operation:
while (!IsDone(createOperation))
{
Console.WriteLine("Polling operation {0}", createOperation.Name);
createOperation =
service.Projects.Regions.Operations.Get(createOperation.Name).Execute();
Thread.Sleep(1000);
}
}
static bool IsDone(Operation op)
{
return op.Done ?? false;
}
}
When creating your ServiceAccountCredential, change:
new[] { StorageService.Scope.DevstorageFullControl }
to:
new[] { DataprocService.Scope.CloudPlatform }

Google Calendar API Authentication for MVC

I am getting the following error when attempting to Insert a new calendar to the user who is currently logged in. Users are able to log in and register but attempting to add a new calendar gives us this error.
Google.Apis.Requests.RequestError
Insufficient Permission [403]
Errors [
Message[Insufficient Permission] Location[ - ] Reason[insufficientPermissions] Domain[global]
]
The error occurs at the execute of the following code:
CalendarService googlecalender = new CalendarService(await (new GoogleAuthentication()).GetInitializer());
Calendar calendar = new Calendar();
calendar.Summary = "sampleCalendar";
calendar.Id = "_Sample";
calendar.Kind = "calendar#calendar";
var calendarRequest = googlecalender.Calendars.Insert(calendar);
var result = calendarRequest.Execute();
I have modified the google authentication to the following:
var authenInfo = new GoogleOAuth2AuthenticationOptions();
authenInfo.Scope.Add("openid");
authenInfo.Scope.Add("profile");
authenInfo.Scope.Add("email");
authenInfo.Scope.Add("https://www.googleapis.com/auth/plus.login");
authenInfo.Scope.Add("https://www.googleapis.com/auth/plus.me");
authenInfo.Scope.Add(YouTubeService.Scope.Youtube);
authenInfo.Scope.Add(CalendarService.Scope.Calendar);
authenInfo.Scope.Add(CalendarService.Scope.CalendarReadonly);
authenInfo.ClientId = "CLIENTID";
authenInfo.ClientSecret = "CLIENTSECRET";
authenInfo.Provider = new GoogleOAuth2AuthenticationProvider();
app.UseGoogleAuthentication(authenInfo);
and the GoogleAuthentication class is this:
public GoogleAuthentication()
{
ClientSecret = new ClientSecrets();
ClientSecret.ClientSecret = "CLIENTSECRET";
ClientSecret.ClientId = "CLIENTID";
Scope = new[] {
"https://www.googleapis.com/auth/plus.login",
YouTubeService.Scope.Youtube,
CalendarService.Scope.Calendar
};
}
private async void Authorize()
{
Credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
ClientSecret,
Scope,
"user",
CancellationToken.None
);
}
public async Task<BaseClientService.Initializer> GetInitializer()
{
if (Credential == null)
Authorize();
else if (Credential.Token.IsExpired(SystemClock.Default))
{
Boolean tokenRefreshed = await Credential.RefreshTokenAsync(CancellationToken.None);
}
return new BaseClientService.Initializer()
{
HttpClientInitializer = Credential,
ApplicationName = Properties.Settings.Default.ApplicationName
};
}

Categories

Resources