Azure 関数を使用して、イベント ハブからメッセージを取得し、Azure 通知ハブを介して通知を送信しています。よく働く!ここで、これらのタグを介してユーザーをターゲティングできるようにするために、これらのメッセージにタグを追加できるかどうかを確認したいと考えました。
通知ハブの出力には、構成可能な「タグ式」パラメーターがあります。しかし、これは静的なテキストのようです。代わりに、イベント ハブから受信したメッセージに基づいてこれらのタグを動的に設定する必要があります。どうにか動的コンテンツをそこに入れることができるかどうかわかりませんか?
私が使用している GcmNotification オブジェクトのコンストラクターには、タグ文字列を使用できるオーバーロードがあることもわかりました。しかし、コンパイル時に警告が表示され、Tag プロパティが空である必要があるため、関数が起動するとエラーが表示されます。
したがって、a)これがまったく可能かどうか、およびb)可能な場合にどのように行うかについては明確ではありません。何か案は?
更新: 示唆されているように、入力文字列にマップする POCO オブジェクトを作成しようとしました。文字列は次のとおりです。
[{"deviceid":"repsaj-neptune-win10pi","readingtype":"temperature1","reading":22.031614503139451,"threshold":23.0,"time":"2016-06-22T09:38:54.1900000Z"}]
POCO オブジェクト:
public class RuleMessage
{
public string deviceid;
public string readingtype;
public object reading;
public double threshold;
public DateTime time;
}
RuleMessage[]
関数については、パラメーターの型として と の両方を試しましList<RuleMessage>
たが、関数は入力を変換できないと不平を言っています。
2016-06-24T18:25:16.830 関数の実行中に例外が発生しました: Functions.submerged-function-ruleout。Microsoft.Azure.WebJobs.Host: バインディング パラメーター 'inputMessage' の例外。Microsoft.Azure.WebJobs.Host: パラメーターを複雑なオブジェクト ('RuleMessage' など) にバインドするには、Json.NET シリアル化を使用します。1. パラメータ タイプを「RuleMessage」ではなく「文字列」としてバインドして生の値を取得し、JSON の逆シリアル化を回避します。または 2. キュー ペイロードを有効な json に変更します。JSON パーサーが失敗しました: 現在の JSON 配列 ([1,2,3] など) を型 'Submission#0+RuleMessage' に逆シリアル化できません。型には JSON オブジェクト ({"name":"value"} など) が必要なためです正しくデシリアライズします。このエラーを修正するには、JSON を JSON オブジェクトに変更します (例: {"name":"value" }) または、逆シリアル化された型を配列、または JSON 配列から逆シリアル化できる List のようなコレクション インターフェイス (ICollection、IList など) を実装する型に変更します。JsonArrayAttribute を型に追加して、強制的に JSON 配列から逆シリアル化することもできます。
機能コード:
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Microsoft.Azure.NotificationHubs;
public static void Run(List<RuleMessage> inputEventMessage, string inputBlob, out Notification notification, out string outputBlob, TraceWriter log)
{
if (inputEventMessage == null || inputEventMessage.Count != 1)
{
log.Info($"The inputEventMessage array was null or didn't contain exactly one item.");
notification = null;
outputBlob = inputBlob;
return;
}
log.Info($"C# Event Hub trigger function processed a message: {inputEventMessage[0]}");
if (String.IsNullOrEmpty(inputBlob))
inputBlob = DateTime.MinValue.ToString();
DateTime lastEvent = DateTime.Parse(inputBlob);
TimeSpan duration = DateTime.Now - lastEvent;
if (duration.TotalMinutes >= 0) {
notification = GetGcmMessage(inputMessage.First());
log.Info($"Sending notification message: {notification.Body}");
outputBlob = DateTime.Now.ToString();
}
else {
log.Info($"Not sending notification message because of timer ({(int)duration.TotalMinutes} minutes ago).");
notification = null;
outputBlob = inputBlob;
}
}
private static Notification GetGcmMessage(RuleMessage input)
{
string message;
if (input.readingtype == "leakage")
message = String.Format("[FUNCTION GCM] Leakage detected! Sensor {0} has detected a possible leak.", input.reading);
else
message = String.Format("[FUNCTION GCM] Sensor {0} is reading {1:0.0}, threshold is {2:0.0}.", input.readingtype, input.reading, input.threshold);
message = "{\"data\":{\"message\":\""+message+"\"}}";
return new GcmNotification(message);
}
public class RuleMessage
{
public string deviceid;
public string readingtype;
public object reading;
public double threshold;
public DateTime time;
}
2016 年 6 月 28 日更新: ASA の出力を、JSON 配列を生成しないように区切られた行に切り替えることで、うまく機能させることができませんでした。これはテンポです。出力に複数の行があるとすぐに関数バインディングが失敗するようになったため修正しました (発生する可能性があります)。
とにかく、次のように変更した指示に従って、tagExpression の設定に進みました。
{
"type": "notificationHub",
"name": "notification",
"hubName": "repsaj-neptune-notifications",
"connection": "repsaj-neptune-notifications_NOTIFICATIONHUB",
"direction": "out",
"tagExpression": "deviceId:{deviceid}"
}
は、 RuleMessage {deviceid}
POCO の deviceid プロパティと同じです。残念ながら、出力する関数を呼び出すと、これは機能しません。
関数の実行中に例外が発生しました: Functions.submerged-function-ruleout。Microsoft.Azure.WebJobs.Host: 例外バインド パラメーター '通知'。Microsoft.Azure.WebJobs.Host: 名前付きパラメーター 'deviceid' の値がありません。
これは正しくありません。出力ウィンドウにログを記録したので、プロパティが設定されていることは確かです。{inputEventMessage.deviceid} のようなものも試しましたが、どちらも機能しません (複数ある場合にランタイムが {deviceid} を正しい入力オブジェクトにマップする方法がわからないためです。