Images are not displayed after publishing the bot with continuous deployment - github

I have developed a bot using Bot Framework. It shows images when I run it locally on the Bot Framework Emulator. But after publishing it on Azure by creating a private GitHub repository, none of the images are displayed. I'm using Direct-Line API 3.0. What could be the reason?
Like, here's the tree-view of my project. The images folder resides in Content Root.
I'm using the following static method to retrieve an image path.
public static string CreateImagePath(string filename)
{
return Path.Combine(TempData.HostingEnvironment?.ContentRootPath, "images", $"{filename}");
}
And then converting it into a Uri, and assigning it to an Adaptive Card's image. Here's the code snippet.
(AdaptiveCardFactory.CreateAdaptiveElement(card, "image") as AdaptiveImage).Url =
new Uri(PathFactory.CreateImagePath("welcome_card_image.png"));
CreateAdaptiveElement is defined as:
public static AdaptiveElement CreateAdaptiveElement(AdaptiveCard card, string adaptiveElementId)
{
return card.Body.Find(ae => ae.Id == adaptiveElementId);
}
This is the Uri that is returned when I run the bot locally. it works fine.
file:///C:/Users/Husai/source/repos/PanjaSahibBot/images/welcome_card_image.png
Here's what is returned after publishing.
file:///D:/home/site/wwwroot/images/welcome_card_image.png
And, it's not working.
Here's the latest command log.
Command: "D:\home\site\deployments\tools\deploy.cmd"
Handling ASP.NET Core Web Application deployment.
Restoring packages for D:\home\site\repository\GurdwaraBot.csproj...
Generating MSBuild file D:\home\site\repository\obj\GurdwaraBot.csproj.nuget.g.props.
Generating MSBuild file D:\home\site\repository\obj\GurdwaraBot.csproj.nuget.g.targets.
Restore completed in 5.02 sec for D:\home\site\repository\GurdwaraBot.csproj.
Microsoft (R) Build Engine version 15.9.20+g88f5fadfbe for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.
Restore completed in 1.41 sec for D:\home\site\repository\GurdwaraBot.csproj.
GurdwaraBot -> D:\home\site\repository\bin\Release\netcoreapp2.2\GurdwaraBot.dll
GurdwaraBot -> D:\local\Temp\8d6da8df6d390f3\
Creating app_offline.htm
KuduSync.NET from: 'D:\local\Temp\8d6da8df6d390f3' to: 'D:\home\site\wwwroot'
Copying file: 'GurdwaraBot.deps.json'
Copying file: 'GurdwaraBot.dll'
Copying file: 'GurdwaraBot.pdb'
Copying file: 'GurdwaraBot.runtimeconfig.json'
Copying file: 'images\01d.png'
Copying file: 'images\01n.png'
Copying file: 'images\02d.png'
Copying file: 'images\02n.png'
Copying file: 'images\03d.png'
Copying file: 'images\03n.png'
Copying file: 'images\04d.png'
Copying file: 'images\04n.png'
Copying file: 'images\09d.png'
Copying file: 'images\09n.png'
Copying file: 'images\1.jpg'
Copying file: 'images\10.jpg'
Copying file: 'images\10d.png'
Copying file: 'images\10n.png'
Copying file: 'images\11d.png'
Copying file: 'images\11n.png'
Copying file: 'images\13d.png'
Copying file: 'images\13n.png'
Copying file: 'images\2.jpg'
Copying file: 'images\3.jpg'
Copying file: 'images\4.jpg'
Copying file: 'images\5.jpg'
Copying file: 'images\50d.png'
Copying file: 'images\50n.png'
Copying file: 'images\6.jpg'
Copying file: 'images\7.jpg'
Copying file: 'images\8.jpg'
Copying file: 'images\9.jpg'
Copying file: 'images\bill.png'
Copying file: 'images\feedback.png'
Copying file: 'images\Festivals.jpg'
Copying file: 'images\festivals_bandi_chhor_divas.jpg'
Copying file: 'images\festivals_gurpurab.jpeg'
Copying file: 'images\festivals_hola_mohalla.jpg'
Copying file: 'images\festivals_maghi.jpg'
Copying file: 'images\festivals_martyrdom_of_guru_arjan.jpg'
Copying file: 'images\festivals_parkash_utsav_dasveh_patshah.jpg'
Copying file: 'images\festivals_vaisakhi.jpg'
Copying file: 'images\menu_card_image.png'
Copying file: 'images\panja_thumbnail_1.png'
Copying file: 'images\panja_thumbnail_2.png'
Copying file: 'images\panja_thumbnail_3.png'
Copying file: 'images\pof_guest_hotel.jpg'
Copying file: 'images\question.png'
Omitting next output lines...
Finished successfully.
This is what I am expecting.
Locally executed
And, this is what I'm getting via DirectLine!!
Actual result
Here's the content of my welcome_card.json
{
"type": "AdaptiveCard",
"body": [
{
"type": "Image",
"id": "image",
"horizontalAlignment": "Center",
"style": "Person",
"url": "",
"size": "Medium"
},
{
"type": "TextBlock",
"horizontalAlignment": "Center",
"size": "Medium",
"weight": "Bolder",
"color": "Accent",
"text": "Welcome to Gurdwara Bot",
"wrap": true
},
{
"type": "TextBlock",
"horizontalAlignment": "Left",
"text": "Hi there! I'm the Sri Panja Sahib's support bot. What can I help you with today? Just so you know, you can enter **MENU** anytime you want to go back to the options below, or just go ahead type your query.",
"wrap": true
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Get an Overview",
"data": {
"dataId": "overview"
}
},
{
"type": "Action.Submit",
"title": "Ask a Question",
"data": {
"dataId": "question"
}
},
{
"type": "Action.Submit",
"title": "Book a Room",
"data": {
"dataId": "room"
}
},
{
"type": "Action.Submit",
"title": "Give a Feedback",
"data": {
"dataId": "feedback"
}
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0",
"speak": "Hi there! I'm the Sri Panja Sahib's support bot. What can I help you with today? Just so you know, you can enter **MENU** anytime you want to go back to the options below, or just go ahead type your query."
}
I've defined AdaptiveCardFactory to manipulate with cards.
public class AdaptiveCardFactory
{
public static AdaptiveCard CreateAdaptiveCard(string path)
{
try
{
var adaptiveCardJson = File.ReadAllText(path);
AdaptiveCardParseResult result = AdaptiveCard.FromJson(adaptiveCardJson);
return result.Card;
}
catch (AdaptiveSerializationException)
{
throw;
}
}
public static Attachment CreateAdaptiveCardAttachment(AdaptiveCard card)
{
return new Attachment
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = card,
};
}
public static AdaptiveElement CreateAdaptiveElement(AdaptiveCard card, string adaptiveElementId)
{
return card.Body.Find(ae => ae.Id == adaptiveElementId);
}
}

TL;DR;
You must provide public URLs for items displayed in AdaptiveCards, not local ones. It is working in local with the emulator because... you are in local, and the emulator has access to your local files, so it can understand files with local location (C:\... or D:\... files).
So change your path so that it uses your sub-domain: you can do it here, for example by using a configuration variable instead of TempData.HostingEnvironment?.ContentRootPath
public static string CreateImagePath(string filename)
{
return Path.Combine(TempData.HostingEnvironment?.ContentRootPath, "images", $"{filename}");
}
Details:
AdaptiveCard item is passed as an attachment in the bot message, everything that is inside is rendered by the client (channel), so it can only render things that are "visible" from the outside.
See my demo here: I used a Card with an ImageSet of 2 images: one with an URL over the web, the other with an URL build like yours.
Local: both images are OK.
Published: only 1st image is displayed
If you look at the Inspector on the right-side, it becomes obvious that you must change the way you build your image Url.
You can also have a look to your deployed webchat by right-clicking the zone where the image should be, and you will find a link with a D:\... path
Code Fix
1st, move your images folder inside wwwroot folder of your projet. Then you can do the following:
public string CreateImagePath(string filename)
{
if (_hostingEnvironment.IsDevelopment())
{
return Path.Combine(TempData.HostingEnvironment?.ContentRootPath, "wwwroot", "images", $"{filename}");
}
else
{
var targetUri = new Uri(new Uri($"https://{Environment.ExpandEnvironmentVariables("%WEBSITE_SITE_NAME%")}.azurewebsites.net"), Path.Combine("images", $"{filename}"));
return targetUri.ToString();
}
}

Related

CI Using Azure Pipelines and Nx fails

UPDATE: I was able to get this working by setting "ProduceReferenceAssembly" to false in the .csproj files of the libs. Not sure if this is optimal or intended but that is what worked for me. See: Ref folder within .NET 5.0 bin folder
I'm trying to set up a proof of concept using NX dot net and Azure using this exaple .yml: https://nx.dev/recipes/ci/monorepo-ci-azure
I have 3 services (libs) and 3 apis (apps) ... I made a change to one of the apis to test caching and incremental builds.
The unchanged projects all say [remote cache] but then the build fails because it's looking for the .dlls in the /obj/Debug/ directory. Why use that when there are .dlls in the /dist directory?
How can I fix this? Is there something in the nx.json or project.json files I need to change?
(https://i.stack.imgur.com/IQhaO.png)
I tried using the same command locally on my machine and it completes as expected. I expect the build to complete. The build fails when remote caching is used.
{
"name": "ShipmentService",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "library",
"sourceRoot": "libs/ShipmentService",
"targets": {
"build": {
"executor": "#nx-dotnet/core:build",
"outputs": [
"{workspaceRoot}/dist/libs/ShipmentService",
"{workspaceRoot}/libs/ShipmentService/obj"
],
"options": {
"configuration": "Debug",
"noDependencies": true
},
"configurations": {
"production": {
"configuration": "Release"
}
}
},
"lint": {
"executor": "#nx-dotnet/core:format"
}
},
"tags": []
}
Tried proposed workaround, here's what I'm noticing: platformservice:build [remote cache]
Error, it sees the intermediates part, but basically same issue: same error
Updated project.json (all of them have been updated to look similar to this [tried with and without /obj portion]):
"outputs": [
"{workspaceRoot}/dist/libs/ShipmentService",
"{workspaceRoot}/dist/intermediates/libs/ShipmentService/obj"
],
This is a bug on nx-dotnet's side, and we aren't quite capturing all of the outputs that are needed for the cache. If you add the path to the obj directory into the outputs array of the build target in project.json it should work. Here's the workaround which will eventually be migrated:
I've got a branch with this working, you do indeed need the obj directory as part of the cache. There are some weird intricacies with this though. I'll work on a migration + patch. In the meantime, the workaround that I used is:
Update Directory.Build.props adding these to the property group containing the output path manipulation:
<BaseIntermediateOutputPath>$(RepoRoot)dist/intermediates/$(ProjectRelativePath)/obj</BaseIntermediateOutputPath>
<IntermediateOutputPath>$(BaseIntermediateOutputPath)</IntermediateOutputPath>
As an example, the full file looks like this on the nx-dotnet repo now:
<Project>
<PropertyGroup>
<!-- Output path configuration -->
<RepoRoot>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)'))</RepoRoot>
<ProjectRelativePath>$([MSBuild]::MakeRelative($(RepoRoot), $(MSBuildProjectDirectory)))</ProjectRelativePath>
<BaseOutputPath>$(RepoRoot)dist/$(ProjectRelativePath)</BaseOutputPath>
<OutputPath>$(BaseOutputPath)</OutputPath>
<BaseIntermediateOutputPath>$(RepoRoot)dist/intermediates/$(ProjectRelativePath)/obj</BaseIntermediateOutputPath>
<IntermediateOutputPath>$(BaseIntermediateOutputPath)</IntermediateOutputPath>
<AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<PropertyGroup>
<RestorePackagesWithLockFile>false</RestorePackagesWithLockFile>
</PropertyGroup>
</Project>
Your project.json file should look something like this now:
{
"name": "demo-webapi",
"sourceRoot": "demo/apps/webapi",
"targets": {
"build": {
"executor": "#nx-dotnet/core:build",
"outputs": [
"{workspaceRoot}/dist/demo/apps/webapi",
"{workspaceRoot}/dist/intermediates/demo/apps/webapi"
],
"options": {
"configuration": "Debug",
"noDependencies": true
},
"configurations": {
"production": {
"configuration": "Release"
}
}
}
}
}

How to fix: "The asset path must start with the project source root"?

We have an nrwl/nx project, that we can build on Windows, but it fails on Linux (Ci sytem).
The error is:
The /root/dev/apps/dmc-svr/src/assets asset path must start with the project source root: apps\dmc-svr\src
It seems to be a Windows/Linux path issue
The problem was a Windows like path for the sourceRoot property in project.json
{
"sourceRoot": "apps\\dmc-svr\\src",
"targets": {
"build": {
"executor": "#nrwl/node:build",
"options": {
"assets": [
"apps/dmc-svr/src/assets",
]
}
}
}
}
the fix is to simply replace the backslash \\ with a slash \: sourceRoot": "apps/dmc-svr/src"
We guess that this has been generated by some nx-schema.

TYPO3 CMS 8.7.27: Call to a member function getPackagePath() on null

After installing extensions in typo3 CMS 8.7.27, I got following error.. Seems like the ExtensionManagementUtility can't load the ah_contentapi.
This is my composer.json file in root (/var/www/html/typo3) for loading my extensions:
{
"repositories":[
{
"type":"composer",
"url":"https://composer.typo3.org/"
},
{
"type":"package",
"package":{
"name":"Bm/ah-content-api",
"version":"0.0.1",
"type":"typo3-cms-extension",
"source":{
"url":"https://user#bitbucket.org/company/ah_config_typo3.git",
"type":"git",
"reference":"master"
}
}
},
{
"type":"package",
"package":{
"name":"Bm/ah-contentelements",
"version":"0.0.1",
"type":"typo3-cms-extension",
"source":{
"url":"https://user#bitbucket.org/company/ah_contentelements_typo3.git",
"type":"git",
"reference":"master"
}
}
}
],
"name":"typo3/cms-base-distribution",
"description":"TYPO3 CMS Base Distribution",
"license":"GPL-2.0-or-later",
"require":{
"helhum/typo3-console":"^4.9.3 || ^5.2",
"typo3/cms-about":"^8.7.10",
"typo3/cms-belog":"^8.7.10",
"typo3/cms-beuser":"^8.7.10",
"typo3/cms-context-help":"^8.7.10",
"typo3/cms-documentation":"^8.7.10",
"typo3/cms-felogin":"^8.7.10",
"typo3/cms-fluid-styled-content":"^8.7.10",
"typo3/cms-form":"^8.7.10",
"typo3/cms-func":"^8.7.10",
"typo3/cms-impexp":"^8.7.10",
"typo3/cms-info":"^8.7.10",
"typo3/cms-info-pagetsconfig":"^8.7.10",
"typo3/cms-rte-ckeditor":"^8.7.10",
"typo3/cms-setup":"^8.7.10",
"typo3/cms-sys-note":"^8.7.10",
"typo3/cms-t3editor":"^8.7.10",
"typo3/cms-tstemplate":"^8.7.10",
"typo3/cms-viewpage":"^8.7.10",
"typo3/cms-wizard-crpages":"^8.7.10",
"typo3/cms-wizard-sortpages":"^8.7.10",
"typo3/cms":"^8.7",
"dmitryd/typo3-realurl":"2.*",
"GridElementsTeam/Gridelements":"8.2.*",
"clickstorm/cs_seo":"3.*",
"Bm/ah-content-api":"0.0.1",
"Bm/ah-contentelements":"0.0.1"
},
"scripts":{
"typo3-cms-scripts":[
"typo3cms install:fixfolderstructure",
"typo3cms install:generatepackagestates"
],
"post-autoload-dump":[
"#typo3-cms-scripts"
]
},
"extra":{
"typo3/cms":{
"web-dir":"public"
},
"helhum/typo3-console":{
"comment":"This option is not needed ay more for helhum/typo3-console 5.x",
"install-extension-dummy":false
}
},
"autoload":{
"psr-4":{
"Bm\\AhContentelements\\":"public/typo3conf/ext/ah_contentelements/Classes",
"Bm\\AhContentapi\\":"public/typo3conf/ext/ah_content_api/Classes"
}
}
}
I already cleared cache in install tool at:
1. -> important actions -> clear all cache
2. -> clean up -> Clean typo3temp/ folder
piece from composer.lock:
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is #generated automatically"
],
"content-hash": "954afd2318d54ec9b1dd0e4d7f9b445b",
"packages": [
{
"name": "Bm/ah-content-api",
"version": "0.0.1",
"source": {
"type": "git",
"url": "https://stevenhippovibe#bitbucket.org/hippovibe/ah_config_typo3.git",
"reference": "master"
},
"type": "typo3-cms-extension"
},
{
"name": "Bm/ah-contentelements",
"version": "0.0.1",
"source": {
"type": "git",
"url": "https://stevenhippovibe#bitbucket.org/stevenhippovibe/ah_contentelements_typo3.git",
"reference": "master"
},
"type": "typo3-cms-extension"
},
The Error occurs when the extension folder name under typo3conf/ext/<folder_name> doesn't match extension key used in some places of the system (e.g. using EXT:your_extension_key/... syntax in TypoScript).
Changing folder name fixed similar problem for me.
Check the PHP version and try to change it from i.e. 7.4 to 7.3.
I once had this problem with an extension that should be compatible with PHP 7.4, but wasn't in real life. This solved the problem for me.
Question here is:
How did you update to 8.7.27 (which composer command was executed)
How does your composer.lock look like?
Do you use TYPO3 console or any other special composer plugins / CLI commands to e.g. generate PackageStates.php?
I just ran into the same error message under TYPO3 9.5.5.
Solution:
Deinstall one TYPO3 extension after the other and try it out again. This will lead you to the extension which has an error. Most probably the error is inside of the file ext_localconf.php or ext_tables.php .
I got this error detail:
PHP Warning: Use of undefined constant FH_DEBUG_EXT - assumed 'FH_DEBUG_EXT' (this will throw an Error in a future version of PHP) in /var/www/html/global-extensions/ext/div2007/ext_localconf.php line 15
This has nothing to do with your error. But it can be that you have an error in one of your installed extensions or even in a backup of an extension, e.g. a folder named as extensionname.bak .
Also these recommendations can help:
https://wiki.typo3.org/Exception/CMS/1476107295

how to setstorageclass for the latest gcloud storage

we use to follow instruction here! to set the bucket lifecycle policy, but with the latest gcloud components update, we are getting an error like this:
Failure: Unsupported tag SetStorageClass.
search the gcs storage lifecycle doc did not fund any update.
The command we used is gsutil lifecycle set <json file> gs://<bucket name>/
and gsutil version: 4.25
{
"lifecycle":{
"rule":[
{
"action":{
"type":"SetStorageClass",
"storageClass":"NEARLINE"
},
"condition":{
"age":30,
"matchesStorageClass":[
"REGIONAL",
"STANDARD",
"DURABLE_REDUCED_AVAILABILITY"
]
}
}
]
}
}
EDIT 2
This was fixed in this GitHub commit, which has been included in the newest version (v4.26) of gsutil.
EDIT
It looks like you actually uncovered a bug that occurs when using the XML API. I've opened a GitHub issue an will work on fixing this ASAP:
https://github.com/GoogleCloudPlatform/gsutil/issues/427
Thanks for the report!
Looking at the code in the Boto library, you're probably trying to specify SetStorageClass a JSON key:
{
...
"SetStorageClass": ...
...
}
rather than making it the value of the action's type attribute. Here's an example using your (fixed) sample from a question comment:
{
"lifecycle": {
"rule": [
{
"action": {
"type": "SetStorageClass",
"storageClass": "NEARLINE"
},
"condition": {
"age":30,
"matchesStorageClass": ["STANDARD", "DURABLE_REDUCED_AVAILABILITY"]
}
}
]
}
}

Modeshape initial content creation

I try to add initial content to my repository. But in the log I can see :
10:12:46.934 DEBUG o.m.jcr.InitialContentImporter - Importing node at path /{}accounts
10:12:46.941 DEBUG o.m.jcr.InitialContentImporter - Importing node at path /{}users
10:12:46.941 DEBUG o.m.jcr.InitialContentImporter - Importing node at path /{}accounts/{}foo
why it add {} ? Cause of that (I guess) I have nothing initialized in my repo
My modeshape config and xml file for initial content look like this
json file :
{
"name": "cloud-repository-dev",
"workspaces": {
"predefined": ["otherWorkspace"],
"default": "default",
"allowCreation": true,
"initialContent": {
"otherWorkspace": "conf/initialContent/init.xml"
}
},
"security": {
"anonymous": {
"roles": [
"readonly",
"readwrite",
"admin"
],
"useOnFailedLogin": false
}
},
"storage": {
"cacheConfiguration": "conf/infinispan-configuration-dev.xml",
"cacheName": "persisted_repository",
"binaryStorage": {
"type": "file",
"directory": "binaries",
"minimumBinarySizeInBytes": 999
}
},
"node-types": ["conf/cnd/cloud.cnd"]
}
xml file
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0">
<accounts>
<account1 jcr:name="foo" email="cwontact#bar.com"/>
</accounts>
<users></users>
</jcr:root>
There is nothing wrong with ModeShape or your content.
ModeShape sometimes prints out node names or paths by wrapping the namespace URI within braces. So in your case, the {} denotes the node names use the "blank" namespace, as specified in your import XML file:
<accounts>
<account1 jcr:name="foo" email="cwontact#bar.com"/>
</accounts>
<users></users>
If you use the JCR API to look at your content, you'd see that the braces don't actually appear in the node names.