Implemented support for contacts share, added stats command

main
Inga 🏳‍🌈 4 years ago
parent 3fd3e62576
commit 37d0c08281
  1. 7
      messages/UserInfo.csx
  2. 109
      messages/run.csx

@ -15,7 +15,7 @@ public class UserInfo
var userInfo = new UserInfo var userInfo = new UserInfo
{ {
Channel = channel, Channel = channel,
Id = infoFromChannelData.id?.ToString(), Id = (infoFromChannelData.id?.ToString() ?? infoFromChannelData.user_id?.ToString()),
Name = infoFromChannelData.username?.ToString(), Name = infoFromChannelData.username?.ToString(),
FirstName = infoFromChannelData.first_name?.ToString(), FirstName = infoFromChannelData.first_name?.ToString(),
LastName = infoFromChannelData.last_name?.ToString(), LastName = infoFromChannelData.last_name?.ToString(),
@ -44,6 +44,11 @@ public class UserInfo
return CreateFromTelegramChannelData(activity.ChannelId, ((dynamic)activity.ChannelData).message.forward_from); return CreateFromTelegramChannelData(activity.ChannelId, ((dynamic)activity.ChannelData).message.forward_from);
} }
public static UserInfo CreateFromTelegramContact(Activity activity)
{
return CreateFromTelegramChannelData(activity.ChannelId, ((dynamic)activity.ChannelData).message.contact);
}
[JsonProperty(PropertyName = "channel")] [JsonProperty(PropertyName = "channel")]
public string Channel { get; set; } public string Channel { get; set; }

