How to subscribe to updates in Telegram Api? - c#

My question is a copy of this question
However, I don't understand how to use the answer given there
The library I am using already implements what the answer says
TelegramClient.cs
var config = new TLRequestGetConfig();
var request = new TLRequestInitConnection()
{
ApiId = apiId,
AppVersion = "1.0.0",
DeviceModel = "PC",
LangCode = "en",
Query = config,
SystemVersion = "Win 10.0",
SystemLangCode = "en",
LangPack = ""
};
var invokewithLayer = new TLRequestInvokeWithLayer() { Layer = 108, Query = request };
await sender.Send(invokewithLayer, token).ConfigureAwait(false);
await sender.Receive(invokewithLayer, token).ConfigureAwait(false);
dcOptions = ((TLConfig)invokewithLayer.Response).DcOptions.ToList();
Where does Telegram send updates?
I thought the updates could be read in the TcpClient that the TelegramClient has, but no, it doesn't receive updates
The documentation says:
Update events are sent to an authorized user into the last active
connection (except for connections needed for downloading / uploading
files).
So to start receiving updates the client needs to init
connection and call API method, e.g. to fetch current state.
But where does it send updates? How do I subscribe to them / how do I read them?
P.S. updates.getDifference is not what i'm looking for
UPD
I've already looked at all the source code, but the most I found is processMessage in MtProtoSender, but it only handles manually sent requests
Another library based on TDLib handles incoming updates. Trying to understand how it does it, I got to this point. What is going on here and how can I do the same in TLSharp I do not understand
Same problem in another library which was solved but doesn't work for me

Related

Where to receive watch notifications for gmail in .NET?

