1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.plugins.botpress.service;
35
36 import fr.paris.lutece.plugins.botpress.service.renderers.BotMessageRenderer;
37 import com.fasterxml.jackson.databind.JsonNode;
38 import com.fasterxml.jackson.databind.ObjectMapper;
39 import com.fasterxml.jackson.databind.node.MissingNode;
40 import fr.paris.lutece.plugins.botpress.business.RequestMessage;
41 import fr.paris.lutece.plugins.chatbot.business.BotPost;
42 import fr.paris.lutece.portal.service.util.AppLogService;
43 import fr.paris.lutece.util.ReferenceList;
44 import fr.paris.lutece.util.httpaccess.HttpAccess;
45 import fr.paris.lutece.util.httpaccess.HttpAccessException;
46 import java.io.IOException;
47 import java.util.ArrayList;
48 import java.util.HashMap;
49 import java.util.Iterator;
50 import java.util.List;
51 import java.util.Locale;
52 import java.util.Map;
53 import org.apache.log4j.Logger;
54
55
56
57
58 public final class ConverseService
59 {
60
61 private static final String CONTENT_TYPE = "Content-Type";
62 private static final String CONTENT_TYPE_JSON = "application/json";
63 private static final String NODE_RESPONSES = "responses";
64 private static final String NODE_PAYLOAD = "payload";
65 private static final int VERSION_1 = 1;
66
67 private static final String LOGGER_NAME = "botpress";
68 private static final Logger LOGGER = Logger.getLogger( LOGGER_NAME );
69 private static ObjectMapper _objectMapper = new ObjectMapper( );
70
71
72 private ConverseService( )
73 {
74 }
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 public static List<BotPost> getBotResponse( String strMessage, String strConversationId, String strBotApiEntryPointUrl, String strErrorMessage,
92 Locale locale )
93 {
94 List<BotPost> listPosts = new ArrayList<>( );
95 RequestMessages/business/RequestMessage.html#RequestMessage">RequestMessage message = new RequestMessage( strMessage );
96 String strUrl = null;
97 String strJsonResponsePretty = null;
98 try
99 {
100 String strJsonMessage = _objectMapper.writeValueAsString( message );
101 HttpAccess client = new HttpAccess( );
102 HashMap<String, String> mapRequestHeaders = new HashMap<>( );
103 mapRequestHeaders.put( CONTENT_TYPE, CONTENT_TYPE_JSON );
104 HashMap<String, String> mapResponseHeaders = new HashMap<>( );
105 strUrl = strBotApiEntryPointUrl + strConversationId;
106 String strJsonResponse = client.doPostJSON( strUrl, strJsonMessage, mapRequestHeaders, mapResponseHeaders );
107 Object jsonResponse = _objectMapper.readTree( strJsonResponse );
108 strJsonResponsePretty = _objectMapper.writerWithDefaultPrettyPrinter( ).writeValueAsString( jsonResponse );
109 if ( LOGGER.isDebugEnabled( ) )
110 {
111 LOGGER.debug( "Message : " + strMessage + "\nResponse : \n" + strJsonResponsePretty );
112 }
113 parseJsonResponse( strJsonResponse, listPosts );
114 return listPosts;
115 }
116 catch( HttpAccessException | IOException ex )
117 {
118 StringBuilder sbError = new StringBuilder( );
119 sbError.append( "Error getting response from Botpress API : " ).append( ex.getMessage( ) );
120 if ( strUrl != null )
121 {
122 sbError.append( "\n - POST URL : " ).append( strUrl );
123 }
124 if ( strJsonResponsePretty != null )
125 {
126 sbError.append( "\n - JSON response : " ).append( strJsonResponsePretty );
127 }
128 AppLogService.error( sbError.toString( ), ex );
129
130 BotPost post = new BotPost( strErrorMessage );
131 listPosts.add( post );
132
133 return listPosts;
134 }
135
136 }
137
138
139
140
141
142
143
144
145
146
147
148 static void parseJsonResponse( String strJsonResponse, List<BotPost> listPosts ) throws IOException
149 {
150 JsonNode rootNode = _objectMapper.readTree( strJsonResponse );
151 JsonNode responsesNode = rootNode.path( NODE_RESPONSES );
152 if( ! (responsesNode instanceof MissingNode ) )
153 {
154 Iterator<JsonNode> elements = responsesNode.elements( );
155 while ( elements.hasNext( ) )
156 {
157 JsonNode response = elements.next( );
158 BotMessageRenderer renderer = RendererService.getRenderer( response );
159 if ( renderer != null )
160 {
161 BotPost post = new BotPost( renderer.render( _objectMapper.convertValue( response, Map.class ) ), renderer.getPostContentType( ) );
162 listPosts.add( post );
163 }
164 }
165 }
166 else
167 {
168 JsonNode payloadNode = rootNode.path( NODE_PAYLOAD );
169 if( ! ( payloadNode instanceof MissingNode ))
170 {
171 String strText = payloadNode.get( "text" ).asText();
172 BotPost post = new BotPost( strText , BotPost.CONTENT_TYPE_TEXT );
173 listPosts.add( post );
174 }
175 }
176
177 }
178
179
180
181
182
183
184 public static ReferenceList getApiVersions( )
185 {
186 ReferenceList list = new ReferenceList( );
187 list.addItem( VERSION_1, "BotPress Converse API Version 1" );
188 return list;
189
190 }
191
192
193
194
195
196
197
198
199
200
201
202
203 public static String getBotApiEntryPointUrl( String strBotKey, String strServerUrl, int nApiVersion )
204 {
205 StringBuilder sbEntryPointUrl = new StringBuilder( );
206
207 switch( nApiVersion )
208 {
209 case VERSION_1:
210 sbEntryPointUrl.append( ( strServerUrl.endsWith( "/" ) ) ? strServerUrl : strServerUrl + "/" ).append( "api/v1/bots/" ).append( strBotKey )
211 .append( "/converse/" );
212 break;
213
214 default:
215 AppLogService.error( "Invalid Bot Press API version number : " + nApiVersion );
216 break;
217
218 }
219 return sbEntryPointUrl.toString( );
220
221 }
222
223 }