C# - Change Streams in MongoDB with $match - c#

I'm trying to narrow down the Change streams in MongoDB to a specific document matching on the document's _id as I have many documents in one collection. Anyone know how to do this in C#? Here's the latest that I've tried to no avail:
{
var userID = "someIdHere";
var match = new BsonDocument
{
{
"$match",
new BsonDocument
{
{"_id", userID}
}
}
};
var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<Class>>().Match(match);
var options = new ChangeStreamOptions { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup };
var cursor = collection.Watch(pipeline, options).ToEnumerable();
foreach (var change in cursor)
{
Debug.WriteLine(change.FullDocument.ToJson());
Debug.WriteLine(change.ResumeToken + " " + change.OperationType);
}
}
If I change the cursor to what you see below, it works but it returns the world and returns the change stream when there's activity on any of the _id's present in the document. That's not what I'm going for.
var cursor = collection.Watch().ToEnumerable();

After searching near and far, I was able to piece together bits and pieces of information from other issues I found online and came up with the solution below. It works like a charm!
Not only was I able to filter Change Stream so that it only recognizes updates but I was able to narrow down the stream to a SPECIFIC document _id AND made it even more granular finding a specific change to a field called LastLogin for that _id. This is what I desired as the default Change stream returned any update that happened on the collection.
I hope this helps someone that come across the same issue I did. Cheers.
{
var db = client.GetDatabase(dbName);
var collectionDoc = db.GetCollection<BsonDocument>(collectionName);
var id = "someID";
//Get the whole document instead of just the changed portion
var options = new ChangeStreamOptions
{
FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
};
//The operationType of update, where the document id in collection is current one and the updated field
//is last login.
var filter = "{ $and: [ { operationType: 'update' }, " +
"{ 'fullDocument._id' : '" + id + "'}" +
"{ 'updateDescription.updatedFields.LastLogin': { $exists: true } } ] }";
var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<BsonDocument>>().Match(filter);
var changeStream = collectionDoc.Watch(pipeline, options).ToEnumerable().GetEnumerator();
try
{
while (changeStream.MoveNext())
{
var next = changeStream.Current;
Debug.WriteLine("PRINT-OUT:" + next.ToJson());
}
}
catch (Exception ex)
{
Debug.WriteLine("PRINT-OUT: " + ex);
}
finally
{
changeStream.Dispose();
}
}

Related

How to use Adaptive Cards on Teams Messaging Extension?

I'm developing a Teams Message Extension and I'm using ThumbnailCard to display my results, however I wanted to use a custom adaptive card. Is that possible?
var resultCardList = GetAttachments(title);
var response = new ComposeExtensionResponse(new ComposeExtensionResult("list", "result"));
response.ComposeExtension.Attachments = resultCardList.ToList();
return response;
foreach (var contract in contractItems)
{
var lastModified = (DateTime)contract["Modified"];
var justificativa = contract["JustificativaContrato"];
var card = new ThumbnailCard
{
Title = $"{contract.Client_Title} - {lastModified.ToShortDateString()} {lastModified.ToLongTimeString()}",
Text = $"Justificativa: {justificativa}",
Tap = new CardAction { Type = "openUrl", Value = $"{Tenant}{ContractList.DefaultEditFormUrl}?ID={contract.Id}" },
Images = new List<CardImage> { new CardImage("http://lorempixel.com/640/480?rand=" + DateTime.Now.Ticks.ToString()) }
};
cardList.Add(card
.ToAttachment()
.ToComposeExtensionAttachment());
}
return cardList;
I've tried to use the below method to generate the Adaptive Card and just add it to the list:
private static Microsoft.Bot.Connector.Attachment CreateAdaptiveCardAttachment()
{
// combine path for cross platform support
string[] paths = { ".", "Cards", "welcomeCard.json" };
string fullPath = Path.Combine(paths);
var adaptiveCard = System.IO.File.ReadAllText(#"Cards\welcomeCard.json");
return new Microsoft.Bot.Connector.Attachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject(adaptiveCard),
};
}
The messaging extension does not allow sending adaptive cards like that.
It requires using the "MessagingExtensionResult" of the framework and just the card sent in the response. The documentation is a bit lacking here.
When you get a call from the messaging extension its action is of type "composeExtension/query"
Create the general "result" list like this:
var invokeResponse = new MessagingExtensionResponse();
var results = new MessagingExtensionResult
{
AttachmentLayout = "list",
Type = "result",
Attachments = new List<MessagingExtensionAttachment>(),
};
For each result in the list you need to create a MessagingExtensionAttachment like this: (Note: Cards need to have a preview!)
results.Attachments.Add(new MessagingExtensionAttachment
{
ContentType = "application/vnd.microsoft.teams.card.adaptive",
Content = JsonConvert.DeserializeObject(cardData),
Preview = new Attachment
{
ContentType = "application/vnd.microsoft.card.thumbnail",
Content = new AttachmentContent
{
text = "Project: " + task.ProjectName,
title = task.Name,
},
}
});
Finally send the result as "InvokeResponse"
return new InvokeResponse
{
Body = invokeResponse,
Status = 200,
};
While "content" of the attachment is the full adaptive card.
You can find an example for the response in json here:
https://learn.microsoft.com/de-de/microsoftteams/platform/concepts/messaging-extensions/search-extensions#response-example
You can freely mix card types based on that, but i never got that working tho...as of now you need to limit to one specific card type as far as i know.
All above is if you're using
Microsoft.Bot.Builder.Teams
Microsoft.Bot.Connector.Teams
Microsoft.Bot.Schema.Teams
in the latest versions.

