UnknownError sending messages to Teams - c#

I'm trying to send a message into a channel inside an organization's Teams.
I have deployed the app successfully, and I get an Authentication token.
When I do as stated here to send messages to a chat, via C# as follows:
_token = await _authenticationHelper.GetAuthenticationToken();
AccessToken = _token;
string teamId = "xxx-xxx-xxx-XX-Xxxxx";
string channelId = "...thread.skype";
var val = await HttpPost($"/teams/{teamId}/channels/{channelId}/messages",
"{ \"body\": { \"contentType\": \"html\", \"content\": \"Hello World\" } }", endpoint: "https://graph.microsoft.com/beta");
get an error from Microsoft Graph Stating:
System.Exception: {
"error": {
"code": "UnknownError",
"message": "",
"innerError": {
"request-id": "44b6397d-aae4-4f60-a2fd-200070c64908",
"date": "2019-04-18T12:30:02"
}
}
}
This error is not descriptive so I don't really know what went wrong.

Related

Webhook Notification With Authorize.Net

I created an endpoint (Endpoint) for the webhook part in Authorize.Net and when I create subscription for a user from web app, I get the following in the request body (Am using Beeceptor for the endpoint):
{
"notificationId": "79780e46-c62d-4620-b4fb-e8c29366b2ec",
"eventType": "net.authorize.customer.subscription.created",
"eventDate": "2021-05-08T17:23:57.7129026Z",
"webhookId": "3b2fd08b-a7c4-4f29-95b5-8330958d6031",
"payload": {
"name": "AT",
"amount": 3.00,
"status": "active",
"profile": {
"customerProfileId": 1518406781,
"customerPaymentProfileId": 1517676588
},
"entityName": "subscription",
"id": "7397362"
}
}
I followed the link to create the endpoint - Webhook
I believe, am close enough for webhook notifications. But can anyone suggest when the monthly subscription is charged using Authorize.Net, how the response body is passed to endpoint with the webhook like is it jSon data or something similar (Obviously jSon, I believe) or what fields will it return in response (SubscriptionId, Date)? In the documentation, they trigger different event to notify with Webhook. My final goal is to retrieve that a subscriber has been charged for a month and this should be saved in database for future use. Though I just started trying with it, will like to have some feedback on it in advance - Thanks.
N.B: Below image is the output when an event is triggered using Webhook.
For regular transaction, I get the following using webhook notification:
{
"notificationId": "c453f527-8b7c-407d-8ec7-b022188af4a7",
"eventType": "net.authorize.payment.authcapture.created",
"eventDate": "2021-05-08T17:51:20.5783303Z",
"webhookId": "3b2fd08b-a7c4-4f29-95b5-8330958d6031",
"payload": {
"responseCode": 1,
"authCode": "OT3UUE",
"avsResponse": "Y",
"authAmount": 1.00,
"entityName": "transaction",
"id": "60167299547"
}
}
C# sample Code: Web request from C# web app
public string GetNotificationWithWebhook()
{
string response = "";
var url = "beeceptor endpoint here";
var httpRequest = (HttpWebRequest)WebRequest.Create(url);
var httpResponse = (HttpWebResponse)httpRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
response = streamReader.ReadToEnd();
}
return response;
}
Request body and response:
The webhook notification will be almost exactly like a "regular" transaction but a subscription ID will also be included. So it should resemble:
{
"notificationId": "c453f527-8b7c-407d-8ec7-b022188af4a7",
"eventType": "net.authorize.payment.authcapture.created",
"eventDate": "2021-05-08T17:51:20.5783303Z",
"webhookId": "3b2fd08b-a7c4-4f29-95b5-8330958d6031",
"payload": {
"responseCode": 1,
"authCode": "OT3UUE",
"avsResponse": "Y",
"authAmount": 1.00,
"entityName": "transaction",
"id": "60167299547",
"subscriptionId": "1234567890"
}
}
I just tested. The subscriptionId field is not the part of Payload of net.authorize.payment.authcapture.created.
So the solution is to use id(transactionid) to call "Get Transaction Details" API which returns the subscription fields.
Reference: https://community.developer.cybersource.com/t5/Integration-and-Testing/net-authorize-payment-authcapture-created-does-not-have/td-p/63234

