Detect text language from files in SharePoint with AI and Flow

In a correlation with my previous blog post I want to share with you solution how you could detect text language from files in SharePoint Document Library. All can be done with help of Microsoft FlowText Analytics API and Azure Functions.

After language detection you want to save language name (English, Slovenian etc.) to one of Managed Metadata Field named Language. Because there we have Terms, you have to define it in format “Name|Guid”. I used Azure Functions to get Term Guid from Name with help of TaxonomySession from Microsoft.SharePoint.Client.Taxonomy library.

I took Flow from my previous blog post solution and add this part of actions to it:

2018-05-14_2223

So, open Flow from previous blog post and add new step just before last action Update item.

2018-05-14_1440

Then search for Text Analytics – Detect Language action.

2018-05-14_1440_001

You have to define text for Language detection. We have Detected Text from one of previous step (OCR).

2018-05-14_1441

From this step we get back list of all detected languages with Language Code, Name and Score. We need only Name in further steps.

But firstly, go into Term store management from SharePoint Site Settings. Create new Group named Custom with Term Set named Language. Add two Terms into it: English, Slovenian.

2018-05-15_0801

When we want to save specific Term into Managed Metadata Field we have to specify it with Name and Guid. If you go into English Term you could find GUID in the bottom of the page.

2018-05-15_0804

So in my example I will write it like “English|16d084fb-6c4e-440b-a92b-25601d8373b5”.

Then open Images Document Library created in previous blog post and create new Managed Metadata field named Language. Link it to Language Term Set created before.

From Detect Language step in Flow we get only language name – English. But we need Guid too, so we have to ask Language Term Set for Guid of specific language Term. For that reason I user Azure Functions.

Go to your portal.azure.com page and create new Function App named GetTermFromTermSet.

Create new function inside Function App …

2018-05-14_2011

… and select HTTP trigger with C# language.

2018-05-14_2012

2018-05-14_2012_001

Then select platform features / Advanced tools (Kudu).

2018-05-15_0813.png

Open Debug console / PowerShell and go into the site/wwwroot/HttpTriggerCSharp1 folder. Create bin folder inside it and drag&drop next assemblies from your local SharePoint 2016 ISAPI hive folder:

  • Microsoft.SharePoint.Client.dll
  • Microsoft.SharePoint.Client.Runtime.dll
  • Microsoft.SharePoint.Client.Taxonomy.dll

Then open run.csx file and copy code below into it. This code is main code for our Azure Function.

#r "Microsoft.SharePoint.Client.Runtime.dll" 
#r "Microsoft.SharePoint.Client.dll"
#r "Microsoft.SharePoint.Client.Taxonomy.dll"

using System.Net;
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.Taxonomy;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    string termName = req.GetQueryNameValuePairs()
        .FirstOrDefault(q => string.Compare(q.Key, "termName", true) == 0)
        .Value;

    string email = "xyz@xyz.onmicrosoft.com";
    string password = "Pa$$w0rd";
    string webUrl = "https://xyz.sharepoint.com/sites/dev";

    string groupName = "Custom";
    string termSetName = "Language";

    System.Security.SecureString securePassword = new System.Security.SecureString(); 
    foreach (char pass in password) {
        securePassword.AppendChar(pass);
    } 

    SharePointOnlineCredentials spOnlineCredentials = new SharePointOnlineCredentials(email, securePassword); 
    try
    {  
        using (var ctx = new ClientContext(webUrl))
        {
            ctx.Credentials = spOnlineCredentials;
            Web web = ctx.Site.RootWeb;

            TaxonomySession taxonomySession = TaxonomySession.GetTaxonomySession(web.Context);

            web.Context.Load(taxonomySession);
            web.Context.ExecuteQuery();

            TermStore termStore = taxonomySession.GetDefaultSiteCollectionTermStore();

            web.Context.Load(termStore.Groups);
            web.Context.ExecuteQuery();

            TermGroup group = CheckIfTermGroupExists(termStore, groupName)
                ? termStore.Groups.GetByName(groupName)
                : termStore.CreateGroup(groupName, Guid.NewGuid());

            web.Context.Load(group.TermSets);
            web.Context.ExecuteQuery();

            TermSet termSet = CheckIfTermSetExists(group, termSetName) ? group.TermSets.GetByName(termSetName) : group.CreateTermSet(termSetName, Guid.NewGuid(), 1033);

            web.Context.Load(termSet.Terms);
            web.Context.ExecuteQuery();

            Term term = CheckIfTermExists(termSet, termName) ? termSet.Terms.GetByName(termName) : null;

            web.Context.Load(term);
            web.Context.ExecuteQuery();

            return req.CreateResponse(HttpStatusCode.OK, term.Name + "|" + term.Id);
        }
    } 
    catch(Exception ex){ 
        log.Info($"Azure Function Exception: {ex.Message}"); 
        return req.CreateResponse(HttpStatusCode.BadRequest, ex.Message);
    }    
}

public static bool CheckIfTermGroupExists(TermStore termStore, string groupName)
{
    foreach (TermGroup group in termStore.Groups)
    {
        if (@group.Name == groupName)
        {
            return true;
        }
    }
    return false;
}

public static bool CheckIfTermSetExists(TermGroup group, string termSetName)
{
    foreach (TermSet termSet in @group.TermSets)
    {
        if (termSet.Name == termSetName)
        {
            return true;
        }
    }
    return false;
}

public static bool CheckIfTermExists(TermSet termSet, string termName)
{
    foreach (Term term in @termSet.Terms)
    {
        if (term.Name == termName)
        {
            return true;
        }
    }
    return false;
}

As you can see, we get termName querystring parameter and we ask specific Term Set in specific Group for Term with this specific Term name.

Save all changes and copy function URL from Get function URL link.

2018-05-15_0826

Your URL looks like this below:

https://gettermfromtermset.azurewebsites.net/api/HttpTriggerCSharp1?code={some-custom-code}==

Go back into your Flow and add new HTTP step for calling this Azure Function via URL above.

2018-05-15_0828

Copy URL into URI field and append &termName= string into it with Name variable from Detect Language step.

Last but not least you have to update Update item action with Language Value. Save Body from HTTP step into it.

2018-05-15_0831

Thats all folks. Open Images Document Library in your SharePoint. Add images into it in you can see text language inside of Language Managed Metadata Field.

2018-05-15_0834

In example above we have this two images inside Library:

Cheers!
Gašper Rupnik

{End.}

Advertisements

2 thoughts on “Detect text language from files in SharePoint with AI and Flow

Add yours

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Powered by WordPress.com.

Up ↑

%d bloggers like this: