Tag: Did you know

Did you know … you can post data to Teams channels from your own code?

This post contains more niche “for developers” information than most of my Teams info series 😊

You’ve seen third-party services with connectors in Teams – both services with connectors published to Teams and services that can use the “Incoming Webhook” connector to post data. Youcan use the “Incoming Webhook” connector within your code too. If you want to allow others to post information into their Teams spaces, you’ll need a configuration option that allows end-users to supply the webhook URL. If you want to post information into your Teams space, then you can include it directly in your code. If you are doing the former, provide something like the “Creating a Teams Webhook URL” instructions below to your end users. In this example, I am doing the later. The example script is Python code that gathers statistics and posts a summary to my Teams space.

Creating a Teams Webhook URL:

Create a URL for your incoming webhook – from the not-quite-a hamburger menu next to the channel into which you want to publish your data, select “Connectors”, find “Incoming Webhook”, and click “Add” (if you have already configured a webhook in your Teams space, you will see “Configure”instead, and will not have to ‘install’ the webhook)

Read the privacy policy and terms of use, and if they are acceptable click “Install”

Provide a name for your webhook – this name will be displayed on all posts made via this webhook. Scroll down.

You can customize the logo associated with your webhook posts – nice if your application has a well-known logo. Click create to generate the webhook URL.

Copy the URL somewhere, then click ‘Done’.

Using Teams Webhooks Within Code:

OK, now you’ve got something like this in a text document (no, I didn’t post a real webhook to the Internet – the long pseudo-random alphanumeric string is hex, and there aren’t a whole lot of m’s and q’s in hex!):

https://outlook.office.com/webhook/bge9922d-44fa-4c60-bp59-e935554ff4cd@2567m4c1-b0ep-40f5-aee3-58d7c5f3e2b2/IncomingWebhook/644915ga291e4ee499f2479a32qde691/9e0c4d6c-65d9-4f94-b0d5-4fbbb0238358

What do you do with it? You make a POST call to that URL and supply JSON-formatted card content in the data. Microsoft provides a complete card reference, but you’ll need to use the O365Connector Card with the incoming webhook connector.

The card requires “summary” or “text” be included – you’ll get a bad data HTTP response if you fail to set one of these values. Card text can be formatted in markdown or HTML – if you want to use HTML, you need to set markdown to false.

You’ll need a function that POSTs data to a URL:

################################################################################
# This function POSTs to a URL
# Requirements: requests
# Input: strURL -- URL to which data is posted
#        strBody -- content to be sent as data
#        strContentType -- Content-Type definition
# Output: BOOL -- TRUE on 200 HTTP code, FALSE on other HTTP response
################################################################################
def postDataToURL(strURL, strBody, strContentType):
    if strURL is None:
        print("POST failed -- no URL provided")
        return False
    print("Sending POST request to strURL=%s" % strURL)
    print("Body: %s" % strBody)
    try:
        dictHeaders = {'Content-Type': strContentType}
        res = requests.post(strURL, headers=dictHeaders,data=strBody)
        print(res.text)
        if 200 <= res.status_code < 300:
            print("Receiver responded with HTTP status=%d" % res.status_code)
            return True
        else:
            print("POST failed -- receiver responded with HTTP status=%d" % res.status_code)
            return False
    except ValueError as e:
        print("POST failed -- Invalid URL: %s" % e)
    return False

And you’ll need something to create a card and call the HTTP POST function. Here, I define a function that takes statistics on Windstream’s Microsoft Teams usage, formats a card with the values, and POSTs it to my webhook URL.

################################################################################
# This function posts usage stats to Teams via webhook
# Requirements: json
# Input: strURL -- webhook url
#        iPrivateMessages, iTeamMessages, iCalls, iMeetings -- integer usage stats
#        strReportDate - datetime date for stats
# Output: BOOL -- TRUE on 200 HTTP code, FALSE on other HTTP response
################################################################################
def postStatsToTeams(strURL,iPrivateMessages,iTeamMessages,iCalls,iMeetings,strReportDate):
    try:
        strCardContent = '{"title": "Teams Usage Statistics","sections": [{"activityTitle": "Usage report for ' + yesterday.strftime('%Y-%m-%d') + '"}, {"title": "Details","facts": [{"name": "Private messages","value": "' + str(iPrivateMessages) + '"}, {"name": "Team messages","value": "' + str(iTeamMessages) + '"}, {"name": "Calls ","value": "' + str(iCalls) + '"}, {"name": "Meetings","value": "' + str(iMeetings) + '"}]}],"summary": "Teams Usage Statistics","potentialAction": [{"name": "View web report","target": ["https://csgdirsvcs.windstream.com:1977/o365Stats/msTeams.php"],"@context": "http://schema.org","@type": "ViewAction"}]}'
        jsonPostData = json.loads(strCardContent)

        if postDataToURL(strURL, json.dumps(jsonPostData),'application/json'):
            print("POST successful")
            return True
        else:
            print("POST failed")
            return False
    except Exception as e:
        print("ERROR Unexpected error: %s" % e)
    return False