Doing a Move and an edit in one Commit with Git TFS API in C#?

I am trying to edit one of our files and also move it to another place in our repo and so far have this setup:
GitRepository repo = new GitRepository();
repo.Id = new Guid(RepositoryId);
repo.Url = "Working.url.goes.here.com";
repo.DefaultBranch = "heads/master";
GitRef defaultBranch = GitClient.GetRefsAsync(repo.Id, filter: repo.DefaultBranch).Result.First();
string result = testpath.Replace(ACTUALFILEPATH, "");
GitCommitRef newCommit;
List<GitChange> changes;
GitRefUpdate newBranch = new GitRefUpdate()
{
Name = currBranch,
OldObjectId = defaultBranch.ObjectId,
};
changes = new List<GitChange>(3);
//the changes for the test being edited
changes.Add(new GitChange()
{
ChangeType = VersionControlChangeType.Add,
Item = new GitItem() { Path = result },
NewContent = new ItemContent()
{
Content = TestContent,
ContentType = ItemContentType.RawText
},
});
//the changes for the csproj file
changes.Add(new GitChange()
{
ChangeType = VersionControlChangeType.Edit,
Item = new GitItem() { Path = projPath },
NewContent = new ItemContent()
{
Content = projContent,
ContentType = ItemContentType.RawText
},
});
//The deletion of the old file
changes.Add(new GitChange()
{
ChangeType = VersionControlChangeType.Delete,
Item = new GitItem() { Path = origpath },
});
newCommit = new GitCommitRef()
{
Comment = commitmessage,
Changes = changes.ToArray()
};
GitPush push = GitClient.CreatePushAsync(new GitPush()
{
RefUpdates = new GitRefUpdate[] { newBranch },
Commits = new GitCommitRef[] { newCommit },
Repository = repo
}, repo.Id).Result;
return result;
Everytime I try to run it, either the delete causes an error that says you cant modify the same file twice in one commit, or if I move the delete to before it says the file doesnt exist in the directory of the branch.
What I need: To be able to move a test from one directory to another, edit its contents, and also edit the contents of another file, and push all that to the server.
Other Notes: Use of Powershell and Cmd are very limited.
Any Thoughts or suggestions or know what is wrong? Thanks so much for helping!
Well, after testing for several more hours, I finally figured it out..
I was using the wrong argument for origpath, and was passing it the same path as the new file that I was adding.
TLDR: Double check your arguments when writing a function

How to I read the number of LIVE users from Google Analytics in my .NET MVC application?

I have a ASP.NET MVC web application. I want to show the number of LIVE users from a website.
How can I read this from Google Analytics?
I have already followed this guide:
http://www.markwemekamp.com/blog/c/how-to-read-from-google-analytics-using-c/
But I can't get the code to work. It keeps on running and gives a System.NullReferenceException.
So I hope there are people with better idea's or guides here. And please, only complete guides with every detail in it. Not those half guide where you don't know what to do.
Thanks in Advance.
Update:
This is the code from the guide that I am using. I only added the date's. I am using the code in de Global.asax.cs file.
The Null exception occures on this piece of code:
foreach (var x in response.Reports.First().Data.Rows)
{
Debug.WriteLine("The next line doesn't appear: seee.....");
Debug.WriteLine(string.Join(", ", x.Dimensions) + " " + string.Join(", ", x.Metrics.First().Values));
}
Code:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
UnityConfig.RegisterComponents();
RouteConfig.RegisterRoutes(RouteTable.Routes);
Database.SetInitializer<EFDbContext>(null);
MethodSomethingGoogle();
}
public void MethodSomethingGoogle()
{
string todaysDate = DateTime.Now.ToString("yyyy-MM-dd");
string tomorrowsDate = DateTime.Now.AddDays(1).ToString("yyyy-MM-dd");
try
{
var filepath = #"C:\Users\ckersten\Downloads\Dashboard-Match-Online-b2f3f0b438a1.json";
var filepath2 = #"~\App_Data\Dashboard-Match-Online-b2f3f0b438a1.json";
// path to the json file for the Service account
var viewid = "109154097"; // id of the view you want to read from
Googl
eCredential 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 = todaysDate,
EndDate = tomorrowsDate
};
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)
{
Debug.WriteLine("The next line doesn't appear: seee.....");
Debug.WriteLine(string.Join(", ", x.Dimensions) + " " + string.Join(", ", x.Metrics.First().Values));
}
}
catch (Exception e)
{
Debug.WriteLine("Google Exception: " + e.ToString());
}
Debug.WriteLine(Console.ReadLine());
}
Your code uses the reporting api which isnt going to give you real time data. Data in the reporting api wont be done processing for 24 -48 hours .
You should be using the realtime api if you want to see whats going on now. Just remember that you can only make 10000 requests against the api a day per view.
DataResource.RealtimeResource.GetRequest request =
service.Data.Realtime.Get(String.Format("ga:{0}", profileId), "rt:activeUsers");
RealtimeData feed = request.Execute();
foreach (List row in realTimeData.Rows)
{
foreach (string col in row)
{
Console.Write(col + " "); // writes the value of the column
}
Console.Write("\r\n");
}
My tutorial on the realtime api here GitHub sample project can be found here you also might want to consider using a service account
Note:
The Real Time Reporting API, in limited beta, is available for developer preview only. Sign up to access the API.

