Twilio Sending SMS from a SharePoint List

The following example can be worked into event receivers, workflow, etc – for simplicity and due to time constraints I used a console application.

For this simple PoC I wanted to send text messages from a SharePoint list, I signed up for a Twilio (https://www.twilio.com/) trial, Twilio offer a very good api for dealing with SMS and voice calls.

I’ve created a new console application and installed two nuget packages:

Install-Package Microsoft.SharePointOnline.CSOM

Install-Package Twilio

The following code assumes you have created a Client Context…

The code below is standard SharePoint code, this deals with getting the data from the list, and populating a dictionary containing the recipients number, and the message to be sent.  I also update the list item so I know it has been processed.

using (var context = new ClientContext(contextWebUrl))
            {
                context.Credentials = new SharePointOnlineCredentials(userName, password);
                Web web = context.Web;
                context.Load(context.Web, w => w.Title);
                context.ExecuteQuery();

                List sms = web.Lists.GetByTitle("SMS");
                context.Load(sms);
                context.ExecuteQuery();

                CamlQuery query = CamlQuery.CreateAllItemsQuery(100);
                ListItemCollection items = sms.GetItems(query);
                context.Load(items);
                context.ExecuteQuery();

                Dictionary<string, string> messageToSend = new Dictionary<string, string>();
                context.Load(items);
                context.ExecuteQuery();

                foreach (ListItem item in items)
                {
                    if (string.Equals(item["Status"], "new"))
                    {
                        context.Load(item);
                        context.ExecuteQuery();
                        messageToSend.Add(item["Title"].ToString(), item["Body"].ToString());
                        item["Status"] = "Sent";
                        item.Update();
                        context.ExecuteQuery();
                    }
                }
          }

The next piece of code deals with sending the messages (this is rough and ready code – purely for a PoC)..

            string AccountSid = "xxxxxxxxxxxxxxxxxxxxxxxx";
            string AuthToken = "xxxxxxxxxxxxxxxxxxxxx";
            var twilio = new TwilioRestClient(AccountSid, AuthToken);

            foreach (var msg in messageToSend)
            {
                var newMsg = twilio.SendMessage("My Twilio Number", msg.Key, msg.Value);
                Console.WriteLine(newMsg.Sid + " " + newMsg.Status);
            }

Once you have a Twilio trial account, you’ll get a phone number, and credentials for interacting with the API.

The next article covers building a web API to receive text messages.

SharePoint Online (2013) Unique List Items Limit

I found conflicting information on the number of items within a list that can contain unique item permissions, a number of resources said 5000, and some mentioned 50000 – however these limits were for SharePoint 2010/2013 on-prem and no information around SharePoint Online.

After a quick test, I can confirm there is a hard limit at 50000 items that can contain unique permissions.

Running a PowerShell CSOM script to create 55000 items, the script failed at 50001 items with the error:

Exception calling “ExecuteQuery” with “0” argument(s): “You cannot break inheritance for this item because there are too many items with unique permissions

Script snippet:

$list = $web.Lists.GetByTitle('limit')
$ctx.Load($list)
$ctx.ExecuteQuery()

$count = 0
$push = 0

for($count -eq 0; $count -lt 55000; $count++)
{ 
Write-Host "adding $count"
$ListItemInfo = New-Object Microsoft.SharePoint.Client.ListItemCreationInformation
$Item = $list.AddItem($ListItemInfo)
$Item["Title"] = $count
$ctx.Load($list)
$item.BreakRoleInheritance($True, $true);
$Item.Update() 
$push++

if($push -eq 50)
{
$ctx.ExecuteQuery()
$push = 0
Write-Host "pushed"
}
}


Uploading files to a specific folder within a SharePoint document library using CSOM + PowerShell

Uploading files to a specific folder within a SharePoint document library using Client Side Object Model + PowerShell….

# Source folder, for example the display templates folder within the masterpage gallery
$sourceFolder = "_catalogs/masterpage/Display%20Templates/Content%20Web%20Parts"

#file path, location of the file to upload
£filePath = "C:\Projects\POC\Upload\Control_Default.html"

$sourceFolder = $ctx.Web.GetFolderByServerRelativeUrl($relativeFolderLocation);
$ctx.Load($sourceFolder)
$ctx.ExecuteQuery()

$filePath = Get-ChildItem $filePath	
$fileBytes = [System.IO.File]::ReadAllBytes($filePath.FullName)

$fileinfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
$fileinfo.Content = $fileBytes
$fileinfo.Url = $relativeFolderLocation + "/" + $filePath.Name
$fileinfo.Overwrite = $true

$ctx.Load($sourceFolder.Files.Add($fileinfo))
$ctx.ExecuteQuery()
Add-LogMessage -message "Adding file to document library"

SharePoint 2013 Search (Office 365)

I was hunting for information on query suggestions for Office 365….query suggestions are handled in two ways:

1: You can upload your own query suggestions through the admin portal

2: SharePoint will dynamical build a list of query suggestions based on previous searches and click throughs:

SharePoint automatically creates a query suggestion when users have clicked a search result for a query at least six times. For example, if users have entered the query word “coffee” and then clicked on a search result six times, then “coffee” automatically becomes a query suggestion.

Source:

http://blogs.technet.com/b/tothesharepoint/archive/2013/12/05/create-and-import-query-suggestions-in-sharepoint-2013.aspx

 

SharePoint 2013 – Getting Content Type by Name – CSOM

Following scenario is using PowerShell and the Client Side Object Model..

Task: Get a specific Content Type by name rather than ID – as we don’t know what the ID is!

### ASSUMES CONNECTION TO CLIENT CONTEXT - $CTX ###
# Get the web context
$web = $ctx.Web
$ctx.Load($web)
$ctx.ExecuteQuery(
# Gets a collection of available content types
$contentTypesColl = $web.AvailableContentTypes
$load = [Microsoft.SharePoint.Client.ClientContext].GetMethod("Load")
$listLoad = $load.MakeGenericMethod([Microsoft.SharePoint.Client.ContentTypeCollection])
$listLoad.Invoke($ctx,@($contentTypesColl,$null))
$ctx.ExecuteQuery()
# Iterate through the content types matching the name
# Once match is found, save content type ID to a variable
$LegalDocId = 0;
foreach($ctype in $contentTypesColl)
{
$i = 0
if($ctype[$i].Name -eq "Legal Document")
{
Write-Host $ctype[$i].Name -ForegroundColor Cyan
$LegalDocId = $ctype[$i].Id
break;
}

$i++
}
# Once content type ID is found, apply content type to a document library
if($LegalDocId -ne '0')
{
# Get the library
$lib = $web.Lists.GetByTitle("Documents")
$ctx.Load($lib)

# Enable content types
$lib.ContentTypesEnabled = $true
$lib.Update()
# Apply the content type
$contentType = $web.ContentTypes.GetById($LegalDocId.ToString())
$ctx.Load($contentType)
Add-LogMessage -message "Adding content type to library"
$ctx.Load($lib.ContentTypes.AddExistingContentType($web.ContentTypes.GetById($LegalDocId.ToString())))

# Update the library
$lib.Update()
$ctx.ExecuteQuery()
}