-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Function app developed through azure portal (#27)
* Azure function app for outbound, using azure portal. * Incorporated review comments * Improvements in content and code Co-authored-by: maulinasharma <[email protected]>
- Loading branch information
1 parent
1c88634
commit 9ed1a89
Showing
13 changed files
with
656 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
--- | ||
page_type: sample | ||
languages: | ||
- csharp | ||
products: | ||
- azure | ||
- azure-communication-services | ||
--- | ||
|
||
# Outbound Azure Function Sample | ||
|
||
This azure function sample send SMS, make an outbound call and play audio using ACS SMS and Server Calling SDKs on the basis of json input given in the following format. | ||
|
||
- `OutboundNumber`: Target phone number where we need to send notification. | ||
- `SourceNumber`: Phone number associated with the Azure Communication Service resource. | ||
- `SMS.Send`: value should be true/false as we want to send SMS or not. | ||
- `SMS.Message`: Message want to send as SMS. | ||
- `PhoneCall.Send`: value should be true/false as we want to make a phone call or not. | ||
- `PhoneCall.PlayAudioUrl`: The wav file url which accessible by the function app. If the value is empty, then the sample will use configured url through azure portal. | ||
|
||
The azure function is built on .NET Framework 4.7.2. | ||
|
||
``` | ||
{ | ||
"SourceNumber":"+18xxxxxxxxxx", | ||
"OutboundNumber": "+18xxxxxxxxxx", | ||
"SMS": { | ||
"Send": "true", | ||
"Message": "message to be sent" | ||
}, | ||
"PhoneCall": { | ||
"Send": "true", | ||
"PlayAudioUrl": "audio file URL function app can able to access" | ||
} | ||
} | ||
``` | ||
|
||
## Prerequisites | ||
|
||
- Create an Azure account with an active subscription. For details, see [Create an account for free](https://azure.microsoft.com/free/) | ||
- [Visual Studio (2019 and above)](https://visualstudio.microsoft.com/vs/) | ||
- [.NET Framework 4.7.2](https://dotnet.microsoft.com/download/dotnet-framework/net472) (Make sure to install version that corresponds with your visual studio instance, 32 vs 64 bit) | ||
- Create an Azure Communication Services resource. For details, see [Create an Azure Communication Resource](https://docs.microsoft.com/azure/communication-services/quickstarts/create-communication-resource). You'll need to record your resource **connection string** for this sample. | ||
- Get a phone number for your new Azure Communication Services resource. For details, see [Get a phone number](https://docs.microsoft.com/azure/communication-services/quickstarts/telephony-sms/get-phone-number?pivots=platform-azp) | ||
|
||
## Code structure | ||
|
||
- ./OutboundFunction/SendNotification.cs : Azure function to send notification using phone call and SMS. | ||
- ./OutboundFunction/OutboundController.cs : Azure function to handle outbound callbacks | ||
- ./OutboundFunction/Phonecall.cs : class for handling outbound phone call. | ||
- ./OutboundFunction/SendSms.cs : class for sending SMS notification. | ||
- ./OutboundFunction/EventHandler/*.cs : Code for managing callbacks and request authorization. | ||
|
||
## Before running the sample for the first time | ||
|
||
- Open an instance of PowerShell, Windows Terminal, Command Prompt or equivalent and navigate to the directory that you'd like to clone the sample to. | ||
- git clone `https://github.com/Azure-Samples/communication-services-dotnet-quickstarts.git`. | ||
- Once you get the config keys add the keys as an environment variable. | ||
- Input your connection string in variable: `Connectionstring` | ||
- Input you Secret/Password that would be part of callback and will be use to validate incoming requests in variable `SecretPlaceholder` | ||
- Input URL of default wav file going to play in outbound phone call in variable `CallbackUri` | ||
|
||
## Locally deploying the sample app | ||
|
||
- Go to OutboundFunction folder and open `OutboundFunction.sln` solution in Visual Studio | ||
- Run `OutboundFunction` project. | ||
- Use postman or any debugging tool and use function URL - http://localhost:7071/api/SendNotification with the json request. | ||
|
||
## Publish to Azure | ||
|
||
[Publish the project to Azure](https://docs.microsoft.com/azure/azure-functions/functions-create-your-first-function-visual-studio#publish-the-project-to-azure) | ||
|
||
### Configuring Azure Function Sample | ||
|
||
After publishing your function App, add following configuration in your function App's `configuration` section. | ||
|
||
- Connectionstring: Azure Communication Service resource's connection string. | ||
- SourcePhone: Phone number associated with the Azure Communication Service resource. | ||
- SecretPlaceholder: Secret/Password that would be part of callback and will be use to validate incoming requests. | ||
- AudioFileUrl: Url of default wav file going to play in outbound phone call which is accessible by function app. |
22 changes: 22 additions & 0 deletions
22
...lReminder/OutboundFunction_AzurePortal/SendNotification/EventHandler/EventAuthHandler.csx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using Microsoft.AspNetCore.Http; | ||
using System; | ||
using System.Web; | ||
|
||
public class EventAuthHandler | ||
{ | ||
private static readonly string SecretKey = "secret"; | ||
private static readonly string SecretValue; | ||
|
||
static EventAuthHandler() | ||
{ | ||
SecretValue = Environment.GetEnvironmentVariable("SecretPlaceholder") ?? "h3llowW0rld"; | ||
} | ||
|
||
public static bool Authorize(HttpRequest request) | ||
{ | ||
string secretKeyValue = request.Query[SecretKey].ToString(); | ||
return !string.IsNullOrEmpty(secretKeyValue) && secretKeyValue.Equals(SecretValue); | ||
} | ||
|
||
public static string GetSecretQuerystring => $"{SecretKey}={HttpUtility.UrlEncode(SecretValue)}"; | ||
} |
95 changes: 95 additions & 0 deletions
95
...llReminder/OutboundFunction_AzurePortal/SendNotification/EventHandler/EventDispatcher.csx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
#load "EventExtensions.csx" | ||
|
||
using Azure.Communication.CallingServer; | ||
using Azure.Messaging; | ||
using System; | ||
using System.Collections.Concurrent; | ||
using System.Threading.Tasks; | ||
|
||
public class EventDispatcher | ||
{ | ||
private static readonly EventDispatcher instance; | ||
private static readonly ConcurrentDictionary<string, NotificationCallback> notificationCallbacks; | ||
|
||
public static EventDispatcher Instance | ||
{ | ||
get | ||
{ | ||
return instance; | ||
} | ||
} | ||
|
||
static EventDispatcher() | ||
{ | ||
instance = new EventDispatcher(); | ||
notificationCallbacks = new ConcurrentDictionary<string, NotificationCallback>(StringComparer.OrdinalIgnoreCase); | ||
} | ||
|
||
public bool Subscribe(string eventType, string eventKey, NotificationCallback notificationCallback) | ||
{ | ||
string eventId = BuildEventKey(eventType, eventKey); | ||
bool ret = notificationCallbacks.TryAdd(eventId, notificationCallback); | ||
return ret; | ||
} | ||
|
||
public void Unsubscribe(string eventType, string eventKey) | ||
{ | ||
string eventId = BuildEventKey(eventType, eventKey); | ||
notificationCallbacks.TryRemove(eventId, out _); | ||
} | ||
|
||
public void ProcessNotification(string request) | ||
{ | ||
var callEvent = this.ExtractEvent(request); | ||
|
||
if (callEvent != null) | ||
{ | ||
if (notificationCallbacks.TryGetValue(GetEventKey(callEvent), out NotificationCallback notificationCallback)) | ||
{ | ||
if (notificationCallback != null) | ||
{ | ||
Task.Run(() => | ||
{ | ||
notificationCallback.Callback.Invoke(callEvent); | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
|
||
public string GetEventKey(CallingServerEventBase callEventBase) | ||
{ | ||
if (callEventBase is CallConnectionStateChangedEvent) | ||
{ | ||
var callLegId = ((CallConnectionStateChangedEvent)callEventBase).CallConnectionId; | ||
return BuildEventKey(CallingServerEventType.CallConnectionStateChangedEvent.ToString(), callLegId); ; | ||
} | ||
|
||
return null; | ||
} | ||
|
||
public string BuildEventKey(string eventType, string eventKey) | ||
{ | ||
return $"{eventType}-{eventKey}"; | ||
} | ||
|
||
/// <summary> | ||
/// Extracting event from the json. | ||
/// </summary> | ||
/// <param name="content"></param> | ||
/// <returns></returns> | ||
public CallingServerEventBase ExtractEvent(string content) | ||
{ | ||
CloudEvent cloudEvent = CloudEvent.Parse(BinaryData.FromString(content)); | ||
|
||
if (cloudEvent != null && cloudEvent.Data != null) | ||
{ | ||
if (cloudEvent.Type.Equals(CallingServerEventType.CallConnectionStateChangedEvent.ToString())) | ||
{ | ||
return CallConnectionStateChangedEvent.Deserialize(cloudEvent.Data.ToString()); | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
...llReminder/OutboundFunction_AzurePortal/SendNotification/EventHandler/EventExtensions.csx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using Azure.Communication.CallingServer; | ||
using System; | ||
|
||
public class NotificationCallback | ||
{ | ||
public Action<CallingServerEventBase> Callback { get; set; } | ||
|
||
public NotificationCallback(Action<CallingServerEventBase> callBack) | ||
{ | ||
this.Callback = callBack; | ||
} | ||
} |
Oops, something went wrong.