I have the following build_settings_message function and I am a bit confused how should I write a unit test for it. What aspects of it do I need to check?
def build_settings_message(team_id):
team = SlackTeam.objects.find_by_id(team_id)
domain = Site.objects.get_current().domain
attachments = [
_build_manage_admins(),
_build_checks_available(team, domain)
]
return {
'text': "Here is my settings page",
'attachments': attachments
}
def _build_manage_admins():
return {
"fallback": "Manage admins",
"color": "#85cdff",
"callback_id": "admins_controls",
"title": "Admins",
"footer": "Users that could remove and edit any checks ",
"actions": [
{
"name": "manage",
"text": ":key: Manage Admins",
"type": "button",
"value": "manage"
}
]
}
def _build_checks_available(team, domain):
return {
"title": "Items available",
"footer": ("You have got *{} of {}* items for "
"check *available*.").format(
team.checks_used, team.checks_available),
"actions": [
{
"text": "Open Dashboard",
"type": "button",
"url": 'https://' + domain + reverse('dashboard')
}
]
}
You have to mock SlackTeam and Site and return some fake, but real-looking values for team and domain, then verify that the value returned by build_settings_message is correct (based on team and domain).
Be sure to check edge-cases such as no team, duplicate domain, etc.
Related
I'd like to create a modal that instantly pops up when a new user joins the channel. My thought process was to use an #app.event to trigger when a new member joins, then somehow activate my slash command. But unfortunately app.event doesn't have a trigger_id so i can't just create a modal in an event method. I'm not married to using a slash command either, but it was all I found that could get users to use checkboxes and submit the checked responses for a modal. Any help connecting the two would be great, or other suggestions would be appreciated.
#app.event("member_joined_channel")
def modal_event(event, say, body):
usr_id = event["user"],
user_id = usr_id[0]
channel_id = event["channel"]
pprint.pprint(body)
say(text=f"Welcome to the channel, <#{user_id}>! 🎉 You can introduce yourself in this channel.")
app.client.chat_postMessage(
channel=channel_id,
)
#app.command("/cmd")
def modal(body):
pprint.pprint(body)
result = app.client.views_open(
trigger_id=body['trigger_id'],
view={
"title": {
"type": "plain_text",
"text": "My App",
"emoji": True
},
"submit": {
"type": "plain_text",
"text": "Submit",
"emoji": True
},
"type": "modal",
"close": {
"type": "plain_text",
"text": "Cancel",
"emoji": True
},
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Hello, Assistant to the Regional Manager Dwight! *Michael Scott* wants to know where you'd like to take the Paper Company investors to dinner tonight.\n\n"
}
},
{
"type": "input",
"element": {
"type": "checkboxes",
"options": [
{
"text": {
"type": "plain_text",
"text": "Gary Danko",
"emoji": True
},
"value": "value-0"
},
{
"text": {
"type": "plain_text",
"text": "Chipotle",
"emoji": True
},
"value": "value-1"
},
{
"text": {
"type": "plain_text",
"text": "Slack Cafe",
"emoji": True
},
"value": "value-2"
}
]
},
"label": {
"type": "plain_text",
"text": "Please select all restaurants you'd be willing to eat at:",
"emoji": True
}
}
]
}
)
Unfortunately, you need a trigger_id to open a modal. I don't know of a way you can open one without it. What you could do is listen for the [member_joined_channel][1]event and then have your app send the user an ephemeral message in the channel prompting them to click a button which would then open a modal.
I'm a beginner and I'm getting a 422 error when running a code to extract data from an API endpoint. I Googled the code and realized it's an (Unprocessable Entity) status code, but I'm not sure how to fix it.
The documentation for the API is right here: https://github.com/fedspendingtransparency/usaspending-api/blob/master/usaspending_api/api_contracts/contracts/v2/search/spending_by_award.md
Can anyone please let me know how to modify my code?
import requests
url = "https://api.usaspending.gov"
endpoint = "/api/v2/search/spending_by_award"
criteria = {
"filters": {
"award_type_codes": ["10"],
"agencies": [
{
"type": "awarding",
"tier": "toptier",
"name": "Social Security Administration"
},
{
"type": "awarding",
"tier": "subtier",
"name": "Social Security Administration"
}
],
"legal_entities": [779928],
"recipient_scope": "domestic",
"recipient_locations": [650597],
"recipient_type_names": ["Individual"],
"place_of_performance_scope": "domestic",
"place_of_performance_locations": [60323],
"award_amounts": [
{
"lower_bound": 1500000.00,
"upper_bound": 1600000.00
}
],
"award_ids": [1018950]
},
"fields": ["Award ID", "Recipient Name", "Start Date", "End Date", "Award Amount", "Awarding Agency", "Awarding Sub Agency", "Award Type", "Funding Agency", "Funding Sub Agency"],
"sort": "Recipient Name",
"order": "desc"
}
response = requests.post(f"{url}{endpoint}", params=criteria)
print(response.status_code)
You may modify the data type of several fields, i.e., the award_ids should be a array[string], recipient_locations consists of array[LocationObject]
For a working example:
import requests
import json
url = "https://api.usaspending.gov/api/v2/search/spending_by_award"
payload = json.dumps({
"filters": {
"award_type_codes": [
"10"
],
"agencies": [
{
"type": "awarding",
"tier": "toptier",
"name": "Social Security Administration"
},
{
"type": "awarding",
"tier": "subtier",
"name": "Social Security Administration"
}
],
"legal_entities": [
779928
],
"recipient_scope": "domestic",
"recipient_type_names": [
"Individual"
],
"place_of_performance_scope": "domestic",
"award_amounts": [
{
"lower_bound": 1500000,
"upper_bound": 1600000
}
],
"award_ids": [
"1018950"
]
},
"fields": [
"Award ID",
"Recipient Name",
"Start Date",
"End Date",
"Award Amount",
"Awarding Agency",
"Awarding Sub Agency",
"Award Type",
"Funding Agency",
"Funding Sub Agency"
],
"sort": "Recipient Name",
"order": "desc"
})
headers = {
'Content-Type': 'application/json',
'Cookie': 'cookiesession1=678A3E0DCDEFGHIJKLNOPQRSTUV08936'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
print(response.status_code)
Result:
{
"limit": 10,
"results": [],
"page_metadata": {
"page": 1,
"hasNext": false,
"last_record_unique_id": null,
"last_record_sort_value": "None"
},
"messages": [
[
"For searches, time period start and end dates are currently limited to an earliest date of 2007-10-01. For data going back to 2000-10-01, use either the Custom Award Download feature on the website or one of our download or bulk_download API endpoints as listed on https://api.usaspending.gov/docs/endpoints."
]
]
}
I created a simple bot with a simple lex intent. This lex intent has one single slot slotTwo.
Then I linked it with a python lambda function. I want to access to the value of that slot from inside the lambda function.
python lambda function receives the parameters context and event. The link below shows the structure for the parameter event.
https://docs.aws.amazon.com/lex/latest/dg/lambda-input-response-format.html
I copy it here too:
{
"currentIntent": {
"name": "intent-name",
"slots": {
"slot name": "value",
"slot name": "value"
},
"slotDetails": {
"slot name": {
"resolutions" : [
{ "value": "resolved value" },
{ "value": "resolved value" }
],
"originalValue": "original text"
},
"slot name": {
"resolutions" : [
{ "value": "resolved value" },
{ "value": "resolved value" }
],
"originalValue": "original text"
}
},
"confirmationStatus": "None, Confirmed, or Denied (intent confirmation, if configured)"
},
"bot": {
"name": "bot name",
"alias": "bot alias",
"version": "bot version"
},
"userId": "User ID specified in the POST request to Amazon Lex.",
"inputTranscript": "Text used to process the request",
"invocationSource": "FulfillmentCodeHook or DialogCodeHook",
"outputDialogMode": "Text or Voice, based on ContentType request header in runtime API request",
"messageVersion": "1.0",
"sessionAttributes": {
"key": "value",
"key": "value"
},
"requestAttributes": {
"key": "value",
"key": "value"
}
}
However, when I print out the content of this parameter I see only the slot and I can access to its value directly, first level.
START RequestId: 60a541d8-b3c8-48b0-a7a3-6b3f65d96482 Version: $LATEST
{
"slotTwo": "some text here"
}
The test from the lambda console works fine. It is able to retrieve the value and continue the logic.
However when I test the bot from Lex it does not work.
Any idea why?
Thanks so much
Ester
My bad.
I missed that the values indicated in the lamdda test must correspond to the whole JSON structure. So now I added this as event test:
{
"currentIntent": {
"name": "intent-name",
"slots": {
"slotTwo": "Hi from the sendmessagetest"
}
}
}
and I access the slot within the lambda this way:
messagetext = event['currentIntent'] ['slots'] ['slotTwo']
Feel free to delete my post if you find it confusing.
Thanks everyone
When ever i am calling my service from alexa i am getting None not the values of slot which i should get.
i have intent schema like :
{
"interactionModel": {
"languageModel": {
"invocationName": "name_of_app",
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "EventsIntent",
"slots": [
{
"name": "City",
"type": "AMAZON.GB_CITY"
}
],
"samples": [
"whats {City}",
"whats going on in {City} ",
"tell me about {City}"
]
}
],
"types": []
}
}
}
my Flask-Ask code where i want to import the city but when ever i run my code i get None on the place of a city name.
#ask.intent('EventsIntent', mapping={'city': 'City'})
def weather(city):
return statement('you have selected {}'.format(city))
You need to use convert rather than mapping it should work nicely please try
#ask.intent('EventsIntent', convert={'City': str})
def weather(City):
return statement('you have selected {}'.format(City))
I've been working on an integration to create a dialog for a Slack bot that uses python 3, AWS API Gateway, and AWS Lambda. I'm currently working on the Slack side for integration versus the end purpose of my function.
I can get my bot running with some responses if I remove the dialog and just have it chat with the user from the tutorials here and here, however once I add a dialog into the mix the bot no longer responds. I've tried basing my code off the the example code from the Slack API's github but it doesn't help. I would appreciate any guidance on how to do this using python 3.
Code below:
import os
import logging
import urllib
import boto3
from slackclient import SlackClient
LOGGER = logging.getLogger()
LOGGER.setLevel(logging.DEBUG)
# Grab the Bot OAuth token from the environment + slack verification
BOT_TOKEN = os.environ["BOT_TOKEN"]
SLACK_VERIFICATION_TOKEN = os.environ["SLACK_VERIFICATION_TOKEN"]
slack_client = SlackClient(BOT_TOKEN)
SLACK_URL = "https://slack.com/api/dialog.open"
def lambda_handler(data, context):
''' Entry point for API Gateway '''
slack_event = data['event']
if "bot_id" in slack_event:
logging.warn("Ignore bot event")
else:
channel_id = slack_event["channel"]
support_form = slack_client.api_call(
"dialog.open",
trigger_id = slack_event["trigger_id"],
dialog = {
"title": "AWS Support Ticket",
"submit_label": "Submit",
"callback_id": "support_form",
"elements": [
{
"label": "Subject",
"type": "text",
"name": "subject",
"placeholder": "Support Case Subject"
},
{
"label": "Description",
"type": "textarea",
"name": "body",
"placeholder": "Describe the issue you would like to open a support case about"
},
{
"type": "select",
"label": "What is your issue type?",
"name": "issueType",
"options": [
{
"label": "Customer Service",
"value": "customerservice"
},
{
"label": "Technical",
"value": "technical"
}
]
},
{
"label": "What is your severity level?",
"type": "select",
"name": "serverity",
"options": [
{
"label": "5 - General Guidance",
"value": "5"
},
{
"label": "4 - System Impaired",
"value": "4"
},
{
"label": "3 - Production System Impaired",
"value": "3"
},
{
"label": "2 - Production System Down",
"value": "2"
},
{
"label": "1 - Business-critical System Down",
"value": "1"
}
]
},
{
"label": "Service Code",
"type": "text",
"name": "serviceCode"
},
{
"label": "Category Code",
"type": "text",
"name": "categoryCode"
},
{
"label": "Please choose your language",
"type": "select",
"name": "language",
"options": [
{
"label": "English",
"value": "english"
},
{
"label": "Japanese",
"value": "japanese"
}
]
},
{
"label": "What is your attachement set id?",
"type": "text",
"name": "attachementSetId"
},
{
"label": "Please enter the emails you want cc'd on this case:",
"type": "textarea",
"name": "ccEmailAddresses"
}
]
}
})
data = urllib.parse.urlencode(
(
("token", BOT_TOKEN),
("channel", channel_id),
("dialog", support_form)
)
)
# Construct the HTTP request that will be sent to the Slack API.
request = urllib.request.Request(
SLACK_URL,
data=data,
method="POST"
)
# Add a header mentioning that the text is URL-encoded.
request.add_header(
"Content-Type",
"application/x-www-form-urlencoded"
)
# Fire off the request!
urllib.request.urlopen(request).read()
# Everything went fine.
return "200 OK"