How to detect changes in google calendar - google-calendar-api

When Google Calendar has been modified, do you receive any signal from the calendar?
if so, What is the method? please help me :)
public IList<Event> CalendarLoad(string username="", string userid="", string userpassword="")
{
scopes.Add(CalendarService.Scope.Calendar);
UserCredential credential;
using (FileStream stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets, scopes, username, CancellationToken.None,
new FileDataStore("Calendar.VB.Sample")).Result;
}

Rather than polling Calendar regularly you can use push notifications to receive updates when Calendars change.

Related

Credentials in GoogleCalendar API with service account (Java)

Right now I need to implement an app to create some google-calendar events but for a service account. I saw examples in docs that create events using AuthorizationCodeInstalledApp (or similar) to create a Credential instance (com.google.api.client.auth.oauth2.Credential) but it works for regular user accounts and not for Service account (I already have the JSON file with key info from my ServiceAccount).
Next lines show what's the ideal for me (of course is not working because Calendar.Builder needs some Credential obj as a third param)
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
GoogleCredentials credential = GoogleCredentials.fromStream(new FileInputStream(jsonPath))
.createScoped(Collections.singleton(CalendarScopes.CALENDAR));
Calendar calendar = new Calendar.Builder(HTTP_TRANSPORT, jsonFactory, credential)
.setApplicationName(APPLICATION_NAME)
.build();
How I can get a Credential obj using/from a .JSON key file (service account) to use with Calendar.Builder? or maybe I'm missing something else and/or there is another way to do this?
Thanks!
This sample should get you started make sure to set the UserEmail to the email address of the user on your Workspace domain that you want to delegate to.
One of these should work.
version 1:
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
GoogleCredential credential = GoogleCredential
.fromStream(new FileInputStream(KEY_FILE_LOCATION))
.setServiceAccountUser(userEmail)
.createScoped(CalendarScopes.all());
Version 2:
private GoogleCredential authorize1() {
GoogleCredential credential = null;
HttpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
try {
InputStream jsonFileStream =
DriveSample.class.getClassLoader().getResourceAsStream("client_secrets.json");
GoogleCredential readJsonFile = GoogleCredential
.fromStream(jsonFileStream, httpTransport, JSON_FACTORY).createScoped(DriveScopes.all());
credential = new GoogleCredential.Builder().setTransport(readJsonFile.getTransport())
.setJsonFactory(readJsonFile.getJsonFactory())
.setServiceAccountId(readJsonFile.getServiceAccountId())
.setServiceAccountUser(userEmail)
.setServiceAccountScopes(readJsonFile.getServiceAccountScopes())
.setServiceAccountPrivateKey(readJsonFile.getServiceAccountPrivateKey()).build();
} catch (IOException exception) {
exception.printStackTrace();
}
return credential;
}
here is a link on how to set up delegation. Just make sure to swap out the scope for the google calendar scope.
Perform Google Workspace Domain-Wide Delegation of Authority

Can I use bot framework to send/update message as a user in MS Teams?

Is it possible to use bot framework to send / update message as a user rather than the bot as the sender of message (perhaps after some form of authentication with the user that allows the bot to perform such operations)?
Below is an illustration of the current situation:
I have sent a message by person A into Teams channel, and I would like to do an update to the message using bot framework as Graph API does not support update of message. However, the message does not get updated although there was no error.
This is placed in a web api controller "/test". Hence the update will be trigger by sending a POST to /test.
ServiceClientCredentials service = new CustomLoginCredentials();
var connectorClient = new ConnectorClient(new Uri("https://smba.trafficmanager.net/apac/"), service);
var newActivity = MessageFactory.Text($"hello: updated on {DateTime.Now}");
string destActivityId = "this is the activity id of the existing message sent using person A account on MS Teams";
string conversationId = $"channelidhere;messageid={destActivityId}";
connectorClient.Conversations.UpdateActivityAsync(conversationId, destActivityId, newActivity, default(CancellationToken));
CustomLoginCredentials
public class CustomLoginCredentials:ServiceClientCredentials
{
private string AuthenticationToken { get; set; }
public override void InitializeServiceClient<T>(ServiceClient<T> client)
{
System.Diagnostics.Debug.WriteLine("CustomLoginCredentials:InitializeServiceClient 1");
IPublicClientApplication publicClient = PublicClientApplicationBuilder.Create("clientid")
.WithAuthority(AzureCloudInstance.AzurePublic, "tenantId")
.Build();
AuthenticationResult authenticationResult = publicClient.AcquireTokenByUsernamePassword(new string[] { "https://graph.microsoft.com/.default" }, "personA MS email", new NetworkCredential("", "personA MS email password").SecurePassword).ExecuteAsync().GetAwaiter().GetResult();
AuthenticationToken = authenticationResult.AccessToken;
}
public override async Task ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request == null) throw new ArgumentNullException("request");
if (AuthenticationToken == null) throw new InvalidOperationException("Token Provider Cannot Be Null");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AuthenticationToken);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
await base.ProcessHttpRequestAsync(request, cancellationToken);
}
}
Where a bot sends messages on behalf of a user, attributing the message to that user helps with engagement and showcase a more natural interaction flow. This feature allows you to attribute a message from your bot to a user on whose behalf it was sent. You can use on-behalf-attribute to send message as a user - please check User attribution for bots messages