Channel data properties : Carousel?

I want to get media from a website. That media should be listed something like Carousel card template.
With loop i want to store all the media in one object.
Have this :
resultMessage.AttachmentLayout = AttachmentLayoutTypes.Carousel;
resultMessage.Attachments = new List<Attachment>();
var fbObject = new object[activities.Count];
while (!stop)
{
if (activities[counter].MediaTypeValue != (int)MediaTypeEnum.Video)
{
fbObject[counter] = new
{
type = "image",
payload = new object[]
{
new
{
url = activities[counter].DocumentPath
},
}
};
}
else
{
fbObject[counter] = new
{
type = "video",
buttons = new object[]
{
new
{
type = "web_url",
url = activities[counter].DocumentPath,
title = activities[counter].FirstName + " " + activities[counter].LastName + " posted " + BotHelper.UserPosted(activities[counter].MediaTypeValue),
webview_height_ratio = "compact",
messenger_extensions = true
}
}
};
}
counter--;
if (counter < 0)
stop = true;
}
resultMessage.ChannelData = JObject.FromObject(new { fbObject }); ;
await context.PostAsync(resultMessage);
But Facebook messenger does not render it as "carousel".
Any idea how to show object like Carousel type of card ?
Facebook will render the carousel if you have Attachments in your message. Your attachments collection is empty and you are sending channel data info, which won't be rendered as a carousel.
Both Image and Video are supported attachments in BotFramework and you can just use the available rich cards instead of using channel data to send them to the user.
Take a look to the RichCards sample to understand how to create each of the supported cards. Also, you might also want to review the Carousel sample.
Finally, it's always a good idea to review the documentation around attachments and Rich cards. See this and this.

Export payment in Applications Tab menu of Bill and Adjustments in Acumatica ERP system using webservices api

I need to export all records in Applications Tab Menu of Bill and Adjustments screen as I did in UI like this screenshot below.
I already create codes to provide it using this code below.
try
{
context.CookieContainer = new System.Net.CookieContainer();
context.Timeout = 10000000;
context.Url = url;
LoginResult login = context.Login(username, password);
AP301000Content konten = context.AP301000GetSchema();
//context.AP301000Clear();
konten.DocumentSummary.Type.Commit = false;
konten.DocumentSummary.Type.LinkedCommand = null;
var command = new Command[]
{
new Value { Value = "Bill", LinkedCommand = Konten.DocumentSummary.Type },
new Value { Value = "00123", LinkedCommand = konten.DocumentSummary.ReferenceNbr },
konten.DocumentSummary.Vendor,
konten.Applications.ReferenceNbrDisplayRefNbr,
konten.Applications.DocTypeDisplayDocType
};
var result = context.AP301000Export(command, null, 0, false, true);
}
catch (Exception x)
{
MessageBox.Show(x.Message);
}
finally
{
sCon.getLogout(context);
}
After i debug this code I got records only for VendorCD but Reference Nbr and Doc Type didn't exported. Please refer to this screenshot below.
please how to solve this issue.
Thanks
You should use "every" fields:
var command = new Command[]
{
konten.DocumentSummary.ServiceCommands.EveryDocType,
konten.DocumentSummary.ServiceCommands.EveryRefNbr,
konten.DocumentSummary.Vendor,
konten.Applications.ReferenceNbrDisplayRefNbr,
konten.Applications.DocTypeDisplayDocType
};

Categories

Resources