I'm trying to receive watch notification for Gmail mailboxes in my .NET C# program.
I have the following code:
WatchRequest body = new WatchRequest()
{
LabelIds = labelIds,
TopicName = PrivateKeys.GoogleGmailTopic
};
WatchResponse response = new UsersResource.WatchRequest(_gmailService, body, "me")
{
Key = PrivateKeys.GoogleApiKey,
OauthToken = AccessToken
}
.Execute();
... and it seems to work, since I get a response.
But where do I receive these notifications inside my program? How can I configure the event entry point?
Assuming you did the preliminary work to set up a Cloud Pub/Sub client (described here: https://developers.google.com/gmail/api/guides/push#initial_cloud_pubsub_setup), you should have a Pub/Sub subscription - either PULL or PUSH.
In order to get the notifications, your application should initiate a subscriber, you can follow the instructions in https://cloud.google.com/pubsub/docs/pull for PULL or in https://cloud.google.com/pubsub/docs/push for PUSH. Configuring the event entry point should be done as part of the subscriber set up.

Manage a long-running operation in MS Teams Bot

I am using the following sample / article to Manage a Long-running operation in MS Teams Bot.
https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-howto-long-operations-guidance?view=azure-bot-service-4.0
In step 5, a DirectLineClient is being created and an Event Activity is sent to Bot using PostActivityAsync.
var responseActivity = new Activity("event");
responseActivity.Value = originalActivity;
responseActivity.Name = "LongOperationResponse";
responseActivity.From = new ChannelAccount("GenerateReport", "AzureFunction");
var directLineSecret = Environment.GetEnvironmentVariable("DirectLineSecret");
using(DirectLineClient client = new DirectLineClient(directLineSecret))
{
var conversation = await client.Conversations.StartConversationAsync();
await client.Conversations.PostActivityAsync(conversation.ConversationId, responseActivity);
}
However, I need the above sample to work for MS Teams Bot and not the DirectLineClient.
I used Microsoft.Bot.Connector.ConnectorClient but StartconversationAsync and PostActivityAsync methods are not available.
I tried the methods available in Microsoft.Bot.Connector.ConnectorClient
connectorClient.Conversations.CreateConversationAsync(conversationparameters)
connectorClient.ConversationsCreateDirectConversationAsync(botAccount, userAccount, (Activity)newActivity);
connectorClient.Conversations.SendToConversationAsync(conversationid, (Activity)newActivity);
But all the methods failed with Bad Requestwith the error as seen in the Response:
{"error":{"code":"BadArgument","message":"Unknown activity type"}}
The newActivity is created as below:
var messagnewActivity = new Activity("event");
newActivity.Value = originalActivity;
newActivity.From = new ChannelAccount("GenerateReport", "AzureFunction");
newActivity.Type = "event";
newActivity.Conversation = new ConversationAccount { Id = originalActivity.Conversation.Id };
newActivity.ChannelId = originalActivity.ChannelId;
Can someone please suggest how do I pass the Activity (Event Activity type) to MS Teams Bot.
Thanks
Gagan
I'm not really familiar with Direct Line, but I think it's effectively an -alternative- type of bot to Teams, so if you're trying to do this inside Teams, it explains the issue. In principle, the basic idea is quite simple though:
you store state somehow (e.g. in memory or in a database) to indicate that the long running operation is in progress for the user
when the long-running process is complete, your code (which could live OUTSIDE your bot, e.g. in an Azure Function) can send the user a message AS IF IT WAS the bot - this is called Pro-Active Messaging and you can read more about it at https://learn.microsoft.com/en-us/graph/teams-proactive-messaging.
This is to inform you that I was facing the same issue sometime before then I found a tweak in the code while debugging. when it calls twice recursively then the Activity Id is the same as the previous one. you can check if the activity id is the same then return the request else go with it.

Configuring wildcard topic selectors in ActiveMQ

Based on the documentation wildcards support does exist, but I can't seem to find any other info on whether it's just supposed to work or if it's configured on the server or whether the producers or consumers need to configure it.
I'm assuming as a publisher I would just send messages to a topic named /patient/2/goal/ and when a consumer subscribed to a topic called /patient/*/goal/ it would still receive the message, however nothing shows up. What am I missing?
Please note that if I publish a message to /patient/*/goal/ and subscribe to /patient/*/goal/ then I receive the message. However, that only confirms my message bus is working, not that wildcard support is working.
Producer test:
var connectUri = new Uri("...");
var factory = new NMSConnectionFactory(connectUri);
var connection = factory.CreateConnection();
session = connection.CreateSession();
var destination = session.GetTopic("/patient/1/goal/");
producer = session.CreateProducer(destination);
...
Consumer:
var topic = _session.GetTopic("/patient/*/goal/");
var consumer = _session.CreateConsumer(topic);
...
Using / as the the path separator needs to be configured through a plugin. Switching to . made it work as expected.

C# AWS SQS request signature does not match the signature provided

I have a single project that contains classes to communicate with AWS. SQS is the only one that is not working. It is safe to assume that the access and secret keys are valid. I am also able to access this queue elsewhere so i am 100% it exists.
I have created a super basic method and this is failing.
var Config = new AmazonSQSConfig() { ServiceURL = "https://sqs.eu-west-1.amazonaws.com/.....etc"};
var Client = new AmazonSQSClient(Config);
SendMessageRequest request = new SendMessageRequest() { MessageBody = "Hello", };
SendMessageResponse sendMessageResponse = Client.SendMessage(request);
When the final line Client.SendMessage(request) runs it throws a 403 exception with the error
The request signature we calculated does not match the signature you
provided. Check your AWS Secret Access Key and signing method. Consult
the service documentation for details.
The code is so basic that i cant see where it could be wrong. The secret and access keys work for all other AWS communication so this cant be the cause and i am 100% sure the queue exists. What could be causing this?
This code works - see if you can use it instead:
using (var client = new AmazonSQSClient(Amazon.RegionEndpoint.USEast1))
{
client.SendMessage(new SendMessageRequest { QueueUrl = _queueName, MessageBody = JsonConvert.SerializeObject(request) });
}
Seems to be a really weird one, but i resolved the issue by using the fragmented AWSSDK instead of the complete one. I was using the main sdk from NuGet that contains everything for AWS. I removed this and install the core, s3 and sqs parts of the SDK. The code immediately worked once i did this. No idea why it did this and why it worked for S3 and not SQS, but at least this was a fairly simple fix.

How to track MongoDB requests from a console application

I have a Console Application project written in C# which I've added Application Insights to with the following NuGet packages.
Microsoft.ApplicationInsights
Microsoft.ApplicationInsights.Agent.Intercept
Microsoft.ApplicationInsights.DependencyCollector
Microsoft.ApplicationInsights.NLogTarget
Microsoft.ApplicationInsights.PerfCounterCollector
Microsoft.ApplicationInsights.Web
Microsoft.ApplicationInsights.WindowsServer
Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel
I've configured my InstrumentationKey in the config file and I'm firing up a TelemetryClient on startup using the with the following code:
var telemetryClient = new TelemetryClient();
telemetryClient.Context.User.Id = Environment.UserName;
telemetryClient.Context.Session.Id = Guid.NewGuid().ToString();
telemetryClient.Context.Device.OperatingSystem = Environment.OSVersion.ToString();
Everything is working well except AI is not capturing any requests that get sent to Mongo, I can see requests going off to SQL server in the 'Application map' but no sign of any other external requests. Is there any way that I can see telemetry of requests made to Mongo?
EDIT - Thanks to Peter Bons I ended up with pretty much the following which works like a charm and allows me to distinguish between success and failure:
var telemetryClient = new TelemetryClient();
var connectionString = connectionStringSettings.ConnectionString;
var mongoUrl = new MongoUrl(connectionString);
var mongoClientSettings = MongoClientSettings.FromUrl(mongoUrl);
mongoClientSettings.ClusterConfigurator = clusterConfigurator =>
{
clusterConfigurator.Subscribe<CommandSucceededEvent>(e =>
{
telemetryClient.TrackDependency("MongoDB", e.CommandName, DateTime.Now.Subtract(e.Duration), e.Duration, true);
});
clusterConfigurator.Subscribe<CommandFailedEvent>(e =>
{
telemetryClient.TrackDependency("MongoDB", $"{e.CommandName} - {e.ToString()}", DateTime.Now.Subtract(e.Duration), e.Duration, false);
});
};
var mongoClient = new MongoClient(mongoClientSettings);
I am not familiar with MongoDB but as far as I can tell there is no default support for it when it comes to Application Insights. But that does not mean you cannot do this, it will just involve some more code.
Again, I am not familiar with MongoDB but according to http://www.mattburkedev.com/logging-queries-from-mongodb-c-number-driver/ there is built-in support for logging the generated queries. Now, we only need to hook this up to Application Insights.
Since you already know how to use the TelemetryClient we can use the custom tracking methods provided by that class. See https://learn.microsoft.com/nl-nl/azure/application-insights/app-insights-api-custom-events-metrics for the available custom tracking methods.
All you need to do is to insert some code like this:
telemetryClient.TrackDependency(
"MongoDB", // The name of the dependency
query, // Text of the query
DateTime.Now, // Time that query is executed
TimeSpan.FromSeconds(0), // Time taken to execute query
true); // Indicates success
The class telemetryClient is thread-safe so you can reuse it.
Now, according to the referenced blogpost you should be able to do something like this:
var client = new MongoClient(new MongoClientSettings()
{
Server = new MongoServerAddress("localhost"),
ClusterConfigurator = cb =>
{
cb.Subscribe<CommandStartedEvent>(e =>
{
telemetryClient.TrackDependency(
"MongoDB", // The name of the dependency
e.Command.ToJson() // Text of the query
DateTime.Now, // Time that query is executed
TimeSpan.FromSeconds(0), // Time taken to execute query
true); // Indicates success
});
}
});
Again, I am not familiar with MongoDB but I hope this is a starting point for your imagination on how to adapt it to your needs using your knowledge of MongoDB.
EDIT:
If there is also a CommandCompletedEvent or similar event as opposed to the CommandStartedEvent event you should probably track the dependency there because you should then be able to calculate (or simpel read) the time spent and maybe get the actual value for the success indicator.

Categories

Resources