Run the program, and you’ll see information in Teams:

A personal recommendation based on my experience with third-party code that uses generic incoming webhooks — have a mechanism to see more than a generic error when the POST fails. It takes a lot of effort to pull apart what is actually being sent, turn it into a curl command to reproduce the event, and read the actual error.Providing a debug facility that includes both the POST body and actual response from the HTTP call saves you a lot of time should your posts fail.

Did you know … Microsoft Teams has a Twitter connector?

Microsoft publishes outage notifications several places –there’s a web portal that provides general status for major Office 365 outages,a customer-only portal that provides a LOT of details on every diminished service state, a Twitter feed with status on wide-spread outages. The common feature of all of these, though, is *checking* to see if there’s an outage –start seeing several calls for the same problem, check the outage site. It works, but it is not proactive.

Twitter could be proactive, but I don’t want to be diving for my phone every time a friend posts some random musing. But Microsoft Teams connects to Twitter, and it posts filtered content into a channel,so I only see pertinent information in our Teams channel. The connector can also search hash tags – useful for tracking brand mentions.

You can include Twitter posts into an existing channel or create a new one. I am creating a new channel to separate Twitter posts from other conversations.

Click the not-quite-a hamburger menu next to the channel into which you want Twitter posts to appear and select “Connectors”.

Locate “Twitter” and click “Configure”

You will need to configure a Twitter account before you can configure the connector. I recommend not using your personal account. Create a new account to be used by your Teams space. If ownership of the Teams space changes, the new owner can take over the Twitter account too. Click “Log in”

Click “Continue” to proceed with Twitter authentication

You are allowing the Twitter connector to use your account – read the access request and sign in if the usage is acceptable.

Once you have authenticated to Twitter, you will be able to configure the Teams connector. Enter accounts or tags to see Teams posts for relevant activity – do not put spaces after the commas!

Decide if you want Teams posts for replies, mentions, or re-tweets. Select the frequency with which you want the Teams connector to check for updates – our Microsoft outage notification connector is set to “Deliver individual messages as new tweets arrive”, but I configure most other connectors to create a digest every 1 or 6 hours. Once you have completed the connector configuration, click “Save”.

In your selected channel, you will find a post summarizing the connector configuration.

Did you know … you can share files in Microsoft Teams chats?

You can share files in both individual and group chats. In the chat, click on “Files”

Then click on “Share” and “Upload from my computer” to share a new file.

While it is uploading, you’ll see a status indicator.

And once the upload completes, you will get a desktop notification.

Voila – a shared file.

Where is that file? It’s been uploaded to your OneDrive for Business. Open the OneDrive web app and you’ll see a folder titled “Microsoft Teams Chat Files”.

In there, you’ll see all of the files you’ve shared in Teams. Click on “Shared”

And you can see with whom the file was shared.

If you shared a file in a group chat, everyone in the chat will be added to the file permission. If you shared a file in an individual chat, just that individual will be added.

If you want to share the same file with a second person, there’s no need to upload it again … doing so would remove the original permissions. When you see a warning that the file already exists, cancel.

Instead of uploading the file from your computer, select “OneDrive” from the “Share” menu.

Navigate into the “Microsoft Teams Chat Files” folder.

And select the file you wanted to share.

The new person with whom you want to share the file is added to the share list, and both individuals will see the file in the “Files” section of your Teams chat.

Be careful — deleting the file from your OneDrive space does not remove it from the Teams files list. The chat participants will get an error when they attempt to view the file.

Splunk Teams Connector – Followup

We managed to use the stock Teams webhook app in Splunk — just needed to modify the search being used. Adding “|table” and specific fields to be included in the table avoids having to filter the list data within the Python code

There still is a tweak to the code that I prefer — Python lists aren’t in any particular order. I’d like to be able to look the same place in the Teams post to see a particular field. Adding a sort when the facts array is put into the post body ensures the fields are in the same order each time.

        sections=[
            {"activityTitle": settings.get("search_name") + " was triggered"},
            {
                "title": "Details",
                "facts": sorted(facts)
            }
        ],

