Untitled document (Pdf) opened in whatsApp version of IOS (Tyntec) - c#

Iam using third part called tyntec to deal with whatsApp messages ,
my Api deals with tyntec to send a file to specific number :-
and this is the part in my repository which has responsability to talk with tyntec :-
public async Task<SendingMessageRespons> SendRequestAsync(object requestBody)
{
var serializedRequest = "";
try
{
serializedRequest = JsonSerializer.Serialize(requestBody, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
IgnoreNullValues = true
});
var requestContent = new StringContent(serializedRequest, Encoding.UTF8, "application/json");
var client = new HttpClient();
client.DefaultRequestHeaders.Add("apikey", _config.APIkey);
var response = await client.PostAsync(_config.APIUrl, requestContent);
var content = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var message = JsonSerializer.Deserialize<Message>(content);
return SendingMessageRespons.Create(response.StatusCode, serializedRequest, content, message.messageId);
}
else
{
return SendingMessageRespons.Create(response.StatusCode, serializedRequest, content, string.Empty);
}
}
catch (Exception ex)
{
return SendingMessageRespons.Create(HttpStatusCode.ExpectationFailed, serializedRequest, ex.Message, null);
}
}
and it's configuration:-
my problem is when I send the pdf to any android user ... it works fine and the name of pdf shows like this :-
but when I send the same pdf to IOS user the name becomes "Untitled" Like this
and when I open the pdf it's name shows
Am trying to guess where is the problem but I can't figure out

I found the answer
the problem was in parameter of the body request :-
My old Json
{
"to": "201119959346",
"channels": ["whatsapp"],
"whatsapp": {
"from" : "201000081092",
"media" : {
"type" : "document"
,
"url" : "https://www.tyntec.com/sites/default/files/uploads/1608_tyntec_CorporateBackground.pdf",
"caption" : "hady125 corporate background"
},
"contentType":"media"
}
}
The new one :-
{
"to": "201119959346",
"channels": ["whatsapp"],
"whatsapp": {
"from" : "201000081092",
"media" : {
"type" : "document"
,
"filename":"hady corporate background" // the new param
,
"url" : "https://www.tyntec.com/sites/default/files/uploads/1608_tyntec_CorporateBackground.pdf",
"caption" : "hady125 corporate background"
},
"contentType":"media"
}
}
notice :- you should keep the two params Caption and filename to work in IOS and Android

Related

How to remove characters from a received request body

I was trying to develop an API to receive GPS data from an IOT device. Below which is the data coming from the device.
O||GPS[ {"GPSTime": "01/09/2021 02:34:03", "Coordinates": "0.000000", "RegisterNo": "144"} ]
I have created an API as mentioned below. When I post data to this API its giving bad request because of invalid json format. Need to know how to remove characters from a received request body and how to take the data only from inside curly bracket.
public class GPSController : ApiController
{
[HttpPost]
[Route("GPSData")]
// public HttpResponseMessage Post([FromBody]GPSModel gPSData)
public HttpResponseMessage Post([FromBody]GPSData gPSData)
{
using (DBEntities entities = new DBEntities())
{
var ins = new GPSData();
ins.Coordinates= gPSData.Coordinates;
ins.GPSTime = gPSData.GPSTime;
ins.UpdatedTime = DateTime.Now;
entities.GPSDatas.Add(ins);
entities.SaveChanges();
var message = Request.CreateResponse(HttpStatusCode.Created, gPSData);
message.Headers.Location = new Uri(Request.RequestUri + gPSData.RegisterNo.ToString());
return message;
}
}
}

Problem accessing passed parameter in url redirection