The caller's YouTube account is not connected to Google+

good day
I'm using the API explorer at the bottom of https://developers.google.com/youtube/v3/docs/commentThreads/insert?apix=true&apix_params=%7B%22part%22%3A%5B%22snippet%22%5D%2C%22resource%22%3A%7B%22snippet%22%3A%7B%22videoId%22%3A%22s-VhIdn0q5E%22%2C%22topLevelComment%22%3A%7B%22snippet%22%3A%7B%22textOriginal%22%3A%22Tsssssnt%20thread.%22%7D%7D%7D%7D%7D
to test this call. I am requesting the scope https://www.googleapis.com/auth/youtube.force-ssl.
Code connect:
GoogleWebAuthorizationBroker.Folder = idapp.ToString();
CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(60));
CancellationToken ct = cts.Token;
using (var stream = new FileStream(client_secret_file, FileMode.Open, FileAccess.Read))
{
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { YouTubeService.Scope.YoutubeForceSsl},userid, ct).Result;
}
youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = apikey,
HttpClientInitializer = credential,
ApplicationName = idapp.ToString()
});
RESPONSE:
cache-control: private
content-encoding: gzip
content-length: 204
content-type: application/json; charset=UTF-8
date: Mon, 29 Jun 2020 13:07:32 GMT
server: scaffolding on HTTPServer2
vary: Origin, X-Origin, Referer
{
"error": {
"code": 403,
"message": "The caller's YouTube account is not connected to Google+.",
"errors": [
{
"message": "The caller's YouTube account is not connected to Google+.",
"domain": "youtube.commentThread",
"reason": "ineligibleAccount",
"location": "Authorization",
"locationType": "header"
}
]
}
}
In apps Exception like this:
Exception Text
The service youtube has thrown an exception: Google.GoogleApiException: Google.Apis.Requests.RequestError
The caller's YouTube account is not connected to Google+. [403]
Errors [
Message[The caller's YouTube account is not connected to Google+.] Location[Authorization - header] Reason[ineligibleAccount] Domain[youtube.commentThread]
]
at Google.Apis.Requests.ClientServiceRequest`1.d__31.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
Google account was created a week ago. Please help how to use api to add comments on youtube via c # application
public bool Comment(string Channel_Id, string Video_Id, string commentmsg)
{
try
{
CommentThreadSnippet commentThreadSnippetz = new CommentThreadSnippet();
commentThreadSnippetz.ChannelId = Channel_Id;
commentThreadSnippetz.VideoId = Video_Id;
commentThreadSnippetz.TopLevelComment = new Comment() { Snippet = new CommentSnippet() { TextOriginal = commentmsg } };
CommentThreadsResource.InsertRequest commentReq = youtubeService.CommentThreads.Insert(new CommentThread() { Snippet = commentThreadSnippetz }, "snippet");
CommentThread commentRes = commentReq.Execute();
return true;
}
catch (AggregateException ex)
{
foreach (var f in ex.InnerExceptions)
{
MessageTip.ShowError(f.Message, 5000);
}
coonector = false;
return false;
}
}
Well, it's actually too late, but for anyone else encountering this problem, your account that you're trying to use is google only - it has no associated youtube CHANNEL. Just login in on youtube, click your profile pic and create a channel. Worked for me.

SNS - JSON message body failed to parse

I am trying to send to mobile devices a remote notification through Amazon SNS. I got a database which i store the JSON (payload) which needs to be given to PublishRequest of the SNS. I serialise the json in code and pass it to the request.
The issue is that SNS fails with an error: "MESSAGE STRUCTURE - JSON MESSAGE BODY FAILED TO PARSE"
As a requirement, the service (which is responsible to communicate with SNS and send the notification) has to retrieve from DB (MySQL) the json.
What I am missing?
The database is MySQL and the service is written in .Net Core
string messageFromDb = JsonConvert.SerializeObject(input.Payload);
var request = new PublishRequest
{
TargetArn = endpoint.EndpointArn,
MessageStructure = "json",
Message = messageFromDb
};
PublishResponse publishResponse = await _client.PublishAsync(request);
JSON from DB:
{"APNS": {"aps": {"alert": "Check out the new!", "sound": "default"}, "category": {"type": "sports"}}}
I tried also this without any luck:
{"default": "something", "APNS": {"aps": {"alert": "Check out the new games!", "sound": "default"}, "game": {"type": "Xbox"}}}
Finally I figured it out, maybe this answer will help someone. The JSON in the DB should be
{"aps": {"alert": "Check out the new!", "sound": "default"}, "category": {"type": "sports"}}
The .Net code should be:
AWSRoot obj = new AWSRoot(input.Payload);
var request = new PublishRequest
{
TargetArn = endpoint.EndpointArn,
MessageStructure = "json",
Message = JsonConvert.SerializeObject(obj)
};
PublishResponse publishResponse = await _client.PublishAsync(request);
AWSRoot is the root object that we create for SNS
public class AWSRoot
{
public string APNS { get; set; }
public AWSRoot(string payload)
{
APNS = payload;
}
}

How to programatically apply an existing SSL certificate to an Azure web app

I'm using the Azure Fluent Management API to automate our deployment process. Up until now, I've had minimal problems.
We have SSL certificates already uploaded into Azure and can manually bind them to a web site through the Azure portal. But I can't find a mechanism for doing this programmatically.
The closest I can find is below and in the documentation here.
webApp.Update()
.DefineSslBinding()
.ForHostname(domainName)
.WithPfxCertificateToUpload(pfxFile, password)
.WithSniBasedSsl()
.Attach();
However, this is obviously uploading a new certificate, not using an existing one.
There are two other options after the ForHostName() call:
WithExistingAppServiceCertificateOrder(certificateOrder)
and
WithNewStandardSslCertificateOrder(certificateOrderName)
But my understanding is that these are related to purchasing the certificates through Azure/Microsoft.
I also can't see anything in the REST API documentation.
So, how can I associate an existing certificate with a web app, in code?
Obviously this was not critical given I've only found an answer 9 months later.
Anyhow, the answer below is copied from the link provided.
await azure
.WebApps
.Inner
.CreateOrUpdateHostNameBindingWithHttpMessagesAsync(
resourceGroupName,
webAppName,
domain,
new HostNameBindingInner(
azureResourceType: AzureResourceType.Website,
hostNameType: HostNameType.Verified,
customHostNameDnsRecordType: CustomHostNameDnsRecordType.CName,
sslState: SslState.SniEnabled,
thumbprint: thumbprint));
As far as I know, the Azure Fluent Management API’s version is 1.0.0-beta50, so it maybe not contain the method add existing certificate to the host name.
I suggest you could use REST API to achieve it.
I suggest you could send request to below url.
Url: https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Web/sites/{snapshotName}?api-version={api-version}
Method: PUT
Parameter:
subscriptionId The identifier of your subscription where the snapshot is being created.
resourceGroup The name of the resource group that will contain the snapshot.
WebappName The name of the WebappName.
api-version The version of the API to use.
Request content:
{
"properties": {
"HostNameSslStates": [
{
"SslState": "the SSL state",
"ToUpdate": "True",
"Thumbprint": "The Thumbprint of the certificate, you could find it in the portal",
"Name": "yourwebsitename"
}
]
},
"kind": "app",
"location": "yourlocation",
"tags": {
"hidden-related:/subscriptions/{subscriptionId}/resourcegroups/{resourceGroup}/providers/Microsoft.Web/serverfarms/{yourserviceplan}": "empty"
}
}
More details, you could refer to below C# codes:
Json.txt:
{
"properties": {
"HostNameSslStates": [
{
"SslState": "1",
"ToUpdate": "True",
"Thumbprint": "BE58B05C5CADE03628D0D58B369D0DA6F535B0FA",
"Name": "test.azureclubs.com"
}
]
},
"kind": "app",
"location": "East Asia",
"tags": {
"hidden-related:/subscriptions/xxxxxxxxxxxxxxxx/resourcegroups/xxxxxxxxxxxxx/providers/Microsoft.Web/serverfarms/BrandoTestServicePlan": "empty"
}
}
Code:
string body = File.ReadAllText(#"D:\json.txt");
// Display the file contents to the console. Variable text is a string.
string tenantId = "xxxxxxxxxxxxxxxxxxxxxxxxx";
string clientId = "xxxxxxxxxxxxxxxxxxxxxxxxxxx";
string clientSecret = "xxxxxxxxxxxxxxxxxxxxxxxxx";
string subscriptionid = "xxxxxxxxxxxxxxxxxxxxxxxxxx";
string resourcegroup = "BrandoSecondTest";
string appname = "BrandoTestApp";
string version = "2015-08-01";
string authContextURL = "https://login.windows.net/" + tenantId;
var authenticationContext = new AuthenticationContext(authContextURL);
var credential = new ClientCredential(clientId, clientSecret);
var result = authenticationContext.AcquireTokenAsync(resource: "https://management.azure.com/", clientCredential: credential).Result;
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
string token = result.AccessToken;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(string.Format("https://management.azure.com/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Web/sites/{2}?api-version={3}", subscriptionid, resourcegroup, appname, version));
request.Method = "PUT";
request.Headers["Authorization"] = "Bearer " + token;
request.ContentType = "application/json";
try
{
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(body);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
// Get the response
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
Console.WriteLine(streamReader.ReadToEnd());
}
This solution works in 2021. You only need to know the thumbprint of your certificate and it should be in the same resource group as your web app.
var webApp = azure.WebApps
.GetById("webapp resource Id goes here")
.Update()
.DefineSslBinding()
.ForHostname("host name goes here")
.WithExistingCertificate("thumbprint goes here")
.WithSniBasedSsl()
.Attach()
.Apply();

Google+ Moments:Insert AddActivity generic error

I'm trying to publish an app moment for Google+. The app successfully completes the authentication process and receives the access token. The problem happens when I try to call the Moment.Insert API on "https://www.googleapis.com/plus/v1/people/me/moments/vault", always returns this unspecified error message
{
"error": {
"errors": [
{
"domain": "global",
"reason": "invalid",
"message": "Invalid Value"
}
],
"code": 400,
"message": "Invalid Value"
}
}
The API steps I'm following are the ones listed here https://developers.google.com/+/api/latest/moments/insert and the request looks like this
{
"target": {
"kind": "plus#itemScope",
"name": "Sample Test for Google Plus REST API",
"id": "88370F18-81A4-47F5-BC2F-19EDBE326A20",
"url": "http://schema.org/Thing"
},
"type": "http://schemas.google.com/AddActivity",
"kind": "plus#moment"
}
I also add the access token to the request header & the api key to the url as a parameter.
I don't know if I'm missing something here but it may worth saying that I receive the exact same error message when using the API explorer in Google Dev. Console.
Thanks in advance for any insights
This is the moment declaration that worked for me. For some reason, the description field is required and not adding it would produce this strange error message.
var client = new RestClient();
var moment = new
{
kind = "plus#moment",
type = "https://schemas.google.com/AddActivity",
target = new
{
kind = "plus#itemScope",
id = "GENERATE-A-POST-ID-HERE",
type = "https://schemas.google.com/AddActivity",
name = "SOMTHING-TO-POST",
description = "SOMTHING-TO-POST"
}
};
var request = new RestRequest(string.Format("{0}?key={1}", GOOGLE_POST_URL, GOOGLE_APP_ID), Method.POST);
request.AddHeader("authorization", "BEARER-ACCESS-TOKEN-RECEIVED-BEFORE");
request.AddBody(moment);
client.ExecuteAsync(request, OnPostCompleted);
I'm using RestSharp library to handle the REST operations.
Hope this would help.

Categories