public async Task <IActionResult> Config([FromBody] IntegrationSetupRequest request) { request.AdditionalProperties.TryGetValue("voicify-app", out var voicifyAppId); request.AdditionalProperties.TryGetValue("quick-base-token", out var quickbaseToken); request.AdditionalProperties.TryGetValue("quick-base-realm", out var quickbaseRealm); // validate inputs if (string.IsNullOrEmpty(voicifyAppId)) { return(BadRequest(new[] { "You must select a Voicify app." })); } if (string.IsNullOrEmpty(quickbaseToken)) { return(BadRequest(new[] { "You must provide a user token for Quick Base." })); } if (string.IsNullOrEmpty(quickbaseRealm)) { return(BadRequest(new[] { "You must provide a Quick Base realm." })); } var voicifyConfig = new Configuration { BasePath = "https://cms.voicify.com", DefaultHeader = new Dictionary <string, string> { { "Authorization", $"Bearer {request.AccessToken}" } } }; using var client = new HttpClient(); var appProvider = new QuickBaseAppProvider(client, quickbaseRealm, quickbaseToken); var tableProvider = new QuickBaseTableProvider(client, quickbaseRealm, quickbaseToken); var fieldProvider = new QuickBaseFieldProvider(client, quickbaseRealm, quickbaseToken); var appApi = new ApplicationApi(voicifyConfig); var userApi = new UserApi(voicifyConfig); var webhookApi = new WebhookApi(voicifyConfig); var orgApi = new OrganizationApi(voicifyConfig); // get voicify org var orgs = await orgApi.GetForUserAsync(); var org = orgs.FirstOrDefault(o => o.Id == request.OrganizationId); // get voicify app var app = await appApi.FindApplicationAsync(voicifyAppId); // create quick base app var appResult = await appProvider.CreateApp(new NewQuickBaseAppRequest { AssignToken = true, Description = app.Description, Name = app.Name }); if (appResult.ResultType != ResultType.Ok) { return(BadRequest(appResult.Errors)); } // create tables var faqTableResult = await tableProvider.CreateTable(appResult.Data.Id, new NewTableRequest { Name = "Questions and Answers", Description = "Free form question and answer options", PluralRecordName = "Questions and Answers", SingleRecordName = "Question and Answer" }); if (faqTableResult.ResultType != ResultType.Ok) { return(BadRequest(faqTableResult.Errors)); } var requestTableResult = await tableProvider.CreateTable(appResult.Data.Id, new NewTableRequest { Name = "Conversational Request Data", Description = "Data from the requests made by users to the voice/bot application", PluralRecordName = "Requests", SingleRecordName = "Request" }); if (requestTableResult.ResultType != ResultType.Ok) { return(BadRequest(requestTableResult.Errors)); } // create fields for tables var results = await Task.WhenAll(new List <Task <Result <(QuickBaseField Field, string TableId)> > > { fieldProvider.CreateField(faqTableResult.Data.Id, new NewFieldRequest { Label = "question" }), fieldProvider.CreateField(faqTableResult.Data.Id, new NewFieldRequest { Label = "answer" }), fieldProvider.CreateField(faqTableResult.Data.Id, new NewFieldRequest { Label = "foregroundImageUrl" }), fieldProvider.CreateField(faqTableResult.Data.Id, new NewFieldRequest { Label = "followUpPrompt" }), fieldProvider.CreateField(faqTableResult.Data.Id, new NewFieldRequest { Label = "nextItemRecordIds" }), fieldProvider.CreateField(requestTableResult.Data.Id, new NewFieldRequest { Label = "applicationId" }), fieldProvider.CreateField(requestTableResult.Data.Id, new NewFieldRequest { Label = "requestDate" }), fieldProvider.CreateField(requestTableResult.Data.Id, new NewFieldRequest { Label = "platform" }), fieldProvider.CreateField(requestTableResult.Data.Id, new NewFieldRequest { Label = "requestId" }), fieldProvider.CreateField(requestTableResult.Data.Id, new NewFieldRequest { Label = "userId" }), fieldProvider.CreateField(requestTableResult.Data.Id, new NewFieldRequest { Label = "sessionId" }), fieldProvider.CreateField(requestTableResult.Data.Id, new NewFieldRequest { Label = "slots" }), fieldProvider.CreateField(requestTableResult.Data.Id, new NewFieldRequest { Label = "contentItemId" }), fieldProvider.CreateField(requestTableResult.Data.Id, new NewFieldRequest { Label = "featureTypeId" }), }); // create API user in voicify var apiUser = await userApi.CreateApiUserAsync(new NewApiUserRequest(request.OrganizationId)); // create token with api user credentials var token = TokenConvert.SerializeEncryptedToken(new WebhookTokenModel { VoicifyOrganizationId = org.Id, VoicifyOrganizationSecret = org.Secret, VoicifyApiUserName = apiUser.Username, VoicifyApiUserSecret = apiUser.Password, QuickBaseToken = quickbaseToken, QuickBaseRealm = quickbaseRealm, VoicifyApplicationId = voicifyAppId, QuickBaseAppId = appResult.Data.Id, QuickBaseFaqTableId = faqTableResult.Data.Id, QuickBaseRequestTableId = requestTableResult.Data.Id, QuickBaseRequestTableMatrix = results.Where(r => r.Data.TableId == requestTableResult.Data.Id) .ToDictionary( d => d.Data.Field.Label, d => d.Data.Field.Id.ToString()), QuickBaseFaqTableMatrix = results.Where(r => r.Data.TableId == faqTableResult.Data.Id) .ToDictionary( d => d.Data.Field.Label, d => d.Data.Field.Id.ToString()) }, _config.GetValue <string>("EncodingKey") ?? "whoops"); // create webhook in voicify var webhook = await webhookApi.CreateWebhookAsync(request.OrganizationId, new NewWebhookRequest( title : $"{app?.Name ?? "App"} - Quick Base Request Event", description : "Creates event records in Quick Base when a request is received through Voicify. Use this token for Quick Base pipelines as well", url : "https://quick-base-voicify-sync.azurewebsites.net/api/voicify/contentHit", webhookTypeId : "53b40ef2-769c-46e6-bc99-c709e7600c03", // Content Hit Event webhook type accessToken : token )); // add webhook to app var appWebhook = await appApi.AddWebhookAsync(voicifyAppId, webhook.Id, new WebhookParametersRequest(values : new Dictionary <string, string>(), userDefinedParameters : new Dictionary <string, string>())); return(Ok()); }