Hello I'm trying to do an Oauth 2.0 to integrate two systems together,
and it uses oauth so I have successfully been able to get the auth code from the url after authenticating, but I couldn't get the parameter from the redirect url to use it and generate the token within the code.
public void getData()
{
var query = "Store-url?scope=offline_access&state=12345678&response_type=code&approval_prompt=auto&redirect_uri=localhost/api/Omar/test&client_id=";
Response.Redirect(query);
}
this is the redirect url which take me to the store website to give the access and then it return the auth code in the url like this:
https://localhost/api/Omar/test?code=OPCKC8KwzcTPUWnvJsA-apz09-PsDNrDYTrUfffMIDU.pnjIZahbJBxC9G_BY4KEom2LNkPHKbnojJCeotylcKA&scope=settings.read+products.read_write+offline_access&state=12345678
and I tried the code to generate the token and it worked
the problem is how I get store the code passed in the parameter so I can use in my method that generates the token within the code
and the method code is
[HttpGet("test")]
public async Task<IActionResult> test(string code)
{
var values = new Dictionary<string, string>
{
{ "client_id", "" },
{ "client_secret", "" },
{ "grant_type", "authorization_code" },
{ "code", code },
{ "redirect_uri", "localhost/api/Omar/test" }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("store-generate-token-url", content);
var responseString = await response.Content.ReadAsStringAsync();
return Ok("TEST SUCCESS"+ " "+ responseString);
}

Calling Microsoft Graph API to create an event, What am I doing wrong?

I've been trying to call Microsoft Graph API for creating events, however I've not been able to do it.
Context: I have a Web MVC application (C#) already in production, with the "common" authentication method, reading a database of users. Recently the customer asked me the possibility to create Microsoft Teams Meetings from the application and also those created meetings have to be scheduled in the Microsoft Teams Calendar with the "Join" button to enter the meeting.
I already configured the API permissions, client secret and used the other properties like tenant, user id, etc from the Azure Portal, I'm sharing a screenshot of my configuration. I'm doing the "Get access on behalf of a user" process.
API Permissions:
Permissions image
Taking the example of the authorize endpoint from the docs, of course I'm replacing the values with my own info
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=11111111-1111-1111-1111-111111111111
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=query
&scope=offline_access%20user.read%20mail.read
&state=12345
Here is my code to Receive the code once the user authorizes the permissions, I'm just storing the value in a static class for testing
public ActionResult ReceiveCode(string code)
{
AuthenticationConfig.Code = code;
//this.Code = code;
return RedirectToAction("Index");
}
Once I got the Auth code, I'm using it to create the event with the generated token, also I already verified that the token contains the permissions given in the Azure Portal.
This is the input for the /events endpoint
var json = JsonConvert.SerializeObject(new
{
subject = "Let's go for lunch",
body = new
{
contentType = "HTML",
content = "Does noon work for you?"
},
start = new
{
dateTime = "2017-04-15T12:00:00",
timeZone = "Pacific Standard Time",
},
end = new
{
dateTime = "2017-04-15T14:00:00",
timeZone = "Pacific Standard Time"
},
location = new
{
displayName = "Harry's Bar",
},
attendees = new List<Attendee>()
{
new Attendee
{
EmailAddress = new EmailAddress
{
Address = "mymail#whatever.com",
Name = "Foo Bar"
},
Type = AttendeeType.Required
}
},
allowNewTimeProposals = true,
isOnlineMeeting = true,
onlineMeetingProvider = "teamsForBusiness",
});
This is the complete method, for the json value, please see the json above. I also tried with the "me" url but it does not work either.
public async Task<ActionResult> OnlineMeeting()
{
try
{
var httpClient = new HttpClient();
var paramsDictionary = new Dictionary<string, string>();
paramsDictionary.Add("client_id",AuthenticationConfig.ClientId);
paramsDictionary.Add("scope", "Calendars.ReadWrite");
paramsDictionary.Add("code", AuthenticationConfig.Code);
paramsDictionary.Add("redirect_uri", "https://localhost:44379/Meeting/Reunion/ReceiveCode");
paramsDictionary.Add("grant_type", "authorization_code");
paramsDictionary.Add("client_secret", AuthenticationConfig.ClientSecret);
var url = string.Format("https://login.microsoftonline.com/{0}/oauth2/v2.0/token", "tenant");
var response = await httpClient.PostAsync(url, new FormUrlEncodedContent(paramsDictionary));
if (response.IsSuccessStatusCode)
{
var jsonResponse = await response.Content.ReadAsStringAsync();
var jsonResult = JsonConvert.DeserializeObject(jsonResponse) as JObject;
var accessToken = jsonResult.GetValue("access_token").ToString();
httpClient = new HttpClient();
var json = JsonConvert.SerializeObject(new { });
var defaultRequestHeaders = httpClient.DefaultRequestHeaders;
if (defaultRequestHeaders.Accept == null || !defaultRequestHeaders.Accept.Any(m => m.MediaType == "application/json"))
{
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
defaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var data = new StringContent(json);
response = await httpClient.PostAsync("https://graph.microsoft.com/v1.0/users/{user id}/events", data);
if (response.IsSuccessStatusCode)
{
// Nice
}
else
{
Console.WriteLine($"Failed to call the web API: {response.StatusCode}");
string content = await response.Content.ReadAsStringAsync();
}
}
else
{
Console.WriteLine($"Failed to call the web API: {response.StatusCode}");
string content = await response.Content.ReadAsStringAsync();
}
}
catch (Exception ex)
{
}
return View();
}
I'm able to the get the token, but when trying to create the event returns the next response.
{
"error": {
"code": "ResourceNotFound",
"message": "Resource could not be discovered.",
"innerError": {
"date": "2021-08-31T22:58:18",
"request-id": "c5c07afa-fa89-4948-a9f8-f80ca4cbafc3",
"client-request-id": "c5c07afa-fa89-4948-a9f8-f80ca4cbafc3"
}
}
}
Am I missing something? Maybe the wrong endpoint?
Please, help.
Thanks in advance.

How to send a json object instead of a string with Azure Client SDK

I'm struggling with creating a message from a device to the IotHub in the correct format.
I'm using the Azure Client SDK (Microsoft.Azure.Devices.Client)
For better understanding lets start with a small example, we have the following string:
var TableName = "table01";
var PartitionKey = "key01";
string messagePayload = $"{{\"tablename\":\"{TableName}\",\"partitionkey\":\"{PartitionKey}\"}}";
( Taken from the example Send device to cloud telemetry) we create an eventMessage
using var eventMessage = new Microsoft.Azure.Devices.Client.Message(Encoding.UTF8.GetBytes(messagePayload))
{
ContentEncoding = Encoding.UTF8.ToString(),
ContentType = "application/json"
};
And then send it to the Cloud:
Console.WriteLine(messagePayload);
await deviceClient.SendEventAsync(eventMessage);
Output from the writeline, which is what I wanted in the first place:
{"tablename":"table01","partitionkey":"key01"}
What I can see in the shell after following the answer about watching incoming IotHub Messages:
{
"event": {
"origin": "WinSensorTest",
"module": "",
"interface": "",
"component": "",
"payload": "{\"tablename\":\"table01\",\"partitionkey\":\"key01\"}"
}
}
The Problem is, that I want it to either look like the code below or completely without the "event" etc, just the string above.
{
"event":{
"origin":"WinSensorTest",
"module":"",
"interface":"",
"component":"",
"payload":{
"tablename":"table01",
"partitionkey":"key01"
}
}
}
Where did I go wrong, how can the payload be correct json format?
Edit:
I just tried the same in Java, with the same result. Why does this not work, or is the data seen in the shell not correctly parsed?
If you create a proper Json object first it works and also shows up correct in the shell - interestingly only for this c# project, I tried doing the same in Java on Android and the same wierd formatting stuff still happens even after making an object with gson.
For the solution:
class JsonMessage
{
public string tablename { get; set; }
public string partitionkey { get; set; }
}
And then Used JsonMessage and JsonConvert to get the desired payload.
JsonMessage newMsg = new JsonMessage()
{
tablename = "table01",
partitionkey = "key01",
};
string payload = JsonConvert.SerializeObject(newMsg);
using var eventMessage = new Microsoft.Azure.Devices.Client.Message(Encoding.UTF8.GetBytes(payload))
{
ContentEncoding = Encoding.UTF8.ToString(),
ContentType = "application/json"
};

Can't Upload a File to QnaMaker Knowledge Base using SDK

I currently have an Azure Function that I would like to have update a QnaMaker Knowledge Base every day or so. Currently everything is connected and working fine, however I can only send Qna Objects (qna pairs) and not urls to files on a website of mine. So in the example I provided below, while it should populate the KB with 2 questions and the file from the url, it only populates the questions.
Currently this is not giving me any kind of error, in fact the response code from my call to the KB comes back as 204. So it it getting through, but still not adding the file to the KB as it should.
NOTE: The file being imported in this example (alice-I.html) is a random one for this demonstration (not mine, for security), but the issue is the same. If I directly add this file to the QnaMaker from the KB site itself it works fine, but it won't update from the Azure Function Code.
Any insights into what is happening would be great.
Content Being Sent To Knowledge Base
string replace_kb = #"{
'qnaList': [
{
'id': 0,
'answer': 'A-1',
'source': 'Custom Editorial',
'questions': [
'Q-1'
],
'metadata': []
},
{
'id': 1,
'answer': 'A-2',
'source': 'Custom Editorial',
'questions': [
'Q-2'
],
'metadata': [
{
'name': 'category',
'value': 'api'
}
]
}
],
'files': [
{
'fileName': 'alice-I.html',
'fileUri': 'https://www.cs.cmu.edu/~rgs/alice-I.html'
}
]
}";
Code Sending Content To Knowledge Base
using (var clientF = new HttpClient())
using (var requestF = new HttpRequestMessage())
{
requestF.Method = HttpMethod.Put;
requestF.RequestUri = new Uri(<your-uri>);
requestF.Content = new StringContent(replace_kb, Encoding.UTF8, "application/json");
requestF.Headers.Add("Ocp-Apim-Subscription-Key", <your-key>);
var responseF = await clientF.SendAsync(requestF);
if (responseF.IsSuccessStatusCode)
{
log.LogInformation("{'result' : 'Success.'}");
log.LogInformation($"------------>{responseF}");
}
else
{
await responseF.Content.ReadAsStringAsync();
log.LogInformation($"------------>{responseF}");
}
}
So I still don't know how to get the above working, but I got it to work a different way. Basically I used the UpdateKbOperationDTO Class listed here: class
This still isn't the perfect solution, but it allows me to update my KB with files using code instead of the interface.
Below is my new code:
QnAMakerClient qnaC = new QnAMakerClient(new ApiKeyServiceClientCredentials(<subscription-key>)) { Endpoint = "https://<your-custom-domain>.cognitiveservices.azure.com"};
log.LogInformation("Delete-->Start");
List<string> toDelete = new List<string>();
toDelete.Add("<my-file>");
var updateDelete = await qnaC.Knowledgebase.UpdateAsync(kbId, new UpdateKbOperationDTO
{
// Create JSON of changes ///
Add = null,
Update = null,
Delete = new UpdateKbOperationDTODelete(null, toDelete)
});
log.LogInformation("Delete-->Done");
log.LogInformation("Add-->Start");
List<FileDTO> toAdd = new List<FileDTO>();
toAdd.Add(new FileDTO("<my-file>", "<url-to-file>"));
var updateAdd = await qnaC.Knowledgebase.UpdateAsync(kbId, new UpdateKbOperationDTO
{
// Create JSON of changes ///
Add = new UpdateKbOperationDTOAdd(null, null, toAdd),
Update = null,
Delete = null
});
log.LogInformation("Add-->Done");

Categories

Resources