Compare commits

...

7 Commits

Author SHA1 Message Date
Colton Sellers
09f2998f00 Address review + nits 2021-07-06 17:30:43 -07:00
Colton Sellers
ada08f861b Rename to ID, due to @ handles not usable 2021-07-06 17:01:39 -07:00
Colton Sellers
ec5ef7b323 Implement configurable token in NotificationTelegram 2021-07-06 16:44:21 -07:00
Colton Sellers
c701247022 Update comment docs 2021-07-06 16:44:21 -07:00
Colton Sellers
70db543cf2 Implement in JSON converter, and add roundtrip test 2021-07-06 16:44:21 -07:00
Colton Sellers
f216745b6f nit comments 2021-07-06 16:44:21 -07:00
Colton Sellers
b8f03e9ea1 Lay telegram notification groundwork 2021-07-06 16:44:21 -07:00
7 changed files with 95 additions and 10 deletions

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
@@ -156,4 +156,44 @@ namespace QuantConnect.Notifications
Headers = headers;
}
}
/// <summary>
/// Telegram notification data
/// </summary>
public class NotificationTelegram : Notification
{
/// <summary>
/// Send a notification message to this user on Telegram
/// Can be either a personal ID or Group ID.
/// </summary>
public string Id;
/// <summary>
/// Message to send. Limited to 4096 characters
/// </summary>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public string Message;
/// <summary>
/// Token to use
/// </summary>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public string Token;
/// <summary>
/// Constructor for sending a telegram notification to a specific User ID
/// or group ID. Note: The bot must have an open chat with the user or be
/// added to the group for messages to deliver.
/// </summary>
/// <param name="id">User Id or Group Id to send the message too</param>
/// <param name="message">Message to send</param>
/// <param name="token">Bot token to use, if null defaults to "telegram-token"
/// in config on send</param>
public NotificationTelegram(string id, string message, string token = null)
{
Id = id;
Message = message;
Token = token;
}
}
}

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
@@ -74,6 +74,12 @@ namespace QuantConnect.Notifications
return new NotificationWeb(token.ToString(), data?.ToString(), headers?.ToObject<Dictionary<string, string>>());
}
else if (jObject.TryGetValue("Id", StringComparison.InvariantCultureIgnoreCase, out token))
{
var message = jObject.GetValue("Message", StringComparison.InvariantCultureIgnoreCase);
var botToken = jObject.GetValue("Token", StringComparison.InvariantCultureIgnoreCase);
return new NotificationTelegram(token.ToString(), message?.ToString(), botToken?.ToString());
}
throw new NotImplementedException($"Unexpected json object: '{jObject.ToString(Formatting.None)}'");
}

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
@@ -122,6 +122,27 @@ namespace QuantConnect.Notifications
return true;
}
/// <summary>
/// Send a telegram message to the chat ID specified
/// Note: Requires bot to be added to have chat with user or
/// be in the group specified by ID.
/// </summary>
/// <param name="user">Chat or group ID to send message to</param>
/// <param name="message">Message to send</param>
/// <param name="token">Bot token to use for this message</param>
public bool Telegram(string id, string message, string token = null)
{
if (!Allow())
{
return false;
}
var telegram = new NotificationTelegram(id, message, token);
Messages.Enqueue(telegram);
return true;
}
/// <summary>
/// Maintain a rate limit of the notification messages per hour send of roughly 20 messages per hour.
/// </summary>

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
@@ -121,7 +121,7 @@ namespace QuantConnect.Messaging
public void SendNotification(Notification notification)
{
var type = notification.GetType();
if (type == typeof (NotificationEmail) || type == typeof (NotificationWeb) || type == typeof (NotificationSms))
if (type == typeof (NotificationEmail) || type == typeof (NotificationWeb) || type == typeof (NotificationSms) || type == typeof (NotificationTelegram))
{
Log.Error("Messaging.SendNotification(): Send not implemented for notification of type: " + type.Name);
return;
@@ -275,4 +275,4 @@ namespace QuantConnect.Messaging
{
}
}
}
}

View File

@@ -145,7 +145,8 @@ namespace QuantConnect.Messaging
var type = notification.GetType();
if (type == typeof (NotificationEmail)
|| type == typeof (NotificationWeb)
|| type == typeof (NotificationSms))
|| type == typeof (NotificationSms)
|| type == typeof(NotificationTelegram))
{
Log.Error("Messaging.SendNotification(): Send not implemented for notification of type: " + type.Name);
return;

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
@@ -72,7 +72,7 @@ namespace QuantConnect.Messaging
public void SendNotification(Notification notification)
{
var type = notification.GetType();
if (type == typeof(NotificationEmail) || type == typeof(NotificationWeb) || type == typeof(NotificationSms))
if (type == typeof(NotificationEmail) || type == typeof(NotificationWeb) || type == typeof(NotificationSms) || type == typeof(NotificationTelegram))
{
Log.Error("Messaging.SendNotification(): Send not implemented for notification of type: " + type.Name);
return;

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
@@ -77,6 +77,23 @@ namespace QuantConnect.Tests.Common.Notifications
Assert.AreEqual(expected.Headers, result.Headers);
}
[TestCase(true, true)]
[TestCase(true, false)]
[TestCase(false, true)]
[TestCase(false, false)]
public void TelegramRoundTrip(bool nullMessage, bool nullToken)
{
var expected = new NotificationTelegram("pepe", nullMessage ? null : "ImAMessage", nullToken ? null : "botToken");
var serialized = JsonConvert.SerializeObject(expected);
var result = (NotificationTelegram)JsonConvert.DeserializeObject<Notification>(serialized);
Assert.AreEqual(expected.Id, result.Id);
Assert.AreEqual(expected.Message, result.Message);
Assert.AreEqual(expected.Token, result.Token);
}
[Test]
public void CaseInsensitive()
{