Implemented support for contacts share, added stats command

main
Inga 🏳‍🌈 3 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
{
Channel = channel,
Id = infoFromChannelData.id?.ToString(),
Id = (infoFromChannelData.id?.ToString() ?? infoFromChannelData.user_id?.ToString()),
Name = infoFromChannelData.username?.ToString(),
FirstName = infoFromChannelData.first_name?.ToString(),
LastName = infoFromChannelData.last_name?.ToString(),
@ -44,6 +44,11 @@ public class UserInfo
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")]
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);
}
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")
{
@ -216,36 +216,80 @@ private static async Task RunForBroadcastMessage(ConnectorClient client, Activit
return;
}
var messagesSent = 0;
List<string> usersFailed = new List<string>();
foreach (var userEntity in usersRepository.GetAllUsers())
{
var broadcastReply = userEntity.OriginalActivity.CreateReply($"Message from @{activity.From.Name}: {broadcastText}");
try
await adminAction();
}
private static async Task RunForBroadcastMessage(ConnectorClient client, Activity activity, string broadcastText, UsersRepository usersRepository, TraceWriter log)
{
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);
messagesSent++;
var broadcastReply = userEntity.OriginalActivity.CreateReply($"Message from @{activity.From.Name}: {broadcastText}");
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}");
await client.Conversations.ReplyToActivityAsync(reply);
private static async Task RunForStats(
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())
{
reply = activity.CreateReply($"Failed to send message to {usersFailed.Count} users: {string.Join(",", usersFailed)}");
var reply = activity.CreateReply($"Total: {usersCount} users, {sympathiesCount} non-mutual sympathies, {mutualSympathiesCount} mutual sympathies");
await client.Conversations.ReplyToActivityAsync(reply);
}
});
}
private static async Task RunForSimpleMessage(ConnectorClient client, Activity activity, TraceWriter log)
{
//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)
@ -256,6 +300,8 @@ private static async Task RunForHelp(ConnectorClient client, Activity activity,
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(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(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!"),
@ -299,6 +345,21 @@ private static async Task RunForMessage(
{
//var replyDebug = activity.CreateReply("Debug: " + Environment.NewLine + "```" + Environment.NewLine + JsonConvert.SerializeObject(activity) + Environment.NewLine + "```");
//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;
if (forwardedFrom != null)
{
@ -350,6 +411,16 @@ private static async Task RunForMessage(
usersRepository,
log);
}
else if (text == "/stats")
{
await RunForStats(
client,
activity,
usersRepository,
userSympathiesRepository,
mutualSympathiesRepository,
log);
}
else
{
await RunForSimpleMessage(client, activity, log);

Loading…
Cancel
Save