Xamarin.Forms SecureStorage Plugin doesn't work

I'm new with Xamarin.Forms, and I'm finding a way to store data in App like: token, username. Now, I'm trying to use SecureStorgae, but the function getValue doesn't work, and I have no idea why.
My code:
public async Task CheckLogin(string usernameString, string passwordString)
{
using (var client = new HttpClient())
{
string url = "myUrl";
var json = JsonConvert.SerializeObject(new { username = usernameString, password=passwordString });
HttpContent content = new StringContent(json,Encoding.UTF8, "application/json");
var response = await client.PostAsync(url,content);
if (response.IsSuccessStatusCode)
{
var rs = JsonConvert.DeserializeObject<LoginResult>(response.Content.ReadAsStringAsync().Result);
var token = rs.result.token;
CrossSecureStorage.Current.SetValue("SessionToken",token);
CrossSecureStorage.Current.SetValue("Username", rs.result.userName);
var token1 = CrossSecureStorage.Current.GetValue("SessionToken");
await Navigation.PushAsync(new Home());
}
}
}
When my app is running, I can't get the value of SessionToken.
in iOS
Open the Entitlements.plist file and make sure that "Enable Keychain Access Groups" is checked. Also ensure that in Project->Options->iOS Bundle Signing, the Entitlements.plist is selected in Custom Entitlements for iPhoneSimulator platform.
in Android
It is required that the password is set by the application prior to use.
SecureStorageImplementation.StoragePassword = "Your Password";
For more detail you can access here

Where to store tokens in a xamarin.form application

I have the class below that will be used in a xamarin.forms mobile application
to retrieve the token generated by OAuth(webapi). Once this is generated I need to store
in a place where I can access it again and not generating this all the time.
Where is the best place to store this in the Pcl? I will also want to be able to remove this once
the user logs off.
class LoginService
{
public async Task Login(string username, string password)
{
HttpWebRequest request = new HttpWebRequest(new Uri(String.Format("{0}Token", Constants.BaseAddress)));
request.Method = "POST";
string postString = String.Format("username={0}&password={1}&grant_type=password",
HttpUtility.HtmlEncode(username), HttpUtility.HtmlEncode(password));
byte[] bytes = Encoding.UTF8.GetBytes(postString);
using (Stream requestStream = await request.GetRequestStreamAsync())
{
requestStream.Write(bytes, 0, bytes.Length);
}
try
{
HttpWebResponse httpResponse = (HttpWebResponse)(await request.GetResponseAsync());
string json;
using (Stream responseStream = httpResponse.GetResponseStream())
{
json = new StreamReader(responseStream).ReadToEnd();
}
TokenResponseModel tokenResponse = JsonConvert.DeserializeObject(json);
return tokenResponse.AccessToken;
}
catch (Exception ex)
{
throw new SecurityException("Bad credentials", ex);
}
}
}
Token(s) being sensitive information, I would recommend storing them in a secure manner. Secure storage is available through Keychain services in iOS, and the KeyStore class in Android. Xamarin has a very good article on how to do that using Xamarin.Auth.
Other options available are:
BlobCache.Secure in Akavache
SecureStorage
Secure storage in XLabs
Just an update for anyone searching, as things have changed since this post was created. It is not advised to use the following any more:
Application.Current.Properties
To securely store things like access tokens etc you can use the Xamarin.Essentials SecureStorage static class.
Just add the Xamarin.Essentials nuget package if you don't already have it and use it like so:
using Xamarin.Essentials;
.
.
.
await SecureStorage.SetAsync("someKey", "someValue");
var myValue = await SecureStorage.GetAsync("someKey");
you also have the option to
SecureStorage.Remove("someKey");
//or
SecureStorage.RemoveAll();
Refer this for more documentation
Forms has a built in Properties dictionary where you can store small bits of persistent data.
Application.Current.Properties ["token"] = myToken;

Issue with httpclient.getstringasync

I want to develop a Dragon Timer Windows Store App for GuildWars 2.
Whatever, I save a timestamp in a sql database. To get this timestamp in the app, I made a php script that writes the content of the database to a page. Now I'm trying to receive that string via the HttpClient.GetStringAsync() Method. Here's the code snipped:
async Task<Dictionary<String, DateTime>> GetKillTimes()
{
Dictionary<String, DateTime> killTimes = new Dictionary<String,DateTime>();
HttpClient httpClient = new HttpClient();
Task<string> getStringTask = httpClient.GetStringAsync("http://www.wp10454523.server-he.de/truhentimer/getTimes.php");
String rawKillTimes = await getStringTask;
//Parse to Dictionary...
return killTimes;
}
I tried some different Methods I got from google (WebRequest ...), but every one got stuck at the Get-Part. Am I maybe misinterpreting the function? Shouldn't I get the content of the page, which is a simple String?
You have to use await keyword as web request & response in WinRT are asynchronous so you have to use await keyword. await before httpClient.GetStringAsync(...)
Task<string> getStringTask = await httpClient.GetStringAsync("http://www.wp10454523.server-he.de/truhentimer/getTimes.php");

Resources