MS Teams List Card - microsoft-teams

Do list cards in teams still work?
I want to try out a simple list card with support for scrolling.
However, I cannot get it working in App Studio(Card Editor) or from the code.
I do not see any way of sending a list card using CardFactory as well.

Yes, they definitely still do work, I happened to test one this morning. You're right though that App Studio's Card Editor doesn't support them though, and CardFactory doesn't have a mechanism for them either, so you either need to create the JSON object explicitly, or use a JSON string.
I'm using C#, so can't send you a code sample, but it should just be a case of making sure your final output matches the correct format for List Cards

The list card sample json is here - https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-reference#list-card
This cannot be tested in the Adaptive cards designer - https://adaptivecards.io/designer
I got this working by using the following code in Java
Attachment attachment = new Attachment();
attachment.setContentType("application/vnd.microsoft.teams.card.list");
attachment.setContent(createCardJson("ListCard.json")));
Activity act=MessageFactory.attachment(attachment);
We have to change the ListCard.json to just have the content part of the json (from the link above) stored with the file. The content type is set with the attachment object

Related

How do I use capture groups in Regular Expressions in Bot Composer

I am attempting to build a Microsoft Teams bot using the Bot Framework Composer. What I would like to do is create an integration with ServiceNow. The goal would be that if anyone posts a record number (ex. REQ0123456, INC0123456, KB0123456) into the group or direct chat (with the bot), the bot would look up that record and provide a card or a short summary of the record to the chat.
To avoid creating a completely separate intent for each record type, I was hoping to use RegEx to gather the match into 2 capture groups; one for the tbl_code and one for the number.
Here is the entry for the user input:
> add some example phrases to trigger this intent:
- look up {conversation.sn_record.tbl_code=REQ}{conversation.sn_record.number=0123456}
- lookup {conversation.sn_record.tbl_code=REQ}{conversation.sn_record.number=0123456}
- {conversation.sn_record.tbl_code=REQ}{conversation.sn_record.number=0123456}
- lu {conversation.sn_record.tbl_code=REQ}{conversation.sn_record.number=0123456}
> entity definitions:
# regex sn_record tbl_code, number = /([a-z]{2,4})([0-9]{7})/mi
The Issue I'm Having
I don't know how to get the values back from the individual capture groups. I would like to have them separate so that I can determine which table needs to be queried. I could probably just use the entire match and the search API in ServiceNow for the whole record string, but I would still like to know how to use capture group values.
I'm currently using turn.recognized.text, but I don't think this is the best method for what I'm looking to do. This returns the entire regex match.
I'm very new to this framework, so please be gentle. :) Let me know if there is more information I can provide.
Thanks all.
Best Regards,
Josh
I was able to figure this one out using the examples in the ToDosSample bot.
The answer was to use named capture groups and then add them to a dialog property to use in the corresponding dialog.
For reference here are the changes I had to make:
New Regex
(?<sn_record>(?<tbl_code>[a-z]{2,4})(?<numbers>[0-9]{7}))
New Dialog Properties
dialog.sn_record = #sn_record
dialog.sn_tbl_code = #tbl_code
dialog.sn_numbers = #numbers
New response
- Okay, looking up ${dialog.sn_tbl_code}${dialog.sn_numbers}

How get stream of selected image by user (BitmapFactory.DecodeStream(inputStream) returns null)

