public async Task UnsubscribeMenu(string[] values) { //Ensure subscriptions are enabled: if (!_subscriptions.ModuleEnabled) { await RespondAsync("Subscriptions module is currently disabled.", ephemeral : true); return; } //Buy more time to process posts: await DeferAsync(true); foreach (string encodedData in values) { // Split String: long IGID = long.Parse(encodedData.Split("-")[0]); ulong chanID = ulong.Parse(encodedData.Split("-")[1]); // Remove Subscribe: try { await _subscriptions.UnsubscribeToAccount(IGID, chanID, Context.Guild.Id); } catch (ArgumentException e) when(e.Message.Contains("Cannot find user.")) { await FollowupAsync("Error: You are not subscribed to that user.", ephemeral : true); return; } string username; try { // Get IG account: InstagramProcessor instagram = new InstagramProcessor(InstagramProcessor.AccountFinder.GetIGAccount()); username = await instagram.GetIGUsername(IGID.ToString()); } catch { username = "******"; } try { // Get Channel: var chan = Context.Guild.GetChannel(chanID) as SocketTextChannel; // Notify: await chan.SendMessageAsync("This channel has been unsubscribed to " + username + " on Instagram by " + Context.User.Mention, allowedMentions : AllowedMentions.None); } catch (Exception e) { Console.WriteLine(e); // Failed to send message (chan might have been deleted). } } await FollowupAsync("Success! You will no longer receive new posts to the selected channel(s).", ephemeral : true); }
public async Task Subscribed() { // Check whitelist: if (!Whitelist.IsServerOnList(((Context.Guild == null) ? (0) : (Context.Guild.Id)))) { // Self-hosted whitelist notification for official bot: if (Context.Client.CurrentUser.Id == 815695225678463017) { await RespondAsync("This bot is now self-host only. Learn more about this change in the updates channel on the support server: https://discord.gg/8dkjmGSbYE", ephemeral : true); } else { await RespondAsync("This guild is not on the whitelist. The command was blocked.", ephemeral : true); } return; } //Ensure subscriptions are enabled: if (!_subscriptions.ModuleEnabled) { await RespondAsync("Subscriptions module is currently disabled.", ephemeral : true); return; } // buy time: await DeferAsync(false); // Get IG account: InstagramProcessor instagram = new InstagramProcessor(InstagramProcessor.AccountFinder.GetIGAccount()); List <Embed> embeds = new List <Embed>(); var embed = new EmbedBuilder(); embed.Title = "Guild Subscriptions"; embed.WithColor(new Color(131, 58, 180)); var subs = await _subscriptions.GuildSubscriptionsAsync(Context.Guild.Id); embed.Description = subs.Count() + " of " + await _subscriptions.MaxSubscriptionsCountForGuildAsync(Context.Guild.Id) + " subscribes used.\n**Instagram Accounts:**"; string accountOutput = ""; string channelOutput = ""; foreach (FollowedIGUser user in subs) { foreach (RespondChannel chan in user.SubscribedChannels) { if (chan.GuildID.Equals(Context.Guild.Id.ToString())) { string chanMention = "Missing channel.\n"; if (Context.Guild.GetChannel(ulong.Parse(chan.ChannelID)) is not null) { chanMention = "<#" + Context.Guild.GetChannel(ulong.Parse(chan.ChannelID)).Id + ">\n"; } string username = await instagram.GetIGUsername(user.InstagramID); string accountMention = "- Deleted Account\n"; if (username is not null) { accountMention = "- [" + username + "](https://www.instagram.com/" + username + ")\n"; } if ((accountOutput + accountMention).Length <= 1024 && (channelOutput + chanMention).Length <= 1024) { accountOutput += accountMention; channelOutput += chanMention; } else { embed.AddField("Account", accountOutput, true); embed.AddField("Channel", channelOutput, true); embeds.Add(embed.Build()); //Restart new embed: embed = new EmbedBuilder(); embed.WithColor(new Color(131, 58, 180)); accountOutput = accountMention; accountOutput = chanMention; } } } } if (subs.Length == 0) { embed.Description = "No accounts followed. Get started by using `/subscribe`"; } else { embed.AddField("Account", accountOutput, true); embed.AddField("Channel", channelOutput, true); } embeds.Add(embed.Build()); await FollowupAsync(embeds : embeds.ToArray()); }
/// <summary> /// Checks any account with the RecheckSubscribedAccounts bool set to true. Unsubscribes if applicable. /// </summary> /// <returns></returns> public async Task UnsubscribeOverSubscriptions() { // Get IG account: InstagramProcessor instagram = new InstagramProcessor(InstagramProcessor.AccountFinder.GetIGAccount()); List <PremiumGuild> queryable = PremiumGuildsContainer.Find(x => x.RecheckSubscribedAccounts).ToListAsync().Result; foreach (PremiumGuild pguild in queryable.ToArray()) { int maxAccounts = await MaxSubscriptionsCountForGuildAsync(ulong.Parse(pguild.GuildID)); int currentAccounts = await GuildSubscriptionCountAsync(ulong.Parse(pguild.GuildID)); if (currentAccounts > maxAccounts) { Console.WriteLine("Guild over limit."); int NumberOfAccountsToRemove = currentAccounts - maxAccounts; List <FollowedIGUser> queryableIG = FollowedAccountsContainer.Find(x => x.SubscribedChannels.Any(n => n.GuildID == pguild.GuildID)).ToListAsync().Result; foreach (FollowedIGUser igAccount in queryableIG.ToArray()) { if (NumberOfAccountsToRemove <= 0) { break; } //Get all to be removed: RespondChannel[] chans = igAccount.SubscribedChannels.FindAll(item => item.GuildID.Equals(pguild.GuildID)).ToArray(); foreach (RespondChannel chan in chans) { //Remove: igAccount.SubscribedChannels.Remove(chan); //Notify: var discordChan = _client.GetChannel(ulong.Parse(chan.ChannelID)) as IMessageChannel; await discordChan.SendMessageAsync("This channel has been automatically unsubscribed to " + (await instagram.GetIGUsername(igAccount.InstagramID)) + " as it exceeded the guild's maximum subscription limit."); } //Update Database: await this.FollowedAccountsContainer.ReplaceOneAsync(x => x.InstagramID == igAccount.InstagramID, igAccount, new ReplaceOptions { IsUpsert = true }); NumberOfAccountsToRemove--; } } pguild.RecheckSubscribedAccounts = false; await this.PremiumGuildsContainer.ReplaceOneAsync(x => x.GuildID == pguild.GuildID, pguild, new ReplaceOptions { IsUpsert = true }); } }
public async Task Unsubscribe() { //Ensure subscriptions are enabled: if (!_subscriptions.ModuleEnabled) { await RespondAsync("Subscriptions module is currently disabled.", ephemeral : true); return; } //Buy more time to process: await DeferAsync(false); // Get Accounts: var subs = await _subscriptions.GuildSubscriptionsAsync(Context.Guild.Id); // Create Dropdown with channels: var menuBuilder = new SelectMenuBuilder() .WithCustomId("unsubscribe") .WithPlaceholder("Select accounts to remove.") .WithMinValues(0); // Get IG account: InstagramProcessor instagram = new InstagramProcessor(InstagramProcessor.AccountFinder.GetIGAccount()); // Add users to dropdown: foreach (FollowedIGUser user in subs) { foreach (RespondChannel chan in user.SubscribedChannels) { // Get username: string username = await instagram.GetIGUsername(user.InstagramID); if (username == null) { username = "******"; } string channelName = Context.Guild.GetChannel(ulong.Parse(chan.ChannelID))?.Name; // Channel null check: if (channelName is null) { channelName = "Unknown Channel"; } // Add account option to menu: SelectMenuOptionBuilder optBuilder = new SelectMenuOptionBuilder() .WithLabel(username) .WithValue(user.InstagramID + "-" + chan.ChannelID) .WithDescription(username + " in channel " + channelName); menuBuilder.AddOption(optBuilder); } } // Check for subs: if (subs.Length < 1) { await FollowupAsync("No accounts subscribed."); return; } // Make embed: var embed = new EmbedBuilder(); embed.Title = "Unsubscribe"; embed.Description = "Select accounts that you would like to unsubscribe from in the dropdown below."; embed.WithColor(new Color(131, 58, 180)); // Set max count: menuBuilder.WithMaxValues(menuBuilder.Options.Count); // Component Builder: var builder = new ComponentBuilder() .WithSelectMenu(menuBuilder) .WithButton("Delete Message", $"delete-message-{Context.User.Id}", style: ButtonStyle.Danger); // Send message await FollowupAsync(embed : embed.Build(), components : builder.Build()); }
/// <summary> /// Gets the latests posts for all subscriptions /// </summary> /// <returns></returns> public async Task GetLatestsPosts() { //Ensure module is enabled. if (!ModuleEnabled) { Console.WriteLine("Module disabled."); return; } if (InSubLoop) { //Prevents multiple loops running at once which could cause an instagram block. Console.WriteLine("Already in loop. Skipping."); return; } else { InSubLoop = true; } try { //Unsubscribe oversubs: await UnsubscribeOverSubscriptions(); Console.WriteLine("Getting new posts!"); var getdbfeed = await FollowedAccountsContainer.Find(_ => true).ToListAsync(); //Randomize the order of the IG accounts: Random rand = new Random(); getdbfeed.OrderBy(item => rand.Next()); foreach (var dbfeed in getdbfeed) { Console.WriteLine("Checking " + dbfeed.InstagramID); try { // Get IG account: InstagramProcessor instagram = new InstagramProcessor(InstagramProcessor.AccountFinder.GetIGAccount()); //Check to see if there is any channel that is subscribed to IG accounts: if (dbfeed.SubscribedChannels.Count == 0) { //If not, delete. await this.FollowedAccountsContainer.DeleteOneAsync(x => x.InstagramID == dbfeed.InstagramID); } else //Otherwise proceed: { //Set last check as now: dbfeed.LastCheckTime = DateTime.Now; var newIGPosts = await instagram.PostsSinceDate(long.Parse(dbfeed.InstagramID), dbfeed.LastPostDate); if (newIGPosts.Length > 0 && newIGPosts[newIGPosts.Length - 1].success) { //Set the most recent posts date: dbfeed.LastPostDate = newIGPosts[newIGPosts.Length - 1].postDate; } foreach (InstagramProcessorResponse response in newIGPosts) { List <RespondChannel> invalidChannels = new List <RespondChannel>(); foreach (RespondChannel subbedGuild in dbfeed.SubscribedChannels) { if (response.success) { //Create component builder: IGComponentBuilder component = new IGComponentBuilder(response); //Create embed response: IGEmbedBuilder embed = new IGEmbedBuilder(response); if (!response.success) { //Failed to process post: Console.WriteLine("Failed to process post."); return; } else if (response.isVideo) { if (response.stream != null) { //Response with stream: using (Stream stream = new MemoryStream(response.stream)) { FileAttachment attachment = new FileAttachment(stream, "IGMedia.mp4", "An Instagram Video."); // get channel: IMessageChannel chan = null; try { chan = _client.GetChannel(ulong.Parse(subbedGuild.ChannelID)) as IMessageChannel; } catch { Console.WriteLine("Cannot find channel. Removing from DB."); invalidChannels.Add(subbedGuild); } if (chan != null) { //send message await chan.SendFileAsync(attachment, embed : embed.AutoSelector(), components : component.AutoSelector()); } else { Console.WriteLine("Cannot find channel. Removing from DB."); invalidChannels.Add(subbedGuild); } } } else { //Response without stream: // get channel: IMessageChannel chan = null; try { chan = _client.GetChannel(ulong.Parse(subbedGuild.ChannelID)) as IMessageChannel; } catch { Console.WriteLine("Cannot find channel. Removing from DB."); invalidChannels.Add(subbedGuild); } if (chan != null) { //send message await chan.SendMessageAsync(response.contentURL.ToString(), embed : embed.AutoSelector(), components : component.AutoSelector()); } else { Console.WriteLine("Cannot find channel. Removing from DB."); invalidChannels.Add(subbedGuild); } } } else { if (response.stream != null) { using (Stream stream = new MemoryStream(response.stream)) { FileAttachment attachment = new FileAttachment(stream, "IGMedia.jpg", "An Instagram Image."); // get channel: IMessageChannel chan = null; try { chan = _client.GetChannel(ulong.Parse(subbedGuild.ChannelID)) as IMessageChannel; } catch { Console.WriteLine("Cannot find channel. Removing from DB."); invalidChannels.Add(subbedGuild); } if (chan != null) { //send message await chan.SendFileAsync(attachment, embed : embed.AutoSelector(), components : component.AutoSelector()); } else { Console.WriteLine("Cannot find channel. Removing from DB."); invalidChannels.Add(subbedGuild); } } } else { // get channel: IMessageChannel chan = null; try { chan = _client.GetChannel(ulong.Parse(subbedGuild.ChannelID)) as IMessageChannel; } catch { Console.WriteLine("Cannot find channel. Removing from DB."); invalidChannels.Add(subbedGuild); } if (chan != null) { //send message try { await chan.SendMessageAsync(embed : embed.AutoSelector(), components : component.AutoSelector()); }catch (Exception e) { Console.WriteLine("Error sending subscription message. Error: " + e); invalidChannels.Add(subbedGuild); } } else { Console.WriteLine("Cannot find channel. Removing from DB."); invalidChannels.Add(subbedGuild); } } } } else if (response.error == "NullAccount") { Console.WriteLine("Removing null account: " + dbfeed.InstagramID); invalidChannels.Add(subbedGuild); } else { //TODO: Decide if the user should be informed or not. May create spam. Console.WriteLine("Failed auto post. ID: " + dbfeed.InstagramID); var chan = _client.GetChannel(ulong.Parse(subbedGuild.ChannelID)) as IMessageChannel; string igUsername = await instagram.GetIGUsername(dbfeed.InstagramID); await chan.SendMessageAsync("Failed to get latest posts for " + igUsername + ". Use `/unsubscribe " + igUsername + "` to remove the inaccessible account."); } } //Remove all invalid channels: invalidChannels.ForEach(item => dbfeed.SubscribedChannels.RemoveAll(c => c.ChannelID.Equals(item.ChannelID))); } //Update database: await this.FollowedAccountsContainer.ReplaceOneAsync(x => x.InstagramID == dbfeed.InstagramID, dbfeed, new ReplaceOptions { IsUpsert = true }); // Wait to prevent spamming IG api: // 10 seconds await Task.Delay(10000); } } catch (Exception e) { Console.WriteLine("Failed to get updates for IG account. Error: " + e); } } } catch (Exception e) { Console.WriteLine("Error with update loop: " + e); } finally { //Always mark as done loop when exiting: InSubLoop = false; Console.WriteLine("Done."); } }