And I’ve got a Teams post from Splunk with a generic script — desired fields are specified within the search, so can be easily changed.

Splunk – Posting to Microsoft Teams via Webhooks

Using either the default webhook action or the Teams-specific webhook, Splunk searches can post data into Microsoft Teams. First, you need to get a webhook URL for your Teams channel. On the hamburger menu next to the channel, select “Connectors”. Select Webhook, provide a name for the webhook, and copy the webhook URL.

If you intend to use the generic webhook app, there is no need to install the Teams-specific one. The Teams-specific app gives you prettier output & a “view in splunk” button. Download the app tgz. To install the app, go into “Manage Apps” and select “Install app from file”.

Click ‘Browse…’ and find the tgz you downloaded. Click ‘Upload’ to install the app to Splunk.

Now create a search for which you want to post data into your Teams channel. Click “Save As” and select “Alert”

Provide a title for the alert — you can use real-time or scheduled alerts. Once you’ve got the alert sorted, select “Add Actions” and select the Teams webhook action (or the generic webhook action if you intend to use that one). Paste in the URL from your Teams channel webhook and click “Save”.

You”ll see a confirmation that the alert has been saved. Close this.

Now you would think you’d be ready to use it … but wait. Neither one works out of the box. In the Splunk log, you see error 400 “Bad data” reported.

