I'm using the Google Chat API to send daily updates. I want to have a UI like this:
Like this, I want the UI should appear,
https://developers.google.com/hangouts/chat/reference/message-formats/cards I'm referring this sheet to generate those UIs.
Checkbox is not an available card message.
You can use button widget in a card message. But there are only 2 types of buttons that you can use, its either an image button or a text button.
Buttons
a widget may contain one or more buttons.
buttons in the same widget will be laid out horizontally.
buttons in a different widget will be laid out vertically.
there are two types of buttons: ImageButton and TextButton.
A button can specify a URL that will be opened when a user clicks on it, or an action to be handled by the bot's CARD_CLICKED event handler, as shown in Creating interactive cards.
An ImageButton may specify either a built-in icon or a custom image URL.
You can create card message using spaces.messages.create.
Sample Message Request Body: (card message)
In this example, there are 3 widgets created having 1 button in each widget so that the buttons will be aligned vertically.
{
"cards": [
{
"header": {
"title": "ChatBot",
"imageUrl": "https://www.gstatic.com/images/icons/material/system/1x/face_black_24dp.png",
},
"sections": [
{
"widgets": [
{
"buttons": [
{
"textButton": {
"text": "I have a bike",
"onClick": {
"action": {
"actionMethodName": "optionClick",
"parameters": [
{
"key": "mode",
"value": "bike"
}
]
}
}
}
}
]
},
{
"buttons": [
{
"textButton": {
"text": "I have a car",
"onClick": {
"action": {
"actionMethodName": "optionClick",
"parameters": [
{
"key": "mode",
"value": "car"
}
]
}
}
}
}
]
},
{
"buttons": [
{
"textButton": {
"text": "I have a boat",
"onClick": {
"action": {
"actionMethodName": "optionClick",
"parameters": [
{
"key": "mode",
"value": "boat"
}
]
}
}
}
}
]
}
]
}
]
}
]
}
OUTPUT:
Related
I am using Adaptive cards for the Microsoft teams. I am trying to use the radio button by using the "Input.ChoiceSet" type to perform two different tasks by clicking on the radio button. However, unable to perform any action on click of the radio button.
We could not find any property to perform the action. Could you please suggest any way through which we can achieve this
{
type: "Input.ChoiceSet",
id: "incType",
style: "expanded",
isMultiSelect: false,
value: "recurrence",
choices: [
{
title: "one Time",
value: "oneTime"
},
{
title: "Recurring",
value: "recurrence"
}
],
verb: "recurrence_radio_btn_action",
}
There is no invoke activity sent when a radio button is selected on an adaptive card, instead you could either..
Have an action button (Action.Submit or Action.Execute if using Universal Actions outside of a messaging extension):
"body": [
{
"type": "Input.ChoiceSet",
"choices": [
{
"title": "Choice 1",
"value": "Choice 1"
},
{
"title": "Choice 2",
"value": "Choice 2"
}
],
"style": "expanded"
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Submit"
}
],
Or render each option as an action of its own:
"body": [
],
"actions": [
{
"type": "Action.Submit",
"title": "Option 1"
},
{
"type": "Action.Submit",
"title": "Option 2"
}
],
In either case, you would then handle the invoke activity when the relevant button is pressed.
I need to build an extremely simple message extension, that once it's clicked (in a teams channel conversation, the same way the "gif" button is clicked) just shows a card with a text and a button (and then when enter is pressed, it's just sent).
I'm a beginner when it comes to message extensions development, I used the instructions from this Microsoft page, and now I'm trying to scrap what I don't need from the generated project and just leave / add what I need.
What I have until now (relevant parts)
in the manifest file
"composeExtensions": [
{
"botId": "{botId}",
"commands": [
{
"id": "createCard",
"context": [
"compose"
],
"description": "Command to run action to create a Card from Compose Box",
"title": "Create Card",
"type": "action",
"parameters": [
{
"name": "title",
"title": "Card title",
"description": "Title for the card",
"inputType": "text"
},
{
"name": "subTitle",
"title": "Subtitle",
"description": "Subtitle for the card",
"inputType": "text"
},
{
"name": "text",
"title": "Text",
"description": "Text for the card",
"inputType": "textarea"
}
]
}
],
"messageHandlers": [
{
"type": "link",
"value": {
"domains": [
"*.botframework.com"
]
}
}
]
}
],
in the bot implementation
export class MessageExtensionBot extends TeamsActivityHandler {
public async handleTeamsMessagingExtensionSubmitAction(
context: TurnContext,
action: any
): Promise<any> {
switch (action.commandId) {
case "createCard":
return createCardCommand(context, action);
default:
throw new Error("NotImplemented");
}
}
}
async function createCardCommand(context: TurnContext, action: any): Promise<any> {
const cardJson = {
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "TextBlock",
"text": "Click the button below to launch Custom Link"
}
],
"actions": [
{
"type": "Action.OpenUrl",
"title": "Launch Custom Link",
"url": "https://google.com"
}
]
};
const adaptiveCard = CardFactory.adaptiveCard(cardJson);
const attachment = {
contentType: adaptiveCard.contentType,
content: adaptiveCard.content,
preview: adaptiveCard,
};
return {
composeExtension: {
type: "result",
attachmentLayout: "list",
attachments: [attachment],
},
};
}
What I have working: when I click the message extension button, I get prompted to enter those three properties (title, subtitle, text), and only after that, I do get my dummy card displayed.
What I need to do:
eliminate that properties prompt completely, I don't need those. I would only need to directly display the adaptive card, without prompting/waiting any other user action
I tried clearing that section from the manifest, but then the app does not work at all: after redeployment I still get prompted for the properties and I get an error no matter if/what I enter
How can I achieve that ?
what do I need to remove/add to the manifest ?
what method do I need to implement in the bot class ?
Can anybody help somehow ?
Thank you.
So if you want to make something like GIF messaging extension in Teams then you should try template - Custom Stickers App Template (C#). If you refer this template you will also get manifest, which you just need to configure with your bot Id.
Explanation of manifest -
The part that you need in manifest is only simple composeExtensions with command type query
"composeExtensions": [
{
"botId": "<bot id>",
"canUpdateConfiguration": false,
"commands": [
{
"id": "Search",
"type": "query",
"title": "Search",
"description": "",
"initialRun": true,
"parameters": [
{
"name": "keyword",
"title": "keyword",
"description": "search for a sticker"
}
]
}
]
}
]
As I understand from the question you asked, you want something like this https://i.stack.imgur.com/vSJ8y.png
In the bot handler -
You need to implement handleTeamsMessagingExtensionQuery(context, query). Here you can use argument query to search for the image you want to send. If you want to see how to implement, we have a sample ready for it(not in context of GIF but you will get general idea)- Sample link.
In this method you need to return messaging extension response. In it you will return all the results(attachment).
Attachment is consist of preview and content. Preview get renders in the messaging extension. Once you click on the preview, its content get render in compose box.
Refer this on how to return messaging extension response having preview as thumbnail card and content as adaptive card - link
You can use this Adaptive card JSON as you just want to show image in it
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "Image",
"url": "https://adaptivecards.io/content/cats/1.png"
}
]
}
Refer this for more image related samples.
Why am I getting an error 'no_text' ?
The Json below is valid and is taken from the slack documentation example.
In bot.postMessage(channel, '', params) if I populate the second parameter (i.e. replacing ' ' with 'some_text) it prints 'some_text' but without the attachment.
bot.postMessage(channel, 'some_text', params) --> works but the attachment doesn't show up.
const element = {
"text": "Would you like to play a game?",
"response_type": "in_channel",
"attachments": [
{
"text": "Choose a game to play",
"fallback": "If you could read this message, you'd be choosing something fun to do right now.",
"color": "#3AA3E3",
"attachment_type": "default",
"callback_id": "game_selection",
"actions": [
{
"name": "games_list",
"text": "Pick a game...",
"type": "select",
"options": [
{
"text": "Hearts",
"value": "hearts"
},
{
"text": "Global Thermonuclear War",
"value": "war"
}
]
}
]
}
]
}
console.log('JSON.stringify(element): '+JSON.stringify(element));
params = {
icon_emoji: ':r2:',
attachments: JSON.stringify(element)
}
bot.postMessage(channel, '', params).always(function (data) {...}
The issue arises from the lack of a text field in the parameters that is passed to bot.PostMessage. Your params should be
params = {
icon_emoji: ':r2:',
text: "Would you like to play a game?",
response_type: "in_channel",
attachments: element
}
and the element now should start from the actual attachment
const element = [
{
"text": "Choose a game to play",
"fallback": "If you could read this message, you'd be choosing something fun to do right now.",
"color": "#3AA3E3",
"attachment_type": "default",
"callback_id": "game_selection",
"actions": [
{
"name": "games_list",
"text": "Pick a game...",
"type": "select",
"options": [
{
"text": "Hearts",
"value": "hearts"
},
{
"text": "Global Thermonuclear War",
"value": "war"
}
]
}
]
}
]
I met the same issue and found the solution.
The problem is that if only attachments field is added into the payload, it will report no_text error. But if text field is added, slack message will only show the text content.
The solution:
When we want to display attachments, we need to add a basic blocks field instead of text field. Something like
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "bar"
}
}
],
"attachments": [
{
"color": "#FF0000",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "foo"
}
}
]
}
]
}
If putting the above payload into the Slack build kit, it will be a misleading. That's also why I stuck with the issue.
I would recommend to use chat.postMessage test to debug the payload. It will work like a charm.
This is the interaction model I am using:
{
"interactionModel": {
"languageModel": {
"invocationName": "greeter",
"intents": [
{
"name": "HelloWorldIntent",
"slots": [
{
"name": "phrase",
"type": "phrase"
}
],
"samples": [
"{phrase}"
]
}
],
"types": [
{
"name": "phrase",
"values": [
{
"name": {
"value": "HelloWorldIntent asdf {phrase}"
}
}
]
}
]
}
}
}
Notice the value of phrase slot type. When I set it this way, whatever I say to alexa, whole of the raw query is getting populated in value field of phrase slot of the request object.
Ex:
"Launch greeter" ==> LaunchIntent (obvious)
"No matter what I say it triggers Hello world intent" ==>
"intent": {
"name": "HelloWorldIntent",
"confirmationStatus": "NONE",
"slots": {
"phrase": {
"name": "phrase",
"value": "no matter what I say it triggers hello world intent",
"resolutions": {
"resolutionsPerAuthority": [
{
"authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.6c1d0991-f895-45fa-ba37-6880d3cc95f1.phrase",
"status": {
"code": "ER_SUCCESS_NO_MATCH"
}
}
]
},
"confirmationStatus": "NONE"
}
}
}
I am not able to figure out how this interaction model is giving me the raw query in "value" field of phrase slot.
I've a webhook for fulfillment.
Below is the code that's responding back
let result_obj = {
"fulfillmentText": "This is a text response",
"fulfillmentMessages": [
{
"text": {
"text": [
"this is test"
]
}
},
{
"card": {
"title": "card title",
"subtitle": "card text",
"imageUri": "https://assistant.google.com/static/images/molecule/Molecule-Formation-stop.png",
"buttons": [
{
"text": "button text",
"postback": "https://assistant.google.com/"
}
]
}
}
]
}
Below is the result from dialogflow GUI
Below is what I get when I run from the simulator or from the Google Assistant application on the Android phone
Both the simulator and phone are not showing the cards. Am I missing something obvious here?
For rich responses like cards to show on Google Assistant you have to use the payload part of response JSON, here is an example:
{
"fulfillmentText": "This is a text response",
"fulfillmentMessages": [],
"source": "example.com",
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "This is a Basic Card:"
}
},
{
"basicCard": {
"title": "card title",
"image": {
"url": "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png",
"accessibilityText": "Google Logo"
},
"buttons": [
{
"title": "Button Title",
"openUrlAction": {
"url": "https://www.google.com"
}
}
],
"imageDisplayOptions": "WHITE"
}
}
]
}
}
},
"outputContexts": [],
"followupEventInput": {}
}
Check out this github repo for all rich-responses' JSON formats.