This repository was archived by the owner on Dec 4, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 117
This repository was archived by the owner on Dec 4, 2023. It is now read-only.
Conversations#replyToActivity() throw the JsonParseException #57
Copy link
Copy link
Closed
Labels
customer-replied-toIndicates that the team has replied to the issue reported by the customer. Do not delete.Indicates that the team has replied to the issue reported by the customer. Do not delete.
Description
When I try to implement the Bot Application on Azure Function, I faced the problem as follows.
- Conversations#replyToActivity() throw the JsonParseException.
111: ResourceResponse response = connector.conversations().replyToActivity(activity.conversation().id(), activity.id(), replyActivity);
This problem was also happen on the method invocation of Conversations#sendToConversation().
Following is the StackTrace of the Exception.
[2018/08/31 9:05:37] java.lang.RuntimeException: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'The': was expecting ('true', 'false' or 'null')
[2018/08/31 9:05:37] at [Source: (String)"The page cannot be displayed because an internal server error has occurred."; line: 1, column: 4]
[2018/08/31 9:05:37]
[2018/08/31 9:05:37] at rx.exceptions.Exceptions.propagate(Exceptions.java:58)
[2018/08/31 9:05:37] at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:464)
[2018/08/31 9:05:37] at rx.observables.BlockingObservable.single(BlockingObservable.java:341)
[2018/08/31 9:05:37] at com.microsoft.bot.connector.implementation.ConversationsImpl.replyToActivity(ConversationsImpl.java:633)
[2018/08/31 9:05:37] at com.yoshio3.Function.execOperation(Function.java:111)
[2018/08/31 9:05:37] at com.yoshio3.Function.lambda$HttpTriggerJava$0(Function.java:55)
Following is the sample code which run on Azure Function.
package com.yoshio3;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.microsoft.aad.adal4j.AuthenticationException;
import java.util.*;
import com.microsoft.azure.functions.annotation.*;
import com.microsoft.azure.functions.*;
import com.microsoft.bot.connector.Conversations;
import com.microsoft.bot.connector.customizations.ClaimsIdentity;
import com.microsoft.bot.connector.customizations.CredentialProvider;
import com.microsoft.bot.connector.customizations.CredentialProviderImpl;
import com.microsoft.bot.connector.customizations.JwtTokenValidation;
import com.microsoft.bot.connector.customizations.MicrosoftAppCredentials;
import com.microsoft.bot.connector.implementation.ConnectorClientImpl;
import com.microsoft.bot.schema.models.Activity;
import com.microsoft.bot.schema.models.ActivityTypes;
import com.microsoft.bot.schema.models.ResourceResponse;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDateTime;
/**
* Azure Functions with HTTP Trigger.
*/
public class Function {
private final static String AUTHORIZATION_HEADER = "authorization";
private static final String APP_ID = "";
private static final String APP_PASSWORD = "";
/**
*
* @param request
* @param context
* @return
*/
@FunctionName("HttpTrigger-Java")
public HttpResponseMessage HttpTriggerJava(
@HttpTrigger(name = "req",
methods = {HttpMethod.POST},
authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
final ExecutionContext context) {
context.getLogger().info("Java HTTP trigger processed a request.");
ExecutorService exec = Executors.newSingleThreadExecutor();
exec.submit(() -> {
try {
execOperation(request, context);
} catch (IOException | ExecutionException | InterruptedException ex) {
context.getLogger().log(Level.SEVERE, null, ex);
} catch (Exception e) {
context.getLogger().log(Level.SEVERE, null, e);
e.printStackTrace();
}
});
return request.createResponseBuilder(HttpStatus.ACCEPTED).build();
}
private void execOperation(HttpRequestMessage<Optional<String>> request, ExecutionContext context) throws JsonProcessingException, IOException, ExecutionException, InterruptedException {
try {
CredentialProvider credentialProvider = new CredentialProviderImpl(APP_ID, APP_PASSWORD);
MicrosoftAppCredentials credentials = new MicrosoftAppCredentials(APP_ID, APP_PASSWORD);
Optional<String> optionalBody = request.getBody();
String httpBody = optionalBody.orElseGet(() -> "");
System.out.println("------- This is the Message Body from BotFramework Start -------");
System.out.println(httpBody);
System.out.println("------- This is the Message Body from BotFramework End -------");
String authHeaderValue = request.getHeaders().getOrDefault(AUTHORIZATION_HEADER, "");
CompletableFuture<ClaimsIdentity> validateAuthHeader = JwtTokenValidation.validateAuthHeader(authHeaderValue, credentialProvider);
validateAuthHeader.thenAccept(claimIdentity -> {
if (claimIdentity.isAuthenticated()) {
System.out.println("AUTENTICATE SUCCESS");
} else {
System.out.println("AUTENTICATE FAILED");
}
});
Activity activity = getActivity(httpBody);
System.out.println("------- This is Activity Object from BotFramework Start ------------");
printActivity(activity);
System.out.println("------- This is Activity Object from BotFramework End ------------");
if (activity.type().equals(ActivityTypes.MESSAGE)) {
ConnectorClientImpl connector = new ConnectorClientImpl(credentials);
Conversations conversations = connector.conversations();
ConversationsResult convResult = conversations.getConversations();
Activity replyActivity = new Activity()
.withType(ActivityTypes.MESSAGE)
.withTimestamp(new LocalDateTime().toDateTime(DateTimeZone.UTC))
.withConversation(activity.conversation())
.withRecipient(activity.from())
.withFrom(activity.recipient())
.withReplyToId(activity.id())
.withText("Echo " + activity.text());
System.out.println("------- This is Activity Object for Return the Message Start -------");
printActivity(replyActivity);
System.out.println("------- This is Activity Object for Return the Message End -------");
ResourceResponse response = conversations.replyToActivity(activity.conversation().id(), activity.id(), replyActivity);
}
} catch (AuthenticationException ae) {
throw ae;
} catch (IOException ioe) {
throw ioe;
} catch (InterruptedException inte) {
throw inte;
} catch (ExecutionException ex) {
throw ex;
} catch (Exception e) {
throw e;
}
}
private Activity getActivity(String httpBody) throws IOException {
ObjectMapper objectMapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.findAndRegisterModules();
return objectMapper.readValue(httpBody, Activity.class);
}
private void printActivity(Activity activity) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.findAndRegisterModules();
System.out.println("------- Print Activity Start -------");
System.out.println("type : " + activity.type());
System.out.println("timestamp : " + activity.timestamp());
System.out.println("from : " + activity.from());
System.out.println("Conversation : " + activity.conversation());
System.out.println("Recipient : " + activity.recipient());
System.out.println("Text : " + activity.text());
System.out.println("replyToId : " + activity.replyToId());
if (activity.membersAdded() != null) {
activity.membersAdded().stream().forEach(account -> {
System.out.println("Members Account ID : " + account.id());
System.out.println("Members Account Name : " + account.name());
});
}
System.out.println("------- Print JSON Data ----------");
String json = objectMapper.writeValueAsString(activity);
System.out.println(json);
}
}
Following is the JSON Data of Activity Object for return the messages.
$ jq . after.json
{
"type": "message",
"id": null,
"timestamp": 1535738736966,
"localTimestamp": null,
"serviceUrl": null,
"channelId": null,
"from": {
"id": "Java-BotBuilder-Function@KLSKBveC4Gw",
"name": "Java-BotBuilder-Function",
"role": null
},
"conversation": {
"group": null,
"isGroup": null,
"conversationType": null,
"id": "eecdbc948df1409eb3d85fd52a2e0b0e",
"name": null,
"role": null
},
"recipient": {
"id": "GqmZkaUErhj",
"name": "You",
"role": null
},
"textFormat": null,
"attachmentLayout": null,
"membersAdded": null,
"membersRemoved": null,
"reactionsAdded": null,
"reactionsRemoved": null,
"topicName": null,
"historyDisclosed": null,
"locale": null,
"text": "Echo test",
"speak": null,
"inputHint": null,
"summary": null,
"suggestedActions": null,
"attachments": null,
"entities": null,
"channelData": null,
"action": null,
"replyToId": "eecdbc948df1409eb3d85fd52a2e0b0e|0000000",
"label": null,
"valueType": null,
"value": null,
"name": null,
"relatesTo": null,
"code": null,
"expiration": null,
"importance": null,
"deliveryMode": null,
"textHighlights": null
}
From the above JSON data, there is no invalid value of "The".
[2018/08/31 9:05:37] java.lang.RuntimeException: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'The': was expecting ('true', 'false' or 'null')
[2018/08/31 9:05:37] at [Source: (String)"The page cannot be displayed because an internal server error has occurred."; line: 1, column: 4]
Please refer to the detail log on log.txt ?
Metadata
Metadata
Assignees
Labels
customer-replied-toIndicates that the team has replied to the issue reported by the customer. Do not delete.Indicates that the team has replied to the issue reported by the customer. Do not delete.