Sample 23.facebook-events (#1128)
* Initial Sample Code * remove vscode files
This commit is contained in:
Родитель
4008d1e5c0
Коммит
30ac79513a
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
|
@ -0,0 +1,91 @@
|
|||
# Facebook Events
|
||||
|
||||
Bot Framework v4 facebook events bot sample
|
||||
|
||||
This bot has been created using [Bot Framework](https://dev.botframework.com), is shows how to integrate and consume Facebook specific payloads, such as postbacks, quick replies and opt-in events. Since Bot Framework supports multiple Facebook pages for a single bot, we also show how to know the page to which the message was sent, so developers can have custom behavior per page.
|
||||
|
||||
More information about configuring a bot for Facebook Messenger can be found here: [Connect a bot to Facebook](https://docs.microsoft.com/en-us/azure/bot-service/bot-service-channel-connect-facebook)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Java 1.8+
|
||||
- Install [Maven](https://maven.apache.org/)
|
||||
- An account on [Azure](https://azure.microsoft.com) if you want to deploy to Azure.
|
||||
|
||||
## To try this sample locally
|
||||
- From the root of this project folder:
|
||||
- Build the sample using `mvn package`
|
||||
- Run it by using `java -jar .\target\facebook-events-sample.jar`
|
||||
|
||||
- Test the bot using Bot Framework Emulator
|
||||
|
||||
[Bot Framework Emulator](https://github.com/microsoft/botframework-emulator) is a desktop application that allows bot developers to test and debug their bots on localhost or running remotely through a tunnel.
|
||||
|
||||
- Install the Bot Framework Emulator version 4.3.0 or greater from [here](https://github.com/Microsoft/BotFramework-Emulator/releases)
|
||||
|
||||
- Connect to the bot using Bot Framework Emulator
|
||||
|
||||
- Launch Bot Framework Emulator
|
||||
- File -> Open Bot
|
||||
- Enter a Bot URL of `http://localhost:3978/api/messages`
|
||||
|
||||
## Deploy the bot to Azure
|
||||
|
||||
As described on [Deploy your bot](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-deploy-az-cli), you will perform the first 4 steps to setup the Azure app, then deploy the code using the azure-webapp Maven plugin.
|
||||
|
||||
### 1. Login to Azure
|
||||
From a command (or PowerShell) prompt in the root of the bot folder, execute:
|
||||
`az login`
|
||||
|
||||
### 2. Set the subscription
|
||||
`az account set --subscription "<azure-subscription>"`
|
||||
|
||||
If you aren't sure which subscription to use for deploying the bot, you can view the list of subscriptions for your account by using `az account list` command.
|
||||
|
||||
### 3. Create an App registration
|
||||
`az ad app create --display-name "<botname>" --password "<appsecret>" --available-to-other-tenants`
|
||||
|
||||
Replace `<botname>` and `<appsecret>` with your own values.
|
||||
|
||||
`<botname>` is the unique name of your bot.
|
||||
`<appsecret>` is a minimum 16 character password for your bot.
|
||||
|
||||
Record the `appid` from the returned JSON
|
||||
|
||||
### 4. Create the Azure resources
|
||||
Replace the values for `<appid>`, `<appsecret>`, `<botname>`, and `<groupname>` in the following commands:
|
||||
|
||||
#### To a new Resource Group
|
||||
`az deployment sub create --name "facebookBotDeploy" --location "westus" --template-file ".\deploymentTemplates\template-with-new-rg.json" --parameters appId="<appid>" appSecret="<appsecret>" botId="<botname>" botSku=S1 newAppServicePlanName="facebookBotPlan" newWebAppName="facebookBot" groupLocation="westus" newAppServicePlanLocation="westus"`
|
||||
|
||||
#### To an existing Resource Group
|
||||
`az deployment group create --resource-group "<groupname>" --template-file ".\deploymentTemplates\template-with-preexisting-rg.json" --parameters appId="<appid>" appSecret="<appsecret>" botId="<botname>" newWebAppName="facebookBot" newAppServicePlanName="facebookBotPlan" appServicePlanLocation="westus" --name "facebookBot"`
|
||||
|
||||
### 5. Update app id and password
|
||||
In src/main/resources/application.properties update
|
||||
- `MicrosoftAppPassword` with the botsecret value
|
||||
- `MicrosoftAppId` with the appid from the first step
|
||||
|
||||
### 6. Deploy the code
|
||||
- Execute `mvn clean package`
|
||||
- Execute `mvn azure-webapp:deploy -Dgroupname="<groupname>" -Dbotname="<botname>"`
|
||||
|
||||
If the deployment is successful, you will be able to test it via "Test in Web Chat" from the Azure Portal using the "Bot Channel Registration" for the bot.
|
||||
|
||||
After the bot is deployed, you only need to execute #6 if you make changes to the bot.
|
||||
|
||||
|
||||
## Further reading
|
||||
|
||||
- [Bot Framework Documentation](https://docs.botframework.com)
|
||||
- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0)
|
||||
- [Facebook Quick Replies](https://developers.facebook.com/docs/messenger-platform/send-messages/quick-replies/0)
|
||||
- [Facebook PostBack](https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/messaging_postbacks/)
|
||||
- [Facebook Opt-in](https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/messaging_optins/)
|
||||
- [Activity processing](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-concept-activity-processing?view=azure-bot-service-4.0)
|
||||
- [Azure Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0)
|
||||
- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0)
|
||||
- [.NET Core CLI tools](https://docs.microsoft.com/en-us/dotnet/core/tools/?tabs=netcore2x)
|
||||
- [Azure CLI](https://docs.microsoft.com/cli/azure/?view=azure-cli-latest)
|
||||
- [Azure Portal](https://portal.azure.com)
|
||||
- [Channels and Bot Connector Service](https://docs.microsoft.com/en-us/azure/bot-service/bot-concepts?view=azure-bot-service-4.0)
|
|
@ -0,0 +1,291 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"groupLocation": {
|
||||
"defaultValue": "",
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Specifies the location of the Resource Group."
|
||||
}
|
||||
},
|
||||
"groupName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Specifies the name of the Resource Group."
|
||||
}
|
||||
},
|
||||
"appId": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings."
|
||||
}
|
||||
},
|
||||
"appSecret": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings."
|
||||
}
|
||||
},
|
||||
"botId": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable."
|
||||
}
|
||||
},
|
||||
"botSku": {
|
||||
"defaultValue": "S1",
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1."
|
||||
}
|
||||
},
|
||||
"newAppServicePlanName": {
|
||||
"defaultValue": "",
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The name of the App Service Plan."
|
||||
}
|
||||
},
|
||||
"newAppServicePlanSku": {
|
||||
"type": "object",
|
||||
"defaultValue": {
|
||||
"name": "P1v2",
|
||||
"tier": "PremiumV2",
|
||||
"size": "P1v2",
|
||||
"family": "Pv2",
|
||||
"capacity": 1
|
||||
},
|
||||
"metadata": {
|
||||
"description": "The SKU of the App Service Plan. Defaults to Standard values."
|
||||
}
|
||||
},
|
||||
"newAppServicePlanLocation": {
|
||||
"defaultValue": "",
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The location of the App Service Plan. Defaults to \"westus\"."
|
||||
}
|
||||
},
|
||||
"newWebAppName": {
|
||||
"type": "string",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"."
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"appServicePlanName": "[parameters('newAppServicePlanName')]",
|
||||
"resourcesLocation": "[parameters('newAppServicePlanLocation')]",
|
||||
"webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]",
|
||||
"siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]",
|
||||
"botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]",
|
||||
"publishingUsername": "[concat('$', parameters('newWebAppName'))]",
|
||||
"resourceGroupId": "[concat(subscription().id, '/resourceGroups/', parameters('groupName'))]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"name": "[parameters('groupName')]",
|
||||
"type": "Microsoft.Resources/resourceGroups",
|
||||
"apiVersion": "2018-05-01",
|
||||
"location": "[parameters('groupLocation')]",
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Resources/deployments",
|
||||
"apiVersion": "2018-05-01",
|
||||
"name": "storageDeployment",
|
||||
"resourceGroup": "[parameters('groupName')]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"mode": "Incremental",
|
||||
"template": {
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {},
|
||||
"variables": {},
|
||||
"resources": [
|
||||
{
|
||||
"comments": "Create a new Linux App Service Plan if no existing App Service Plan name was passed in.",
|
||||
"type": "Microsoft.Web/serverfarms",
|
||||
"name": "[variables('appServicePlanName')]",
|
||||
"apiVersion": "2018-02-01",
|
||||
"location": "[variables('resourcesLocation')]",
|
||||
"sku": "[parameters('newAppServicePlanSku')]",
|
||||
"kind": "linux",
|
||||
"properties": {
|
||||
"perSiteScaling": false,
|
||||
"maximumElasticWorkerCount": 1,
|
||||
"isSpot": false,
|
||||
"reserved": true,
|
||||
"isXenon": false,
|
||||
"hyperV": false,
|
||||
"targetWorkerCount": 0,
|
||||
"targetWorkerSizeId": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"comments": "Create a Web App using a Linux App Service Plan",
|
||||
"type": "Microsoft.Web/sites",
|
||||
"apiVersion": "2018-11-01",
|
||||
"location": "[variables('resourcesLocation')]",
|
||||
"kind": "app,linux",
|
||||
"dependsOn": [
|
||||
"[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/serverfarms/', variables('appServicePlanName'))]"
|
||||
],
|
||||
"name": "[variables('webAppName')]",
|
||||
"properties": {
|
||||
"name": "[variables('webAppName')]",
|
||||
"hostNameSslStates": [
|
||||
{
|
||||
"name": "[concat(parameters('newWebAppName'), '.azurewebsites.net')]",
|
||||
"sslState": "Disabled",
|
||||
"hostType": "Standard"
|
||||
},
|
||||
{
|
||||
"name": "[concat(parameters('newWebAppName'), '.scm.azurewebsites.net')]",
|
||||
"sslState": "Disabled",
|
||||
"hostType": "Repository"
|
||||
}
|
||||
],
|
||||
"serverFarmId": "[variables('appServicePlanName')]",
|
||||
"reserved": true,
|
||||
"isXenon": false,
|
||||
"hyperV": false,
|
||||
"scmSiteAlsoStopped": false,
|
||||
"clientAffinityEnabled": true,
|
||||
"clientCertEnabled": false,
|
||||
"hostNamesDisabled": false,
|
||||
"containerSize": 0,
|
||||
"dailyMemoryTimeQuota": 0,
|
||||
"httpsOnly": false,
|
||||
"redundancyMode": "None",
|
||||
"siteConfig": {
|
||||
"appSettings": [
|
||||
{
|
||||
"name": "JAVA_OPTS",
|
||||
"value": "-Dserver.port=80"
|
||||
},
|
||||
{
|
||||
"name": "MicrosoftAppId",
|
||||
"value": "[parameters('appId')]"
|
||||
},
|
||||
{
|
||||
"name": "MicrosoftAppPassword",
|
||||
"value": "[parameters('appSecret')]"
|
||||
}
|
||||
],
|
||||
"cors": {
|
||||
"allowedOrigins": [
|
||||
"https://botservice.hosting.portal.azure.net",
|
||||
"https://hosting.onecloud.azure-test.net/"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Web/sites/config",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[concat(variables('webAppName'), '/web')]",
|
||||
"location": "[variables('resourcesLocation')]",
|
||||
"dependsOn": [
|
||||
"[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/sites/', variables('webAppName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"numberOfWorkers": 1,
|
||||
"defaultDocuments": [
|
||||
"Default.htm",
|
||||
"Default.html",
|
||||
"Default.asp",
|
||||
"index.htm",
|
||||
"index.html",
|
||||
"iisstart.htm",
|
||||
"default.aspx",
|
||||
"index.php",
|
||||
"hostingstart.html"
|
||||
],
|
||||
"netFrameworkVersion": "v4.0",
|
||||
"linuxFxVersion": "JAVA|8-jre8",
|
||||
"requestTracingEnabled": false,
|
||||
"remoteDebuggingEnabled": false,
|
||||
"httpLoggingEnabled": false,
|
||||
"logsDirectorySizeLimit": 35,
|
||||
"detailedErrorLoggingEnabled": false,
|
||||
"publishingUsername": "[variables('publishingUsername')]",
|
||||
"scmType": "None",
|
||||
"use32BitWorkerProcess": true,
|
||||
"webSocketsEnabled": false,
|
||||
"alwaysOn": true,
|
||||
"managedPipelineMode": "Integrated",
|
||||
"virtualApplications": [
|
||||
{
|
||||
"virtualPath": "/",
|
||||
"physicalPath": "site\\wwwroot",
|
||||
"preloadEnabled": true
|
||||
}
|
||||
],
|
||||
"loadBalancing": "LeastRequests",
|
||||
"experiments": {
|
||||
"rampUpRules": []
|
||||
},
|
||||
"autoHealEnabled": false,
|
||||
"localMySqlEnabled": false,
|
||||
"ipSecurityRestrictions": [
|
||||
{
|
||||
"ipAddress": "Any",
|
||||
"action": "Allow",
|
||||
"priority": 1,
|
||||
"name": "Allow all",
|
||||
"description": "Allow all access"
|
||||
}
|
||||
],
|
||||
"scmIpSecurityRestrictions": [
|
||||
{
|
||||
"ipAddress": "Any",
|
||||
"action": "Allow",
|
||||
"priority": 1,
|
||||
"name": "Allow all",
|
||||
"description": "Allow all access"
|
||||
}
|
||||
],
|
||||
"scmIpSecurityRestrictionsUseMain": false,
|
||||
"http20Enabled": false,
|
||||
"minTlsVersion": "1.2",
|
||||
"ftpsState": "AllAllowed",
|
||||
"reservedInstanceCount": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2017-12-01",
|
||||
"type": "Microsoft.BotService/botServices",
|
||||
"name": "[parameters('botId')]",
|
||||
"location": "global",
|
||||
"kind": "bot",
|
||||
"sku": {
|
||||
"name": "[parameters('botSku')]"
|
||||
},
|
||||
"properties": {
|
||||
"name": "[parameters('botId')]",
|
||||
"displayName": "[parameters('botId')]",
|
||||
"endpoint": "[variables('botEndpoint')]",
|
||||
"msaAppId": "[parameters('appId')]",
|
||||
"developerAppInsightsApplicationId": null,
|
||||
"developerAppInsightKey": null,
|
||||
"publishingCredentials": null,
|
||||
"storageResourceId": null
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/sites/', variables('webAppName'))]"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,259 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"appId": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings."
|
||||
}
|
||||
},
|
||||
"appSecret": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Defaults to \"\"."
|
||||
}
|
||||
},
|
||||
"botId": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable."
|
||||
}
|
||||
},
|
||||
"botSku": {
|
||||
"defaultValue": "S1",
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1."
|
||||
}
|
||||
},
|
||||
"newAppServicePlanName": {
|
||||
"type": "string",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "The name of the new App Service Plan."
|
||||
}
|
||||
},
|
||||
"newAppServicePlanSku": {
|
||||
"type": "object",
|
||||
"defaultValue": {
|
||||
"name": "P1v2",
|
||||
"tier": "PremiumV2",
|
||||
"size": "P1v2",
|
||||
"family": "Pv2",
|
||||
"capacity": 1
|
||||
},
|
||||
"metadata": {
|
||||
"description": "The SKU of the App Service Plan. Defaults to Standard values."
|
||||
}
|
||||
},
|
||||
"appServicePlanLocation": {
|
||||
"type": "string",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "The location of the App Service Plan."
|
||||
}
|
||||
},
|
||||
"existingAppServicePlan": {
|
||||
"type": "string",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "Name of the existing App Service Plan used to create the Web App for the bot."
|
||||
}
|
||||
},
|
||||
"newWebAppName": {
|
||||
"type": "string",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"."
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"defaultAppServicePlanName": "[if(empty(parameters('existingAppServicePlan')), 'createNewAppServicePlan', parameters('existingAppServicePlan'))]",
|
||||
"useExistingAppServicePlan": "[not(equals(variables('defaultAppServicePlanName'), 'createNewAppServicePlan'))]",
|
||||
"servicePlanName": "[if(variables('useExistingAppServicePlan'), parameters('existingAppServicePlan'), parameters('newAppServicePlanName'))]",
|
||||
"publishingUsername": "[concat('$', parameters('newWebAppName'))]",
|
||||
"resourcesLocation": "[parameters('appServicePlanLocation')]",
|
||||
"webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]",
|
||||
"siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]",
|
||||
"botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"comments": "Create a new Linux App Service Plan if no existing App Service Plan name was passed in.",
|
||||
"type": "Microsoft.Web/serverfarms",
|
||||
"condition": "[not(variables('useExistingAppServicePlan'))]",
|
||||
"name": "[variables('servicePlanName')]",
|
||||
"apiVersion": "2018-02-01",
|
||||
"location": "[variables('resourcesLocation')]",
|
||||
"sku": "[parameters('newAppServicePlanSku')]",
|
||||
"kind": "linux",
|
||||
"properties": {
|
||||
"perSiteScaling": false,
|
||||
"maximumElasticWorkerCount": 1,
|
||||
"isSpot": false,
|
||||
"reserved": true,
|
||||
"isXenon": false,
|
||||
"hyperV": false,
|
||||
"targetWorkerCount": 0,
|
||||
"targetWorkerSizeId": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"comments": "Create a Web App using a Linux App Service Plan",
|
||||
"type": "Microsoft.Web/sites",
|
||||
"apiVersion": "2018-11-01",
|
||||
"location": "[variables('resourcesLocation')]",
|
||||
"kind": "app,linux",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]"
|
||||
],
|
||||
"name": "[variables('webAppName')]",
|
||||
"properties": {
|
||||
"name": "[variables('webAppName')]",
|
||||
"hostNameSslStates": [
|
||||
{
|
||||
"name": "[concat(parameters('newWebAppName'), '.azurewebsites.net')]",
|
||||
"sslState": "Disabled",
|
||||
"hostType": "Standard"
|
||||
},
|
||||
{
|
||||
"name": "[concat(parameters('newWebAppName'), '.scm.azurewebsites.net')]",
|
||||
"sslState": "Disabled",
|
||||
"hostType": "Repository"
|
||||
}
|
||||
],
|
||||
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]",
|
||||
"reserved": true,
|
||||
"isXenon": false,
|
||||
"hyperV": false,
|
||||
"scmSiteAlsoStopped": false,
|
||||
"clientAffinityEnabled": true,
|
||||
"clientCertEnabled": false,
|
||||
"hostNamesDisabled": false,
|
||||
"containerSize": 0,
|
||||
"dailyMemoryTimeQuota": 0,
|
||||
"httpsOnly": false,
|
||||
"redundancyMode": "None",
|
||||
"siteConfig": {
|
||||
"appSettings": [
|
||||
{
|
||||
"name": "JAVA_OPTS",
|
||||
"value": "-Dserver.port=80"
|
||||
},
|
||||
{
|
||||
"name": "MicrosoftAppId",
|
||||
"value": "[parameters('appId')]"
|
||||
},
|
||||
{
|
||||
"name": "MicrosoftAppPassword",
|
||||
"value": "[parameters('appSecret')]"
|
||||
}
|
||||
],
|
||||
"cors": {
|
||||
"allowedOrigins": [
|
||||
"https://botservice.hosting.portal.azure.net",
|
||||
"https://hosting.onecloud.azure-test.net/"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Web/sites/config",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[concat(variables('webAppName'), '/web')]",
|
||||
"location": "[variables('resourcesLocation')]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Web/sites/', variables('webAppName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"numberOfWorkers": 1,
|
||||
"defaultDocuments": [
|
||||
"Default.htm",
|
||||
"Default.html",
|
||||
"Default.asp",
|
||||
"index.htm",
|
||||
"index.html",
|
||||
"iisstart.htm",
|
||||
"default.aspx",
|
||||
"index.php",
|
||||
"hostingstart.html"
|
||||
],
|
||||
"netFrameworkVersion": "v4.0",
|
||||
"linuxFxVersion": "JAVA|8-jre8",
|
||||
"requestTracingEnabled": false,
|
||||
"remoteDebuggingEnabled": false,
|
||||
"httpLoggingEnabled": false,
|
||||
"logsDirectorySizeLimit": 35,
|
||||
"detailedErrorLoggingEnabled": false,
|
||||
"publishingUsername": "[variables('publishingUsername')]",
|
||||
"scmType": "None",
|
||||
"use32BitWorkerProcess": true,
|
||||
"webSocketsEnabled": false,
|
||||
"alwaysOn": true,
|
||||
"managedPipelineMode": "Integrated",
|
||||
"virtualApplications": [
|
||||
{
|
||||
"virtualPath": "/",
|
||||
"physicalPath": "site\\wwwroot",
|
||||
"preloadEnabled": true
|
||||
}
|
||||
],
|
||||
"loadBalancing": "LeastRequests",
|
||||
"experiments": {
|
||||
"rampUpRules": []
|
||||
},
|
||||
"autoHealEnabled": false,
|
||||
"localMySqlEnabled": false,
|
||||
"ipSecurityRestrictions": [
|
||||
{
|
||||
"ipAddress": "Any",
|
||||
"action": "Allow",
|
||||
"priority": 1,
|
||||
"name": "Allow all",
|
||||
"description": "Allow all access"
|
||||
}
|
||||
],
|
||||
"scmIpSecurityRestrictions": [
|
||||
{
|
||||
"ipAddress": "Any",
|
||||
"action": "Allow",
|
||||
"priority": 1,
|
||||
"name": "Allow all",
|
||||
"description": "Allow all access"
|
||||
}
|
||||
],
|
||||
"scmIpSecurityRestrictionsUseMain": false,
|
||||
"http20Enabled": false,
|
||||
"minTlsVersion": "1.2",
|
||||
"ftpsState": "AllAllowed",
|
||||
"reservedInstanceCount": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2017-12-01",
|
||||
"type": "Microsoft.BotService/botServices",
|
||||
"name": "[parameters('botId')]",
|
||||
"location": "global",
|
||||
"kind": "bot",
|
||||
"sku": {
|
||||
"name": "[parameters('botSku')]"
|
||||
},
|
||||
"properties": {
|
||||
"name": "[parameters('botId')]",
|
||||
"displayName": "[parameters('botId')]",
|
||||
"endpoint": "[variables('botEndpoint')]",
|
||||
"msaAppId": "[parameters('appId')]",
|
||||
"developerAppInsightsApplicationId": null,
|
||||
"developerAppInsightKey": null,
|
||||
"publishingCredentials": null,
|
||||
"storageResourceId": null
|
||||
},
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Web/sites/', variables('webAppName'))]"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.microsoft.bot.sample</groupId>
|
||||
<artifactId>facebook-events</artifactId>
|
||||
<version>sample</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.groupId}:${project.artifactId}</name>
|
||||
<description>This package contains a Java Facebook Events sample using Spring Boot.</description>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.4.0</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>MIT License</name>
|
||||
<url>http://www.opensource.org/licenses/mit-license.php</url>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<name>Bot Framework Development</name>
|
||||
<email></email>
|
||||
<organization>Microsoft</organization>
|
||||
<organizationUrl>https://dev.botframework.com/</organizationUrl>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<start-class>com.microsoft.bot.sample.facebookevents.Application</start-class>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<version>2.4.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>2.11.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.13.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.bot</groupId>
|
||||
<artifactId>bot-integration-spring</artifactId>
|
||||
<version>4.6.0-preview9</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.bot</groupId>
|
||||
<artifactId>bot-dialogs</artifactId>
|
||||
<version>4.6.0-preview9</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>build</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>3.2.3</version>
|
||||
<configuration>
|
||||
<warSourceDirectory>src/main/webapp</warSourceDirectory>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<mainClass>com.microsoft.bot.sample.facebookevents.Application</mainClass>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.microsoft.azure</groupId>
|
||||
<artifactId>azure-webapp-maven-plugin</artifactId>
|
||||
<version>1.12.0</version>
|
||||
<configuration>
|
||||
<schemaVersion>V2</schemaVersion>
|
||||
<resourceGroup>${groupname}</resourceGroup>
|
||||
<appName>${botname}</appName>
|
||||
<appSettings>
|
||||
<property>
|
||||
<name>JAVA_OPTS</name>
|
||||
<value>-Dserver.port=80</value>
|
||||
</property>
|
||||
</appSettings>
|
||||
<runtime>
|
||||
<os>linux</os>
|
||||
<javaVersion>Java 8</javaVersion>
|
||||
<webContainer>Java SE</webContainer>
|
||||
</runtime>
|
||||
<deployment>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${project.basedir}/target</directory>
|
||||
<includes>
|
||||
<include>*.jar</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
</deployment>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>publish</id>
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>3.2.3</version>
|
||||
<configuration>
|
||||
<warSourceDirectory>src/main/webapp</warSourceDirectory>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.sonatype.plugins</groupId>
|
||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||
<version>1.6.8</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<skipRemoteStaging>true</skipRemoteStaging>
|
||||
<serverId>ossrh</serverId>
|
||||
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
|
||||
<autoReleaseAfterClose>true</autoReleaseAfterClose>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>8</source>
|
||||
<failOnError>false</failOnError>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
|
@ -0,0 +1,67 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.sample.facebookevents;
|
||||
|
||||
import com.microsoft.bot.builder.Bot;
|
||||
import com.microsoft.bot.integration.AdapterWithErrorHandler;
|
||||
import com.microsoft.bot.integration.BotFrameworkHttpAdapter;
|
||||
import com.microsoft.bot.integration.Configuration;
|
||||
import com.microsoft.bot.integration.spring.BotController;
|
||||
import com.microsoft.bot.integration.spring.BotDependencyConfiguration;
|
||||
import com.microsoft.bot.sample.facebookevents.bot.FacebookBot;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
//
|
||||
// This is the starting point of the Sprint Boot Bot application.
|
||||
//
|
||||
@SpringBootApplication
|
||||
|
||||
// Use the default BotController to receive incoming Channel messages. A custom
|
||||
// controller could be used by eliminating this import and creating a new
|
||||
// org.springframework.web.bind.annotation.RestController.
|
||||
// The default controller is created by the Spring Boot container using
|
||||
// dependency injection. The default route is /api/messages.
|
||||
@Import({BotController.class})
|
||||
|
||||
/**
|
||||
* This class extends the BotDependencyConfiguration which provides the default
|
||||
* implementations for a Bot application. The Application class should
|
||||
* override methods in order to provide custom implementations.
|
||||
*/
|
||||
public class Application extends BotDependencyConfiguration {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Bot for this application.
|
||||
*
|
||||
* <p>
|
||||
* The @Component annotation could be used on the Bot class instead of this method
|
||||
* with the @Bean annotation.
|
||||
* </p>
|
||||
*
|
||||
* @return The Bot implementation for this application.
|
||||
*/
|
||||
@Bean
|
||||
public Bot getBot() {
|
||||
return new FacebookBot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a custom Adapter that provides error handling.
|
||||
*
|
||||
* @param configuration The Configuration object to use.
|
||||
* @return An error handling BotFrameworkHttpAdapter.
|
||||
*/
|
||||
@Override
|
||||
public BotFrameworkHttpAdapter getBotFrameworkHttpAdaptor(Configuration configuration) {
|
||||
return new AdapterWithErrorHandler(configuration);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,253 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.sample.facebookevents.bot;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.microsoft.bot.builder.ActivityHandler;
|
||||
import com.microsoft.bot.builder.MessageFactory;
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
import com.microsoft.bot.connector.Channels;
|
||||
import com.microsoft.bot.dialogs.choices.Choice;
|
||||
import com.microsoft.bot.dialogs.choices.ChoiceFactory;
|
||||
import com.microsoft.bot.sample.facebookevents.facebookmodel.FacebookMessage;
|
||||
import com.microsoft.bot.sample.facebookevents.facebookmodel.FacebookOptin;
|
||||
import com.microsoft.bot.sample.facebookevents.facebookmodel.FacebookPayload;
|
||||
import com.microsoft.bot.sample.facebookevents.facebookmodel.FacebookPostback;
|
||||
import com.microsoft.bot.sample.facebookevents.facebookmodel.FacebookQuickReply;
|
||||
import com.microsoft.bot.schema.ActionTypes;
|
||||
import com.microsoft.bot.schema.Activity;
|
||||
import com.microsoft.bot.schema.CardAction;
|
||||
import com.microsoft.bot.schema.HeroCard;
|
||||
import com.microsoft.bot.schema.Serialization;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* This class implements the functionality of the Bot.
|
||||
*/
|
||||
public class FacebookBot extends ActivityHandler {
|
||||
|
||||
// These are the options provided to the user when they message the bot
|
||||
final String FacebookPageIdOption = "Facebook Id";
|
||||
final String QuickRepliesOption = "Quick Replies";
|
||||
final String PostBackOption = "PostBack";
|
||||
|
||||
protected final Logger Logger;
|
||||
|
||||
public FacebookBot() {
|
||||
Logger = LoggerFactory.getLogger(FacebookBot.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompletableFuture<Void> onMessageActivity(TurnContext turnContext) {
|
||||
Logger.info("Processing a Message Activity.");
|
||||
|
||||
// Show choices if the Facebook Payload from ChannelData instanceof not handled
|
||||
try {
|
||||
return processFacebookPayload(turnContext, turnContext.getActivity().getChannelData())
|
||||
.thenCompose(result -> {
|
||||
if (result == false) {
|
||||
return showChoices(turnContext);
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
});
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompletableFuture<Void> onEventActivity(TurnContext turnContext) {
|
||||
Logger.info("Processing an Event Activity.");
|
||||
|
||||
// Analyze Facebook payload from EventActivity.Value
|
||||
try {
|
||||
return processFacebookPayload(turnContext, turnContext.getActivity().getValue()).thenApply(result -> null);
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> showChoices(TurnContext turnContext) {
|
||||
// Create choices for the prompt
|
||||
List<Choice> choices = new ArrayList<Choice>();
|
||||
|
||||
Choice firstChoice = new Choice();
|
||||
firstChoice.setValue(QuickRepliesOption);
|
||||
CardAction firstChoiceCardAction = new CardAction();
|
||||
firstChoiceCardAction.setTitle(QuickRepliesOption);
|
||||
firstChoiceCardAction.setType(ActionTypes.POST_BACK);
|
||||
firstChoiceCardAction.setValue(QuickRepliesOption);
|
||||
firstChoice.setAction(firstChoiceCardAction);
|
||||
choices.add(firstChoice);
|
||||
|
||||
Choice secondChoice = new Choice();
|
||||
firstChoice.setValue(FacebookPageIdOption);
|
||||
CardAction secondChoiceCardAction = new CardAction();
|
||||
secondChoiceCardAction.setTitle(FacebookPageIdOption);
|
||||
secondChoiceCardAction.setType(ActionTypes.POST_BACK);
|
||||
secondChoiceCardAction.setValue(FacebookPageIdOption);
|
||||
secondChoice.setAction(secondChoiceCardAction);
|
||||
choices.add(secondChoice);
|
||||
|
||||
Choice thirdChoice = new Choice();
|
||||
firstChoice.setValue(PostBackOption);
|
||||
CardAction thirdChoiceCardAction = new CardAction();
|
||||
thirdChoiceCardAction.setTitle(PostBackOption);
|
||||
thirdChoiceCardAction.setType(ActionTypes.POST_BACK);
|
||||
thirdChoiceCardAction.setValue(PostBackOption);
|
||||
thirdChoice.setAction(thirdChoiceCardAction);
|
||||
|
||||
choices.add(thirdChoice);
|
||||
|
||||
// Create the prompt message
|
||||
Activity message = ChoiceFactory.forChannel(
|
||||
turnContext.getActivity().getChannelId(),
|
||||
choices,
|
||||
"What Facebook feature would you like to try? Here are some quick replies to choose from!"
|
||||
);
|
||||
return turnContext.sendActivity(message).thenApply(result -> null);
|
||||
}
|
||||
|
||||
|
||||
private CompletableFuture<Boolean> processFacebookPayload(
|
||||
TurnContext turnContext,
|
||||
Object data
|
||||
) throws JsonProcessingException {
|
||||
// At this point we know we are on Facebook channel, and can consume the
|
||||
// Facebook custom payload
|
||||
// present in channelData.
|
||||
try {
|
||||
FacebookPayload facebookPayload = Serialization.safeGetAs(data, FacebookPayload.class);
|
||||
|
||||
if (facebookPayload != null) {
|
||||
// PostBack
|
||||
if (facebookPayload.getPostBack() != null) {
|
||||
return onFacebookPostBack(turnContext, facebookPayload.getPostBack()).thenApply(result -> true);
|
||||
} else if (facebookPayload.getOptin() != null) {
|
||||
// Optin
|
||||
return onFacebookOptin(turnContext, facebookPayload.getOptin()).thenApply(result -> true);
|
||||
} else if (
|
||||
facebookPayload.getMessage() != null && facebookPayload.getMessage().getQuickReply() != null
|
||||
) {
|
||||
// Quick reply
|
||||
return onFacebookQuickReply(turnContext, facebookPayload.getMessage().getQuickReply())
|
||||
.thenApply(result -> true);
|
||||
} else if (facebookPayload.getMessage() != null && facebookPayload.getMessage().getIsEcho()) {
|
||||
// Echo
|
||||
return onFacebookEcho(turnContext, facebookPayload.getMessage()).thenApply(result -> true);
|
||||
} else {
|
||||
return turnContext.sendActivity("This sample is intended to be used with a Facebook bot.")
|
||||
.thenApply(result -> false);
|
||||
}
|
||||
|
||||
// TODO: Handle other events that you're interested in...
|
||||
}
|
||||
} catch (JsonProcessingException ex) {
|
||||
if (turnContext.getActivity().getChannelId() != Channels.FACEBOOK) {
|
||||
turnContext.sendActivity("This sample is intended to be used with a Facebook bot.");
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
|
||||
protected CompletableFuture<Void> onFacebookOptin(TurnContext turnContext, FacebookOptin optin) {
|
||||
Logger.info("Optin message received.");
|
||||
|
||||
// TODO: Your optin event handling logic here...
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
protected CompletableFuture<Void> onFacebookEcho(TurnContext turnContext, FacebookMessage facebookMessage) {
|
||||
Logger.info("Echo message received.");
|
||||
|
||||
// TODO: Your echo event handling logic here...
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
protected CompletableFuture<Void> onFacebookPostBack(TurnContext turnContext, FacebookPostback postBack) {
|
||||
Logger.info("PostBack message received.");
|
||||
|
||||
// TODO: Your PostBack handling logic here...
|
||||
|
||||
// Answer the postback, and show choices
|
||||
Activity reply = MessageFactory.text("Are you sure?");
|
||||
return turnContext.sendActivity(reply).thenCompose(result -> {
|
||||
return showChoices(turnContext);
|
||||
});
|
||||
}
|
||||
|
||||
protected CompletableFuture<Void> onFacebookQuickReply(TurnContext turnContext, FacebookQuickReply quickReply) {
|
||||
Logger.info("QuickReply message received.");
|
||||
|
||||
// TODO: Your quick reply event handling logic here...
|
||||
|
||||
// Process the message by checking the Activity.getText(). The
|
||||
// FacebookQuickReply could also contain a json payload.
|
||||
|
||||
// Initially the bot offers to showcase 3 Facebook features: Quick replies,
|
||||
// PostBack and getting the Facebook Page Name.
|
||||
switch (turnContext.getActivity().getText()) {
|
||||
// Here we showcase how to obtain the Facebook page id.
|
||||
// This can be useful for the Facebook multi-page support provided by the Bot
|
||||
// Framework.
|
||||
// The Facebook page id from which the message comes from instanceof in
|
||||
// turnContext.getActivity().getRecipient().getId().
|
||||
case FacebookPageIdOption: {
|
||||
Activity reply = MessageFactory.text(
|
||||
String.format(
|
||||
"This message comes from the following Facebook Page: %s",
|
||||
turnContext.getActivity().getRecipient().getId()
|
||||
)
|
||||
);
|
||||
return turnContext.sendActivity(reply).thenCompose(result -> {
|
||||
return showChoices(turnContext);
|
||||
});
|
||||
}
|
||||
|
||||
// Here we send a HeroCard with 2 options that will trigger a Facebook PostBack.
|
||||
case PostBackOption: {
|
||||
HeroCard card = new HeroCard();
|
||||
card.setText("Is 42 the answer to the ultimate question of Life, the Universe, and Everything?");
|
||||
|
||||
List<CardAction> buttons = new ArrayList<CardAction>();
|
||||
|
||||
CardAction yesAction = new CardAction();
|
||||
yesAction.setTitle("Yes");
|
||||
yesAction.setType(ActionTypes.POST_BACK);
|
||||
yesAction.setValue("Yes");
|
||||
buttons.add(yesAction);
|
||||
|
||||
CardAction noAction = new CardAction();
|
||||
noAction.setTitle("No");
|
||||
noAction.setType(ActionTypes.POST_BACK);
|
||||
noAction.setValue("No");
|
||||
buttons.add(noAction);
|
||||
|
||||
card.setButtons(buttons);
|
||||
|
||||
Activity reply = MessageFactory.attachment(card.toAttachment());
|
||||
return turnContext.sendActivity(reply).thenApply(result -> null);
|
||||
}
|
||||
|
||||
// By default we offer the users different actions that the bot supports,
|
||||
// through quick replies.
|
||||
case QuickRepliesOption:
|
||||
default: {
|
||||
return showChoices(turnContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MT License.
|
||||
|
||||
|
||||
package com.microsoft.bot.sample.facebookevents.facebookmodel;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class FacebookMessage {
|
||||
|
||||
@JsonProperty(value = "mid")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private String messageId;
|
||||
|
||||
@JsonProperty(value = "text")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private String text;
|
||||
|
||||
@JsonProperty(value = "is_echo")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private boolean isEcho;
|
||||
|
||||
@JsonProperty(value = "quick_reply")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private FacebookQuickReply quickReply;
|
||||
|
||||
/**
|
||||
* Gets the message Id from Facebook.
|
||||
* @return the MessageId value as a String.
|
||||
*/
|
||||
public String getMessageId() {
|
||||
return this.messageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message Id from Facebook.
|
||||
* @param withMessageId The MessageId value.
|
||||
*/
|
||||
public void setMessageId(String withMessageId) {
|
||||
this.messageId = withMessageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message text.
|
||||
* @return the Text value as a String.
|
||||
*/
|
||||
public String getText() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message text.
|
||||
* @param withText The Text value.
|
||||
*/
|
||||
public void setText(String withText) {
|
||||
this.text = withText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the message is an echo message. See
|
||||
* {@link
|
||||
* https://developers#facebook#com/docs/messenger-platform/reference/webhook-events/message-echoes/} Echo Message
|
||||
* @return the IsEcho value as a boolean.
|
||||
*/
|
||||
public boolean getIsEcho() {
|
||||
return this.isEcho;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the message is an echo message. See
|
||||
* {@link
|
||||
* https://developers#facebook#com/docs/messenger-platform/reference/webhook-events/message-echoes/} Echo Message
|
||||
* @param withIsEcho The IsEcho value.
|
||||
*/
|
||||
public void setIsEcho(boolean withIsEcho) {
|
||||
this.isEcho = withIsEcho;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the quick reply.
|
||||
* @return the QuickReply value as a FacebookQuickReply.
|
||||
*/
|
||||
public FacebookQuickReply getQuickReply() {
|
||||
return this.quickReply;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the quick reply.
|
||||
* @param withQuickReply The QuickReply value.
|
||||
*/
|
||||
public void setQuickReply(FacebookQuickReply withQuickReply) {
|
||||
this.quickReply = withQuickReply;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MT License.
|
||||
|
||||
package com.microsoft.bot.sample.facebookevents.facebookmodel;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* A Facebook optin event payload definition.
|
||||
*
|
||||
* See https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/messaging_optins/
|
||||
* for more information on messaging_optin.
|
||||
*/
|
||||
public class FacebookOptin {
|
||||
|
||||
@JsonProperty(value = "ref")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private String ref;
|
||||
|
||||
@JsonProperty(value = "user_ref")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private String userRef;
|
||||
|
||||
/**
|
||||
* Gets the optin data ref.
|
||||
* @return the Ref value as a String.
|
||||
*/
|
||||
public String getRef() {
|
||||
return this.ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the optin data ref.
|
||||
* @param withRef The Ref value.
|
||||
*/
|
||||
public void setRef(String withRef) {
|
||||
this.ref = withRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the optin user ref.
|
||||
* @return the UserRef value as a String.
|
||||
*/
|
||||
public String getUserRef() {
|
||||
return this.userRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the optin user ref.
|
||||
* @param withUserRef The UserRef value.
|
||||
*/
|
||||
public void setUserRef(String withUserRef) {
|
||||
this.userRef = withUserRef;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MT License.
|
||||
|
||||
package com.microsoft.bot.sample.facebookevents.facebookmodel;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Simple version of the payload received from the Facebook channel.
|
||||
*/
|
||||
public class FacebookPayload {
|
||||
|
||||
@JsonProperty(value = "sender")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private FacebookSender sender;
|
||||
|
||||
@JsonProperty(value = "recipient")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private FacebookRecipient recipient;
|
||||
|
||||
@JsonProperty(value = "message")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private FacebookMessage message;
|
||||
|
||||
@JsonProperty(value = "postback")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private FacebookPostback postBack;
|
||||
|
||||
@JsonProperty(value = "optin")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private FacebookOptin optin;
|
||||
|
||||
/**
|
||||
* Gets the sender of the message.
|
||||
* @return the Sender value as a FacebookSender.
|
||||
*/
|
||||
public FacebookSender getSender() {
|
||||
return this.sender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the sender of the message.
|
||||
* @param withSender The Sender value.
|
||||
*/
|
||||
public void setSender(FacebookSender withSender) {
|
||||
this.sender = withSender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the recipient of the message.
|
||||
* @return the Recipient value as a FacebookRecipient.
|
||||
*/
|
||||
public FacebookRecipient getRecipient() {
|
||||
return this.recipient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the recipient of the message.
|
||||
* @param withRecipient The Recipient value.
|
||||
*/
|
||||
public void setRecipient(FacebookRecipient withRecipient) {
|
||||
this.recipient = withRecipient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message.
|
||||
* @return the Message value as a FacebookMessage.
|
||||
*/
|
||||
public FacebookMessage getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message.
|
||||
* @param withMessage The Message value.
|
||||
*/
|
||||
public void setMessage(FacebookMessage withMessage) {
|
||||
this.message = withMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the postback payload if available.
|
||||
* @return the PostBack value as a FacebookPostback.
|
||||
*/
|
||||
public FacebookPostback getPostBack() {
|
||||
return this.postBack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the postback payload if available.
|
||||
* @param withPostBack The PostBack value.
|
||||
*/
|
||||
public void setPostBack(FacebookPostback withPostBack) {
|
||||
this.postBack = withPostBack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the optin payload if available.
|
||||
* @return the Optin value as a FacebookOptin.
|
||||
*/
|
||||
public FacebookOptin getOptin() {
|
||||
return this.optin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the optin payload if available.
|
||||
* @param withOptin The Optin value.
|
||||
*/
|
||||
public void setOptin(FacebookOptin withOptin) {
|
||||
this.optin = withOptin;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MT License.
|
||||
|
||||
package com.microsoft.bot.sample.facebookevents.facebookmodel;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Definition for Facebook PostBack payload. Present on calls
|
||||
* frommessaging_postback webhook event.
|
||||
*
|
||||
* See
|
||||
* {@link
|
||||
* https://developers#getfacebook()#com/docs/messenger-platform/reference/webhook-events/messaging_postbacks/}
|
||||
* Facebook messaging_postback
|
||||
*/
|
||||
public class FacebookPostback {
|
||||
|
||||
@JsonProperty(value = "payload")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private String payload;
|
||||
|
||||
@JsonProperty(value = "title")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* Gets payload of the PostBack. Could be an Object depending on
|
||||
* the Object sent.
|
||||
* @return the Payload value as a String.
|
||||
*/
|
||||
public String getPayload() {
|
||||
return this.payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets payload of the PostBack. Could be an Object depending on
|
||||
* the Object sent.
|
||||
* @param withPayload The Payload value.
|
||||
*/
|
||||
public void setPayload(String withPayload) {
|
||||
this.payload = withPayload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the title of the postback.
|
||||
* @return the Title value as a String.
|
||||
*/
|
||||
public String getTitle() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title of the postback.
|
||||
* @param withTitle The Title value.
|
||||
*/
|
||||
public void setTitle(String withTitle) {
|
||||
this.title = withTitle;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MT License.
|
||||
|
||||
package com.microsoft.bot.sample.facebookevents.facebookmodel;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* A Facebook quick reply.
|
||||
*
|
||||
* See
|
||||
* {@link
|
||||
* https://developers#getfacebook()#com/docs/messenger-platform/send-messages/quick-replies/}
|
||||
* Quick Replies Facebook Documentation
|
||||
*/
|
||||
public class FacebookQuickReply {
|
||||
|
||||
@JsonProperty(value = "payload")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private String payload;
|
||||
|
||||
/**
|
||||
* @return the Payload value as a String.
|
||||
*/
|
||||
public String getPayload() {
|
||||
return this.payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param withPayload The Payload value.
|
||||
*/
|
||||
public void setPayload(String withPayload) {
|
||||
this.payload = withPayload;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MT License.
|
||||
|
||||
package com.microsoft.bot.sample.facebookevents.facebookmodel;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Defines a Facebook recipient.
|
||||
*/
|
||||
public class FacebookRecipient {
|
||||
|
||||
@JsonProperty(value = "id")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* The Facebook Id of the recipient.
|
||||
* @return the Id value as a String.
|
||||
*/
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Facebook Id of the recipient.
|
||||
* @param withId The Id value.
|
||||
*/
|
||||
public void setId(String withId) {
|
||||
this.id = withId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MT License.
|
||||
|
||||
package com.microsoft.bot.sample.facebookevents.facebookmodel;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Defines a Facebook sender.
|
||||
*/
|
||||
public class FacebookSender {
|
||||
|
||||
@JsonProperty(value = "id")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* The Facebook Id of the sender.
|
||||
* @return the Id value as a String.
|
||||
*/
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Facebook Id of the sender.
|
||||
* @param withId The Id value.
|
||||
*/
|
||||
public void setId(String withId) {
|
||||
this.id = withId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
MicrosoftAppId=7455f666-b11d-4ce8-8c81-36370eaae99a
|
||||
MicrosoftAppPassword=1G_Rv.yT8eDjg.2nd6S6j0__HGxN5T.epz
|
||||
server.port=3978
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"configuration": {
|
||||
"name": "Default",
|
||||
"appenders": {
|
||||
"Console": {
|
||||
"name": "Console-Appender",
|
||||
"target": "SYSTEM_OUT",
|
||||
"PatternLayout": {"pattern": "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"}
|
||||
}
|
||||
},
|
||||
"loggers": {
|
||||
"root": {
|
||||
"level": "debug",
|
||||
"appender-ref": {"ref": "Console-Appender","level": "debug"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
Manifest-Version: 1.0
|
||||
Class-Path:
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<servlet>
|
||||
<servlet-name>dispatcher</servlet-name>
|
||||
<servlet-class>
|
||||
org.springframework.web.servlet.DispatcherServlet
|
||||
</servlet-class>
|
||||
<init-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
|
@ -0,0 +1,418 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>EchoBot</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
font-family: Segoe UI;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
header {
|
||||
background-image: url("data:image/svg+xml,%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 4638.9 651.6' style='enable-background:new 0 0 4638.9 651.6;' xml:space='preserve'%3E%3Cstyle type='text/css'%3E .st0%7Bfill:%2355A0E0;%7D .st1%7Bfill:none;%7D .st2%7Bfill:%230058A8;%7D .st3%7Bfill:%23328BD8;%7D .st4%7Bfill:%23B6DCF1;%7D .st5%7Bopacity:0.2;fill:url(%23SVGID_1_);enable-background:new ;%7D%0A%3C/style%3E%3Crect y='1.1' class='st0' width='4640' height='646.3'/%3E%3Cpath class='st1' d='M3987.8,323.6L4310.3,1.1h-65.6l-460.1,460.1c-17.5,17.5-46.1,17.5-63.6,0L3260.9,1.1H0v646.3h3660.3 L3889,418.7c17.5-17.5,46.1-17.5,63.6,0l228.7,228.7h66.6l-260.2-260.2C3970.3,369.8,3970.3,341.1,3987.8,323.6z'/%3E%3Cpath class='st2' d='M3784.6,461.2L4244.7,1.1h-983.9l460.1,460.1C3738.4,478.7,3767.1,478.7,3784.6,461.2z'/%3E%3Cpath class='st3' d='M4640,1.1h-329.8l-322.5,322.5c-17.5,17.5-17.5,46.1,0,63.6l260.2,260.2H4640L4640,1.1L4640,1.1z'/%3E%3Cpath class='st4' d='M3889,418.8l-228.7,228.7h521.1l-228.7-228.7C3935.2,401.3,3906.5,401.3,3889,418.8z'/%3E%3ClinearGradient id='SVGID_1_' gradientUnits='userSpaceOnUse' x1='3713.7576' y1='438.1175' x2='3911.4084' y2='14.2535' gradientTransform='matrix(1 0 0 -1 0 641.3969)'%3E%3Cstop offset='0' style='stop-color:%23FFFFFF;stop-opacity:0.5'/%3E%3Cstop offset='1' style='stop-color:%23FFFFFF'/%3E%3C/linearGradient%3E%3Cpath class='st5' d='M3952.7,124.5c-17.5-17.5-46.1-17.5-63.6,0l-523,523h1109.6L3952.7,124.5z'/%3E%3C/svg%3E%0A");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100%;
|
||||
background-position: right;
|
||||
background-color: #55A0E0;
|
||||
width: 100%;
|
||||
font-size: 44px;
|
||||
height: 120px;
|
||||
color: white;
|
||||
padding: 30px 0 40px 0px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
background-image: url("data:image/svg+xml;utf8,%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20viewBox%3D%220%200%20150.2%20125%22%20style%3D%22enable-background%3Anew%200%200%20150.2%20125%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Cstyle%20type%3D%22text/css%22%3E%0A%09.st0%7Bfill%3Anone%3B%7D%0A%09.st1%7Bfill%3A%23FFFFFF%3B%7D%0A%3C/style%3E%0A%3Crect%20x%3D%220.5%22%20class%3D%22st0%22%20width%3D%22149.7%22%20height%3D%22125%22/%3E%0A%3Cg%3E%0A%09%3Cpath%20class%3D%22st1%22%20d%3D%22M59%2C102.9L21.8%2C66c-3.5-3.5-3.5-9.1%2C0-12.5l37-36.5l2.9%2C3l-37%2C36.4c-1.8%2C1.8-1.8%2C4.7%2C0%2C6.6l37.2%2C37L59%2C102.9z%22%0A%09%09/%3E%0A%3C/g%3E%0A%3Cg%3E%0A%09%3Cpath%20class%3D%22st1%22%20d%3D%22M92.5%2C102.9l-3-3l37.2-37c0.9-0.9%2C1.4-2%2C1.4-3.3c0-1.2-0.5-2.4-1.4-3.3L89.5%2C20l2.9-3l37.2%2C36.4%0A%09%09c1.7%2C1.7%2C2.6%2C3.9%2C2.6%2C6.3s-0.9%2C4.6-2.6%2C6.3L92.5%2C102.9z%22/%3E%0A%3C/g%3E%0A%3Cg%3E%0A%09%3Cpath%20class%3D%22st1%22%20d%3D%22M90.1%2C68.4c-4.5%2C0-8-3.5-8-8.1c0-4.5%2C3.5-8.1%2C8-8.1c4.4%2C0%2C8%2C3.7%2C8%2C8.1C98.1%2C64.7%2C94.4%2C68.4%2C90.1%2C68.4z%0A%09%09%20M90.1%2C56.5c-2.2%2C0-3.8%2C1.7-3.8%2C3.9c0%2C2.2%2C1.7%2C3.9%2C3.8%2C3.9c1.9%2C0%2C3.8-1.6%2C3.8-3.9S91.9%2C56.5%2C90.1%2C56.5z%22/%3E%0A%3C/g%3E%0A%3Cg%3E%0A%09%3Cpath%20class%3D%22st1%22%20d%3D%22M61.4%2C68.4c-4.5%2C0-8-3.5-8-8.1c0-4.5%2C3.5-8.1%2C8-8.1c4.4%2C0%2C8%2C3.7%2C8%2C8.1C69.5%2C64.7%2C65.8%2C68.4%2C61.4%2C68.4z%0A%09%09%20M61.4%2C56.5c-2.2%2C0-3.8%2C1.7-3.8%2C3.9c0%2C2.2%2C1.7%2C3.9%2C3.8%2C3.9c1.9%2C0%2C3.8-1.6%2C3.8-3.9S63.3%2C56.5%2C61.4%2C56.5z%22/%3E%0A%3C/g%3E%0A%3C/svg%3E%0A");
|
||||
background-repeat: no-repeat;
|
||||
float: left;
|
||||
height: 140px;
|
||||
width: 140px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.header-text {
|
||||
padding-left: 1%;
|
||||
color: #FFFFFF;
|
||||
font-family: "Segoe UI";
|
||||
font-size: 72px;
|
||||
font-weight: 300;
|
||||
letter-spacing: 0.35px;
|
||||
line-height: 96px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.header-inner-container {
|
||||
min-width: 480px;
|
||||
max-width: 1366px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.header-inner-container::after {
|
||||
content: "";
|
||||
clear: both;
|
||||
display: table;
|
||||
}
|
||||
|
||||
.main-content-area {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.content-title {
|
||||
color: #000000;
|
||||
font-family: "Segoe UI";
|
||||
font-size: 46px;
|
||||
font-weight: 300;
|
||||
line-height: 62px;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
color: #808080;
|
||||
font-size: 24px;
|
||||
font-family: "Segoe UI";
|
||||
font-size: 24px;
|
||||
font-weight: 200;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.main-text-p1{
|
||||
padding-top: 48px;
|
||||
padding-bottom: 28px;
|
||||
}
|
||||
|
||||
.endpoint {
|
||||
height: 32px;
|
||||
width: 571px;
|
||||
color: #808080;
|
||||
font-family: "Segoe UI";
|
||||
font-size: 24px;
|
||||
font-weight: 200;
|
||||
line-height: 32px;
|
||||
padding-top: 28px;
|
||||
}
|
||||
|
||||
.how-to-build-section {
|
||||
padding-top: 20px;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.how-to-build-section>h3 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.35px;
|
||||
line-height: 22px;
|
||||
margin: 0 0 24px 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.step-container {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.step-container dl {
|
||||
border-left: 1px solid #A0A0A0;
|
||||
display: block;
|
||||
padding: 0 24px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.step-container dl>dt::before {
|
||||
background-color: white;
|
||||
border: 1px solid #A0A0A0;
|
||||
border-radius: 100%;
|
||||
content: '';
|
||||
left: 47px;
|
||||
height: 11px;
|
||||
position: absolute;
|
||||
width: 11px;
|
||||
}
|
||||
|
||||
.step-container dl>.test-bullet::before {
|
||||
background-color: blue;
|
||||
}
|
||||
|
||||
.step-container dl>dt {
|
||||
display: block;
|
||||
font-size: inherit;
|
||||
font-weight: bold;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.step-container dl>dd {
|
||||
font-size: inherit;
|
||||
line-height: 20px;
|
||||
margin-left: 0;
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
|
||||
.step-container:last-child dl {
|
||||
border-left: 1px solid transparent;
|
||||
}
|
||||
|
||||
.ctaLink {
|
||||
background-color: transparent;
|
||||
border: 1px solid transparent;
|
||||
color: #006AB1;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
padding: 0;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.ctaLink:focus {
|
||||
outline: 1px solid #00bcf2;
|
||||
}
|
||||
|
||||
.ctaLink:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.step-icon {
|
||||
display: flex;
|
||||
height: 38px;
|
||||
margin-right: 15px;
|
||||
width: 38px;
|
||||
}
|
||||
|
||||
.step-icon>div {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.ms-logo-container {
|
||||
min-width: 580px;
|
||||
max-width: 980px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transition: bottom 400ms;
|
||||
}
|
||||
|
||||
.ms-logo {
|
||||
float: right;
|
||||
background-image: url("data:image/svg+xml;utf8,%0A%3Csvg%20version%3D%221.1%22%20id%3D%22MS-symbol%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20viewBox%3D%220%200%20400%20120%22%20style%3D%22enable-background%3Anew%200%200%20400%20120%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Cstyle%20type%3D%22text/css%22%3E%0A%09.st0%7Bfill%3Anone%3B%7D%0A%09.st1%7Bfill%3A%23737474%3B%7D%0A%09.st2%7Bfill%3A%23D63F26%3B%7D%0A%09.st3%7Bfill%3A%23167D3E%3B%7D%0A%09.st4%7Bfill%3A%232E76BC%3B%7D%0A%09.st5%7Bfill%3A%23FDB813%3B%7D%0A%3C/style%3E%0A%3Crect%20x%3D%220.6%22%20class%3D%22st0%22%20width%3D%22398.7%22%20height%3D%22119%22/%3E%0A%3Cpath%20class%3D%22st1%22%20d%3D%22M171.3%2C38.4v43.2h-7.5V47.7h-0.1l-13.4%2C33.9h-5l-13.7-33.9h-0.1v33.9h-6.9V38.4h10.8l12.4%2C32h0.2l13.1-32H171.3%0A%09z%20M177.6%2C41.7c0-1.2%2C0.4-2.2%2C1.3-3c0.9-0.8%2C1.9-1.2%2C3.1-1.2c1.3%2C0%2C2.4%2C0.4%2C3.2%2C1.3c0.8%2C0.8%2C1.3%2C1.8%2C1.3%2C3c0%2C1.2-0.4%2C2.2-1.3%2C3%0A%09c-0.9%2C0.8-1.9%2C1.2-3.2%2C1.2s-2.3-0.4-3.1-1.2C178%2C43.8%2C177.6%2C42.8%2C177.6%2C41.7z%20M185.7%2C50.6v31h-7.3v-31H185.7z%20M207.8%2C76.3%0A%09c1.1%2C0%2C2.3-0.3%2C3.6-0.8c1.3-0.5%2C2.5-1.2%2C3.6-2v6.8c-1.2%2C0.7-2.5%2C1.2-4%2C1.5c-1.5%2C0.3-3.1%2C0.5-4.9%2C0.5c-4.6%2C0-8.3-1.4-11.1-4.3%0A%09c-2.9-2.9-4.3-6.6-4.3-11c0-5%2C1.5-9.1%2C4.4-12.3c2.9-3.2%2C7-4.8%2C12.4-4.8c1.4%2C0%2C2.7%2C0.2%2C4.1%2C0.5c1.4%2C0.4%2C2.5%2C0.8%2C3.3%2C1.2v7%0A%09c-1.1-0.8-2.3-1.5-3.4-1.9c-1.2-0.5-2.4-0.7-3.6-0.7c-2.9%2C0-5.2%2C0.9-7%2C2.8c-1.8%2C1.9-2.7%2C4.4-2.7%2C7.6c0%2C3.1%2C0.8%2C5.6%2C2.5%2C7.3%0A%09C202.6%2C75.4%2C204.9%2C76.3%2C207.8%2C76.3z%20M235.7%2C50.1c0.6%2C0%2C1.1%2C0%2C1.6%2C0.1s0.9%2C0.2%2C1.2%2C0.3v7.4c-0.4-0.3-0.9-0.5-1.7-0.8%0A%09c-0.7-0.3-1.6-0.4-2.7-0.4c-1.8%2C0-3.3%2C0.8-4.5%2C2.3c-1.2%2C1.5-1.9%2C3.8-1.9%2C7v15.6h-7.3v-31h7.3v4.9h0.1c0.7-1.7%2C1.7-3%2C3-4%0A%09C232.2%2C50.6%2C233.8%2C50.1%2C235.7%2C50.1z%20M238.9%2C66.6c0-5.1%2C1.4-9.2%2C4.3-12.2c2.9-3%2C6.9-4.5%2C12.1-4.5c4.8%2C0%2C8.6%2C1.4%2C11.3%2C4.3%0A%09c2.7%2C2.9%2C4.1%2C6.8%2C4.1%2C11.7c0%2C5-1.4%2C9-4.3%2C12c-2.9%2C3-6.8%2C4.5-11.8%2C4.5c-4.8%2C0-8.6-1.4-11.4-4.2C240.3%2C75.3%2C238.9%2C71.4%2C238.9%2C66.6z%0A%09%20M246.5%2C66.3c0%2C3.2%2C0.7%2C5.7%2C2.2%2C7.4c1.5%2C1.7%2C3.6%2C2.6%2C6.3%2C2.6c2.7%2C0%2C4.7-0.9%2C6.1-2.6c1.4-1.7%2C2.1-4.2%2C2.1-7.6c0-3.3-0.7-5.8-2.2-7.5%0A%09c-1.4-1.7-3.4-2.5-6-2.5c-2.7%2C0-4.7%2C0.9-6.2%2C2.7C247.2%2C60.5%2C246.5%2C63%2C246.5%2C66.3z%20M281.5%2C58.8c0%2C1%2C0.3%2C1.9%2C1%2C2.5%0A%09c0.7%2C0.6%2C2.1%2C1.3%2C4.4%2C2.2c2.9%2C1.2%2C5%2C2.5%2C6.1%2C3.9c1.2%2C1.5%2C1.8%2C3.2%2C1.8%2C5.3c0%2C2.9-1.1%2C5.3-3.4%2C7c-2.2%2C1.8-5.3%2C2.7-9.1%2C2.7%0A%09c-1.3%2C0-2.7-0.2-4.3-0.5c-1.6-0.3-2.9-0.7-4-1.2v-7.2c1.3%2C0.9%2C2.8%2C1.7%2C4.3%2C2.2c1.5%2C0.5%2C2.9%2C0.8%2C4.2%2C0.8c1.6%2C0%2C2.9-0.2%2C3.6-0.7%0A%09c0.8-0.5%2C1.2-1.2%2C1.2-2.3c0-1-0.4-1.9-1.2-2.5c-0.8-0.7-2.4-1.5-4.6-2.4c-2.7-1.1-4.6-2.4-5.7-3.8c-1.1-1.4-1.7-3.2-1.7-5.4%0A%09c0-2.8%2C1.1-5.1%2C3.3-6.9c2.2-1.8%2C5.1-2.7%2C8.6-2.7c1.1%2C0%2C2.3%2C0.1%2C3.6%2C0.4c1.3%2C0.2%2C2.5%2C0.6%2C3.4%2C0.9v6.9c-1-0.6-2.1-1.2-3.4-1.7%0A%09c-1.3-0.5-2.6-0.7-3.8-0.7c-1.4%2C0-2.5%2C0.3-3.2%2C0.8C281.9%2C57.1%2C281.5%2C57.8%2C281.5%2C58.8z%20M297.9%2C66.6c0-5.1%2C1.4-9.2%2C4.3-12.2%0A%09c2.9-3%2C6.9-4.5%2C12.1-4.5c4.8%2C0%2C8.6%2C1.4%2C11.3%2C4.3c2.7%2C2.9%2C4.1%2C6.8%2C4.1%2C11.7c0%2C5-1.4%2C9-4.3%2C12c-2.9%2C3-6.8%2C4.5-11.8%2C4.5%0A%09c-4.8%2C0-8.6-1.4-11.4-4.2C299.4%2C75.3%2C297.9%2C71.4%2C297.9%2C66.6z%20M305.5%2C66.3c0%2C3.2%2C0.7%2C5.7%2C2.2%2C7.4c1.5%2C1.7%2C3.6%2C2.6%2C6.3%2C2.6%0A%09c2.7%2C0%2C4.7-0.9%2C6.1-2.6c1.4-1.7%2C2.1-4.2%2C2.1-7.6c0-3.3-0.7-5.8-2.2-7.5c-1.4-1.7-3.4-2.5-6-2.5c-2.7%2C0-4.7%2C0.9-6.2%2C2.7%0A%09C306.3%2C60.5%2C305.5%2C63%2C305.5%2C66.3z%20M353.9%2C56.6h-10.9v25h-7.4v-25h-5.2v-6h5.2v-4.3c0-3.3%2C1.1-5.9%2C3.2-8c2.1-2.1%2C4.8-3.1%2C8.1-3.1%0A%09c0.9%2C0%2C1.7%2C0%2C2.4%2C0.1c0.7%2C0.1%2C1.3%2C0.2%2C1.8%2C0.4V42c-0.2-0.1-0.7-0.3-1.3-0.5c-0.6-0.2-1.3-0.3-2.1-0.3c-1.5%2C0-2.7%2C0.5-3.5%2C1.4%0A%09s-1.2%2C2.4-1.2%2C4.2v3.7h10.9v-7l7.3-2.2v9.2h7.4v6h-7.4v14.5c0%2C1.9%2C0.3%2C3.3%2C1%2C4c0.7%2C0.8%2C1.8%2C1.2%2C3.3%2C1.2c0.4%2C0%2C0.9-0.1%2C1.5-0.3%0A%09c0.6-0.2%2C1.1-0.4%2C1.6-0.7v6c-0.5%2C0.3-1.2%2C0.5-2.3%2C0.7c-1.1%2C0.2-2.1%2C0.3-3.2%2C0.3c-3.1%2C0-5.4-0.8-6.9-2.5c-1.5-1.6-2.3-4.1-2.3-7.4%0A%09V56.6z%22/%3E%0A%3Cg%3E%0A%09%3Crect%20x%3D%2231%22%20y%3D%2224%22%20class%3D%22st2%22%20width%3D%2234.2%22%20height%3D%2234.2%22/%3E%0A%09%3Crect%20x%3D%2268.8%22%20y%3D%2224%22%20class%3D%22st3%22%20width%3D%2234.2%22%20height%3D%2234.2%22/%3E%0A%09%3Crect%20x%3D%2231%22%20y%3D%2261.8%22%20class%3D%22st4%22%20width%3D%2234.2%22%20height%3D%2234.2%22/%3E%0A%09%3Crect%20x%3D%2268.8%22%20y%3D%2261.8%22%20class%3D%22st5%22%20width%3D%2234.2%22%20height%3D%2234.2%22/%3E%0A%3C/g%3E%0A%3C/svg%3E%0A");
|
||||
}
|
||||
|
||||
.ms-logo-container>div {
|
||||
min-height: 60px;
|
||||
width: 150px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding: 90px 0px 0 20px;
|
||||
min-width: 480px;
|
||||
max-width: 1366px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.column {
|
||||
float: left;
|
||||
width: 45%;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.row:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.download-the-emulator {
|
||||
height: 20px;
|
||||
color: #0063B1;
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
padding-bottom: 70px;
|
||||
}
|
||||
|
||||
.how-to-iframe {
|
||||
max-width: 700px !important;
|
||||
min-width: 650px !important;
|
||||
height: 700px !important;
|
||||
}
|
||||
|
||||
.remove-frame-height {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1300px) {
|
||||
.ms-logo {
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
.header-text {
|
||||
font-size: 40x;
|
||||
}
|
||||
|
||||
.column {
|
||||
float: none;
|
||||
padding-top: 30px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ms-logo-container {
|
||||
padding-top: 30px;
|
||||
min-width: 480px;
|
||||
max-width: 650px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding: 20px 0px 0 20px;
|
||||
min-width: 480px;
|
||||
max-width: 650px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1370px) {
|
||||
header {
|
||||
background-color: #55A0E0;
|
||||
background-size: auto 200px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1230px) {
|
||||
header {
|
||||
background-color: #55A0E0;
|
||||
background-size: auto 200px;
|
||||
}
|
||||
|
||||
.header-text {
|
||||
font-size: 44px;
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1000px) {
|
||||
header {
|
||||
background-color: #55A0E0;
|
||||
background-image: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 632px) {
|
||||
.header-text {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding: 10px 0px 0 10px;
|
||||
max-width: 490px !important;
|
||||
min-width: 410px !important;
|
||||
}
|
||||
|
||||
.endpoint {
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.step-container dl>dd {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.column {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
height: 110px;
|
||||
width: 110px;
|
||||
}
|
||||
|
||||
.how-to-iframe {
|
||||
max-width: 480px !important;
|
||||
min-width: 400px !important;
|
||||
height: 650px !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.remove-frame-height {
|
||||
max-height: 10px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
loadFrame();
|
||||
});
|
||||
var loadFrame = function () {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.setAttribute("id", "iframe");
|
||||
var offLineHTMLContent = "";
|
||||
var frameElement = document.getElementById("how-to-iframe");
|
||||
if (window.navigator.onLine) {
|
||||
iframe.src = 'https://docs.botframework.com/static/abs/pages/f5.htm';
|
||||
iframe.setAttribute("scrolling", "no");
|
||||
iframe.setAttribute("frameborder", "0");
|
||||
iframe.setAttribute("width", "100%");
|
||||
iframe.setAttribute("height", "100%");
|
||||
var frameDiv = document.getElementById("how-to-iframe");
|
||||
frameDiv.appendChild(iframe);
|
||||
} else {
|
||||
frameElement.classList.add("remove-frame-height");
|
||||
}
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner-container">
|
||||
<div class="header-icon" style="display: inline-block"></div>
|
||||
<div class="header-text" style="display: inline-block">Spring Boot Bot</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="row">
|
||||
<div class="column" class="main-content-area">
|
||||
<div class="content-title">Your bot is ready!</div>
|
||||
<div class="main-text main-text-p1">You can test your bot in the Bot Framework Emulator<br />
|
||||
by connecting to http://localhost:3978/api/messages.</div>
|
||||
<div class="main-text download-the-emulator"><a class="ctaLink" href="https://aka.ms/bot-framework-F5-download-emulator"
|
||||
target="_blank">Download the Emulator</a></div>
|
||||
<div class="main-text">Visit <a class="ctaLink" href="https://aka.ms/bot-framework-F5-abs-home" target="_blank">Azure
|
||||
Bot Service</a> to register your bot and add it to<br />
|
||||
various channels. The bot's endpoint URL typically looks
|
||||
like this:</div>
|
||||
<div class="endpoint">https://<i>your_bots_hostname</i>/api/messages</div>
|
||||
</div>
|
||||
<div class="column how-to-iframe" id="how-to-iframe"></div>
|
||||
</div>
|
||||
<div class="ms-logo-container">
|
||||
<div class="ms-logo"></div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.sample.facebookevents;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
public class ApplicationTest {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
Загрузка…
Ссылка в новой задаче