For the default webhook app, edit the Python script (/opt/splunk/etc/apps/alert_webhook/bin/webhook.py in my case). Find the section where the JSON body is built. Teams requires a summary or title within the POST data. I just added a static summary, but you could do something fancier.

        body = OrderedDict(
            sid=settings.get('sid'),
            summary='LJRWebhook',
            search_name=settings.get('search_name'),
            app=settings.get('app'),
            owner=settings.get('owner'),
            results_link=settings.get('results_link'),
            result=settings.get('result')

For the Teams-specific webhook, edit the Python script (/opt/splunk/etc/apps/alert_msteams/bin/teams.py in my case) and find the section where the facts list is populated. There’s too much data being sent through. There’s probably a way to filter it out in Splunk, but I don’t know how 🙂

The right way to do it is select the most important items from settings.get(‘result’).items that you want to be displayed within Teams and populate facts with those elements. I used a new list, strWantedKeys, to determine which keys should be added to the facts list. The quick/ugly way is to just take the first n items from the result items (settings.get(‘results’).items()[:7] gets seven … 8 produced a ‘bad payload received by generic incoming webhook’ error from Teams.

try:
settings = json.loads(sys.stdin.read())
print >> sys.stderr, "DEBUG Settings: %s" % settings
url = settings['configuration'].get('url')
facts = []
strWantedKeys = ['sourcetype', '_raw', 'host', 'source']
for key,value in settings.get('result').items():
if key in strWantedKeys:
facts.append({"name":key, "value":value})
body = OrderedDict(

For reference, the original facts list was:

    "facts": [{
        "name": "index",
        "value": "history"
    }, {
        "name": "_raw",
        "value": "Test push to teams 555"
    }, {
        "name": "_eventtype_color",
        "value": ""
    }, {
        "name": "host",
        "value": "10.10.15.134:8088"
    }, {
        "name": "source",
        "value": "http:Sendmail testing"
    }, {
        "name": "_si",
        "value": ["49cgc3e5e52e", "history"]
    }, {
        "name": "sourcetype",
        "value": "mysourcetype"
    }, {
        "name": "_indextime",
        "value": "1544554125"
    }, {
        "name": "punct",
        "value": "___"
    }, {
        "name": "linecount",
        "value": ""
    }, {
        "name": "_time",
        "value": "1544554125"
    }, {
        "name": "eventtype",
        "value": ""
    }, {
        "name": "_sourcetype",
        "value": "mysourcetype"
    }, {
        "name": "_kv",
        "value": "1"
    }, {
        "name": "_serial",
        "value": "15"
    }, {
        "name": "_confstr",
        "value": "source::http:Sendmail testing|host::10.10.15.134:8088|mysourcetype"
    }, {
        "name": "splunk_server",
        "value": ""
    }]

Now generate a message that matches your search — you’ll see a post created in your Teams channel.

Did you know … you can record Microsoft Teams meetings (and add a transcription)?

Once you have started a Microsoft Teams meeting, click the not-quite-a-hamburger menu in the meeting control and select “Start recording.

You will see a confirmation that your meeting is recording – and, as the message mentions, make sure everyone knows they are being recorded.

If you are attending the meeting using a web browser, the browser tab will have a little red circle indicating that recording is active.

If you no longer wish to record the meeting, click the not-quite-a-hamburger-menu button again and select “Stop recording.

Now where is that recording?? Open the meeting chat

And you’ll see a post indicating that the recording is saving. Once the recording has been saved, a link to the recording will appear in the conversation. You can get a link to share with others.

If you would like a transcription to be created for your meeting, select “Open in Microsoft Stream”. This will open the recording in a web browser. Under the meeting information, click the not-quite-a-hamburger menu and select “Edit”

On the edit page, select the video language. Ensure “Captions” is checked.

Scroll up to the top of the page and click “Apply”.

Wait for it – the transcription process can take a loooong time. Once the transcription is done, you can click the gear icon in the video information and select “Show transcript” (if the transcript isn’t done yet, this option is still available. But the transcript pane will just tell you to come back later)

Read through the transcript – an AI engine is used to perform the natural language processing, and the transcription accuracy *should* improve as you use the service. Click on “Edit”, make any corrections

Click “Done” to save your changes.

When your video is played, there is now a button to display closed captioning.

And the transcript will be displayed as the video progresses.

When you view the transcript, you can copy the entire thing & paste the transcript into OneNote or the meeting chat to have computer-generated meeting notes. I usually edit the transcript to remove the timestamps (and remove any tangential discussions).

 

Did you know … Microsoft Teams saves your un-sent chat messages?

While cognitive research says we focus best if we’re not switching topics every few minutes,sometimes I find myself needing to switch to a new channel in the middle of a thought. Desktop notifications, important content flags … but Teams will save what you’ve already typed even if you leave the channel or chat session.

I’ve switched over to the channel with that important activity – I can even send a new message here.

And when I return to my original channel, everything I’ve typed is still in there. Teams even saves the un-sent post if you close the client (I still copy my post to notepad just in case if I’m doing anything more than re-launching the browser to apply updates, but I haven’t needed the saved post content yet)

I can continue writing my post and send it.

Did you know … you can schedule meetings through Microsoft Teams?

You can! From the Teams side-bar, select Meetings.

At the bottom of your screen, along the left-hand side click “Schedule a meeting”.

Add the usual stuff – a title, time, agenda. Click under “Invite people” and type in some names to add people to the invitation. They don’t all have to work here – you can type in SMTP addresses as well.

Once you’ve added your attendees, click on “Scheduling assistant” to view attendee availability.

You will see each person’s published availability to the left of their name, and text under their name will indicate if they are free during the selected time interval.

Select a time and click “Schedule”.

A meeting summary is displayed. You can edit the meeting if needed or click close.

As attendees accept your invitation, you will see their acceptance within your meeting.

To attend the meeting, click the “Join” button.

If you’ve invited individuals who work outside of Windstream, they can still use the “Join Microsoft Teams Meeting” link to join the meeting. They’ll be joining anonymously, and someone will have to let them join the meeting … but they’ll get there too.

Did you know … you can name a Teams chat?

As you use Teams to chat with colleagues, you may find your “recent”chats include several entries with almost the same list of people. And now you’re clicking between groups with someone’s name to find the right group chat. Don’t! You can rename group chats to make it easier to find a specific conversation.

Within the group chat, click on the little pencil next to the participant names.

You will have an edit dialogue where you can add a group name – this is displayed to the other participants so select the name accordingly 😊 Click ‘Save’.

The conversation is now listed with the name you’ve supplied. Should you want to remove the name, simply click the pencil again and delete the name. Save a blank name, and the conversation will be titled with the participants again.

Did you know … you can get desktop notifications from the Microsoft Team web client?

The *one* disadvantage of using Teams in a web browser was not getting notifications for new activity, but the Teams web site now supports desktop notifications. Next time you log into Teams in a web browser, you’ll be asked if you want to turn on desktop notifications – click “Turn on”.

You may see an additional browser prompt asking you to confirm you wish to grant the Teams website the right to show notifications –click Allow.

If you have Windows 10 notifications enabled, you will now get notifications in the lower right-hand corner of your screen and the Windows notification panel.

You will get notifications even if you’ve disabled desktop notifications.When you are on the Teams tab, you’ll see notifications in the lower right-hand corner of the browser.

And when you are not on the Teams tab, you’ll see a number indicating the number of new notifications that have been sent.