When loading the selected image of the user and passing the stream to BitmapFactory.DecodeStream(inputStream) I always get as result null.
I load the stream of the image like this:
Stream stream = new Java.Net.URL(Uri.Parse($"file://{imageFile.Path}").ToString()).OpenStream(); I also tried many other variants like:
BitmapFactory.DecodeStream(Activity.ContentResolver.OpenInputStream(uri) or new Java.IO.FileInputStream(imageFile.Path)
I have permissions for WriteExternalStorage. Whats causing the problem? How to fix it?
The sample project is available here https://github.com/mfe-/App10
You probably need to use the content resolver. Unfortunately, the process is not consistent across sdk versions and even sometimes devices. Take a look at how the media picker plugin handles getting the file. I've actually ended up copy/pasting its GetFileForUriAsync method into my project.
https://github.com/jamesmontemagno/MediaPlugin/blob/master/src/Media.Plugin/Android/MediaPickerActivity.cs

What is the relationship between CGPDFContext and CGPDFDocument?

My understanding of this was that perhaps CGPDFContext is to be used for editing PDF document data and CGPDFDocument is used for storing it, since the documentation doesn't list any ways to alter the content of a CGPDFDocument.
I'm also not quite sure what CGDataConsumer/Provider does. From reading the documentation I got the impression that the consumer/provider abstracts the relationship between the CG object and the CFData it writes to; so I don't have to do that myself. So I figured the following code would create a two page blank PDFdocument:
//Don't know exactly how large a PDF is so I gave it 1 MB for now
self->pdfData = CFDataCreateMutable(kCFAllocatorDefault, 1024);
self->consumerRef = CGDataConsumerCreateWithCFData(self->pdfData);
self.pdfRef = CGPDFContextCreate(self->consumerRef, NULL, NULL);
CGPDFContextBeginPage(self.pdfRef, NULL); //Creates a blank page?
CGPDFContextEndPage(self.pdfRef);
CGPDFContextBeginPage(self.pdfRef, NULL); //Creates a second blank page?
CGPDFContextEndPage(self.pdfRef);
//Copies the data from pdfRef's consumer into docRef's provider?
self.docRef = CGPDFDocumentCreateWithProvider(
CGDataProviderCreateWithCFData(
CFDataCreateCopy(kCFAllocatorDefault, self->pdfData)
));
It didn't work though, and NSLogging the first two pages of docRef returns NULL. I'm rather new at this, the C-Layer stuff in particular. Can someone explain to me the relationship between CGPDFContext, CGPDFDocument, CGDataConsumer & CGDataProvider and how I'd use them to create a blank PDF?
Your basic understanding is correct as far as I can see:
A CGPDFContext is a drawing context that "translates" everything that is drawn onto it to PDF instructions (typically for storage in a PDF file).
A CGPDFDocument is used to open an existing PDF file and get information from it.
When you want to create your own PDF file, you have two ways to do it as described here: https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CGPDFContext/Reference/reference.html
Use "CGPDFContextCreate" which you pass a data consumer. The data consumer gets the data and can do with it as it pleases (you could create a data consumer that passes the PDF onto the clipboard for example).
Use "CGPDFContextCreateWithURL" which you pass a URL. In that case your data will be written to a PDF file at that URL.
If you want to use these functions, have a look at this page https://developer.apple.com/library/mac/documentation/graphicsimaging/Conceptual/drawingwithquartz2d/dq_pdf/dq_pdf.html#//apple_ref/doc/uid/TP30001066-CH214-TPXREF101 which explains in detail how to create PDF files with a data provider and without (simply to a PDF).
To figure out what is happening I would start by trying to write a simple PDF file to disk before writing one to a data provider and then using that data provider immediately to read it again. Without trying your code however, let me point out that you didn't use "CGPDFContextClose" which is described in the document as closing the PDF document and flushing all information to output. You could actually having a situation where stuff is cached and not written to your data provider yet, simply because you haven't forced that.

Get a list of Active Directory Users along with their Full Name and Email

I need to retrieve a list of Active Directory users and their attributes using Delphi 2010.
I've seen a few similar questions on SO (e.g. Delphi - Find primary email address for an Active Directory user), but they all seem to require the user name before any additional information can be retrieved.
I had written an article for [The Delphi Magazine] way back when..... if you have access to a backlog of those magazines, it's in issue no. 62 (October 2000) - unfortunately, it seems those back issues aren't available for purchase anymore :-(
It's too long of an article and a code sample to post here.... basically it's about wrapping the IDirectorySearch interface in a nicer Delphi-like shell. You pass in a base container where to search, you define an LDAP filter, and you define a set of attributes you're interested in - then you search and get back basically an enumerator for the results, which you can get one by one.
In the end, I discovered TJvObjectPickerDialog, part of JVCL. It wraps the Windows Select Object dialog and does everything I need with very little coding. Just set the required properties and call execute. The selected user objects are returned along with the attributes that you set in the 'Attributes' property.

How to add components in to an existing GUI created by guide?

I just created a GUI using guide in MATLAB for a small project I'm working on. I have amongst other things two text fields for from and to dates. Now I'd like to get rid of them and use a Java date select tool. Of course this is not possible using guide so I need to add them manually.
I've managed to get them to show up by putting this code into my Opening_Fcn,
uicomponent(handles, 'style','com.jidesoft.combobox.DateChooserPanel','tag','til2');
using UICOMPONENT.
But even though it shows up I can't access the date select's attributes, for example
get(handles.til2)
returns
??? Reference to non-existent field 'til2'.
How can I fix this?
Unless you edit the saved GUI figure, the basic handles structure will not include your new component by default.
One way to access you component is to store the handle via guidata, by adding the following to your opening function:
handles.til2 = uicomponent(handles, 'style','com.jidesoft.combobox.DateChooserPanel','tag','til2');
guidata(hObject,handles)
Functions that need to access the handle need the line
handles = guidata(hObject)
to return the full handles structure that includes the filed til2

Resources