@ -206,7 +206,7 @@ private static async Task RunForDelete(ConnectorClient client, Activity activity
await RunForList(client, activity, user, userSympathiesRepository, mutualSympathiesRepository, log); await RunForList(client, activity, user, userSympathiesRepository, mutualSympathiesRepository, log);
} }
private static async Task RunForBroadcastMessage(ConnectorClient client, Activity activity, string broadcastText, UsersRepository usersRepository, TraceWriter log) private static async Task RunForAdmin(ConnectorClient client, Activity activity, Func<Task> adminAction)
{ {
if (activity.From.Id.ToString() != "812607159") if (activity.From.Id.ToString() != "812607159")
{ {
@ -216,36 +216,80 @@ private static async Task RunForBroadcastMessage(ConnectorClient client, Activit
return; return;
} }
var messagesSent = 0; await adminAction();
List<string> usersFailed = new List<string>(); }
foreach (var userEntity in usersRepository.GetAllUsers())
{ private static async Task RunForBroadcastMessage(ConnectorClient client, Activity activity, string broadcastText, UsersRepository usersRepository, TraceWriter log)
var broadcastReply = userEntity.OriginalActivity.CreateReply($"Message from @{activity.From.Name}: {broadcastText}"); {
try await RunForAdmin(client, activity, async () => {
var messagesSent = 0;
List<string> usersFailed = new List<string>();
// NOTE: Sensitive data processing here,
// DO NOT memorize specific users, only store the messages count
foreach (var userEntity in usersRepository.GetAllUsers())
{ {
await client.Conversations.ReplyToActivityAsync(broadcastReply); var broadcastReply = userEntity.OriginalActivity.CreateReply($"Message from @{activity.From.Name}: {broadcastText}");
messagesSent++; try
{
await client.Conversations.ReplyToActivityAsync(broadcastReply);
messagesSent++;
}
catch (Exception)
{
usersFailed.Add(userEntity.PartitionKey);
}
} }
catch (Exception)
var reply = activity.CreateReply($"Message broadcast sent to {messagesSent} users: {broadcastText}");
await client.Conversations.ReplyToActivityAsync(reply);
if (usersFailed.Any())
{ {
usersFailed.Add(userEntity.UserInfo.ToString()); reply = activity.CreateReply($"Failed to send message to {usersFailed.Count} users: {string.Join(",", usersFailed)}");
await client.Conversations.ReplyToActivityAsync(reply);
} }
} });
}
var reply = activity.CreateReply($"Message broadcast sent to {messagesSent} users: {broadcastText}"); private static async Task RunForStats(
await client.Conversations.ReplyToActivityAsync(reply); ConnectorClient client,
Activity activity,
UsersRepository usersRepository,
UserSympathiesRepository userSympathiesRepository,
UserSympathiesRepository mutualSympathiesRepository,
TraceWriter log
)
{
await RunForAdmin(client, activity, async () => {
var usersCount = 0;
var sympathiesCount = 0;
var mutualSympathiesCount = 0;
// NOTE: Sensitive data processing here,
// DO NOT disaggregate per-user sympathies,
// DO NOT process separate users,
// ONLY aggregation of total users count / sympathies count (per-bot, NOT per-user) is allowed
foreach (var userEntity in usersRepository.GetAllUsers())
{
usersCount++;
try {
sympathiesCount += userSympathiesRepository.GetAllSympathies(userEntity.UserInfo).Count();
mutualSympathiesCount += mutualSympathiesRepository.GetAllSympathies(userEntity.UserInfo).Count();
} catch(Exception) {
var debugReply = activity.CreateReply("Malformed user:" + Environment.NewLine + "```" + Environment.NewLine + userEntity.PartitionKey + Environment.NewLine + JsonConvert.SerializeObject(userEntity.UserInfo) + Environment.NewLine + "```");
await client.Conversations.ReplyToActivityAsync(debugReply);
throw;
}
}
if (usersFailed.Any()) var reply = activity.CreateReply($"Total: {usersCount} users, {sympathiesCount} non-mutual sympathies, {mutualSympathiesCount} mutual sympathies");
{
reply = activity.CreateReply($"Failed to send message to {usersFailed.Count} users: {string.Join(",", usersFailed)}");
await client.Conversations.ReplyToActivityAsync(reply); await client.Conversations.ReplyToActivityAsync(reply);
} });
} }
private static async Task RunForSimpleMessage(ConnectorClient client, Activity activity, TraceWriter log) private static async Task RunForSimpleMessage(ConnectorClient client, Activity activity, TraceWriter log)
{ {
//await ReplyWithMarkdown(client, activity, $"```{Environment.NewLine}{JsonConvert.SerializeObject(activity)}{Environment.NewLine}```"); //await ReplyWithMarkdown(client, activity, $"```{Environment.NewLine}{JsonConvert.SerializeObject(activity)}{Environment.NewLine}```");
await ReplyWithHtml(client, activity, new XText("Forward me someone else's message")); await ReplyWithHtml(client, activity, new XText("Forward me someone else's message (preferred), or share their contact with me"));
} }
private static async Task RunForHelp(ConnectorClient client, Activity activity, TraceWriter log) private static async Task RunForHelp(ConnectorClient client, Activity activity, TraceWriter log)
@ -256,6 +300,8 @@ private static async Task RunForHelp(ConnectorClient client, Activity activity,
new [] { new [] {
new XText("Forward me someone else's message, and I'll remember that you like them (you can make me forget about that by using commands from /list)"), new XText("Forward me someone else's message, and I'll remember that you like them (you can make me forget about that by using commands from /list)"),
new XText(Environment.NewLine), new XText(Environment.NewLine),
new XText("Alternatively, you can share their contact with me, but message forwarding works better."),
new XText(Environment.NewLine),
new XText("Once they will forward me your message, I'll notify both of you that you like each other! Until then, I will keep silence."), new XText("Once they will forward me your message, I'll notify both of you that you like each other! Until then, I will keep silence."),
new XText(Environment.NewLine), new XText(Environment.NewLine),
new XText("What's more, if you two have some common person with mutual sympathies between all three of you, I'll notify all three about that!"), new XText("What's more, if you two have some common person with mutual sympathies between all three of you, I'll notify all three about that!"),
@ -299,6 +345,21 @@ private static async Task RunForMessage(
{ {
//var replyDebug = activity.CreateReply("Debug: " + Environment.NewLine + "```" + Environment.NewLine + JsonConvert.SerializeObject(activity) + Environment.NewLine + "```"); //var replyDebug = activity.CreateReply("Debug: " + Environment.NewLine + "```" + Environment.NewLine + JsonConvert.SerializeObject(activity) + Environment.NewLine + "```");
//await client.Conversations.ReplyToActivityAsync(replyDebug); //await client.Conversations.ReplyToActivityAsync(replyDebug);
var contact = ((dynamic)activity.ChannelData)?.message?.contact;
if (contact != null) {
await RunForSympathyMessage(
client,
activity,
userInfo,
UserInfo.CreateFromTelegramContact(activity),
userSympathiesRepository,
mutualSympathiesRepository,
log);
return;
}
var forwardedFrom = ((dynamic)activity.ChannelData)?.message?.forward_from; var forwardedFrom = ((dynamic)activity.ChannelData)?.message?.forward_from;
if (forwardedFrom != null) if (forwardedFrom != null)
{ {
@ -350,6 +411,16 @@ private static async Task RunForMessage(
usersRepository, usersRepository,
log); log);
} }
else if (text == "/stats")
{
await RunForStats(
client,
activity,
usersRepository,
userSympathiesRepository,
mutualSympathiesRepository,
log);
}
else else
{ {
await RunForSimpleMessage(client, activity, log); await RunForSimpleMessage(client, activity, log);

Loading…
Cancel
Save