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 Profile([Summary("username", "The username of the Instagram account.")] string username) { // 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; } //Buy more time to process posts: await DeferAsync(false); // Get IG account: InstagramProcessor instagram = new InstagramProcessor(InstagramProcessor.AccountFinder.GetIGAccount()); //Create url: string url = username; if (!Uri.IsWellFormedUriString(username, UriKind.Absolute)) { url = "https://instagram.com/" + username; } // Process profile: InstagramProcessorResponse response = await instagram.PostRouter(url, (int)Context.Guild.PremiumTier, 1); // Check for failed post: if (!response.success) { await FollowupAsync(response.error); return; } // If not a profile for some reason, treat otherwise: if (!response.onlyAccountData) { await FollowupAsync("This doesnt appear to be a profile. Try using `/link` for posts."); return; } IGEmbedBuilder embed = new IGEmbedBuilder(response, Context.User.Username); IGComponentBuilder component = new IGComponentBuilder(response, Context.User.Id); await FollowupAsync(embed : embed.AutoSelector(), allowedMentions : AllowedMentions.None, components : component.AutoSelector()); }
/// <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 ProfileParser([Remainder] string args = null) { // Check whitelist: if (!Whitelist.IsServerOnList(Context.Guild.Id)) { // Ignore if not on list: return; } using (Context.Channel.EnterTypingState()) { // Get IG account: InstagramProcessor instagram = new InstagramProcessor(InstagramProcessor.AccountFinder.GetIGAccount()); string url = "https://instagram.com/" + args.Replace(" ", "/"); // Process profile: InstagramProcessorResponse response = await instagram.PostRouter(url, (int)Context.Guild.PremiumTier, 1); // Check for failed post: if (!response.success) { await Context.Message.ReplyAsync(response.error); return; } // If not a profile for some reason, treat otherwise: if (!response.onlyAccountData) { await Responder(url, Context); return; } IGEmbedBuilder embed = new IGEmbedBuilder(response, Context.User.Username); IGComponentBuilder component = new IGComponentBuilder(response, Context.User.Id); await Context.Message.ReplyAsync(embed : embed.AutoSelector(), allowedMentions : AllowedMentions.None, components : component.AutoSelector()); //Attempt to remove any automatic embeds: DiscordTools.SuppressEmbeds(Context); } }
// this class is where the magic starts, and takes actions upon receiving messages public async Task MessageReceivedAsync(SocketMessage rawMessage) { if (!(rawMessage is SocketUserMessage message)) { return; } // ensures we don't process system/other bot messages if (message.Source != MessageSource.User) { // Add exception to this rule if desired: if (string.IsNullOrEmpty(_config["AllowBotMessages"]) || _config["AllowBotMessages"].ToLower() != "true") { return; } } //DMs: if (message.Channel.GetType() == typeof(SocketDMChannel)) { //TODO: Move this to a module file: if (message.Content.ToLower().StartsWith("debug")) { if (!string.IsNullOrEmpty(_config["OwnerID"]) && message.Author.Id == ulong.Parse(_config["OwnerID"])) { long guilds = 0; foreach (DiscordSocketClient shard in _client.Shards) { guilds += shard.Guilds.Count(); } //Server count: await message.ReplyAsync("Server Count: " + guilds); //Shard count: await message.ReplyAsync("Shards: " + _client.Shards.Count()); //IP check: try { OpenGraph graph = OpenGraph.ParseUrl("https://api.ipify.org/", ""); await message.ReplyAsync("IP: " + graph.OriginalHtml); } catch (Exception e) { await message.ReplyAsync("Could not connect to server. Error: " + e); } } } else if (message.Content.ToLower().StartsWith("guilds")) { //Guild list if (!string.IsNullOrEmpty(_config["OwnerID"]) && message.Author.Id == ulong.Parse(_config["OwnerID"])) { //TODO: Export to CSV file string serverList = Format.Bold("Servers:"); foreach (SocketGuild guild in _client.Guilds) { String serverLine = "\n" + guild.Name + " \tBoost: " + guild.PremiumTier + " \tUsers: " + guild.MemberCount + " \tLocale: " + guild.PreferredLocale; //Discord max message length: if (serverList.Length + serverLine.Length > 2000) { await message.ReplyAsync(serverList); serverList = ""; } serverList += serverLine; } await message.ReplyAsync(serverList); } } else if (message.Content.ToLower().StartsWith("toggle error")) { //toggle error DMs if (!string.IsNullOrEmpty(_config["OwnerID"]) && message.Author.Id == ulong.Parse(_config["OwnerID"])) { notifyOwnerOnError = !notifyOwnerOnError; if (notifyOwnerOnError) { await message.ReplyAsync("Error notifications enabled."); } else { await message.ReplyAsync("Error notifications disabled."); } } } else if (message.Content.ToLower().StartsWith("users")) { if (!string.IsNullOrEmpty(_config["OwnerID"]) && message.Author.Id == ulong.Parse(_config["OwnerID"])) { long users = 0; foreach (DiscordSocketClient shard in _client.Shards) { foreach (SocketGuild guild in shard.Guilds) { users += guild.MemberCount; } } await message.ReplyAsync("Users: " + users); } } else if (message.Content.ToLower().StartsWith("accounts")) { if (!string.IsNullOrEmpty(_config["OwnerID"]) && message.Author.Id == ulong.Parse(_config["OwnerID"])) { foreach (IGAccount user in InstagramProcessor.AccountFinder.Accounts) { if (user.OTPSecret != null) { try { var code = Security.GetTwoFactorAuthCode(user.OTPSecret); await message.ReplyAsync("Username: "******"\n2FA Code: " + code + "\nLast Failed: " + user.Blacklist); } catch (Exception e) { await message.ReplyAsync("Failed to get 2FA code."); Console.WriteLine("2FA Code error: " + e); } } else { await message.ReplyAsync("Username: "******"\nLast Failed: " + user.Blacklist); } } } } else if (message.Content.ToLower().StartsWith("sync")) { if (!string.IsNullOrEmpty(_config["OwnerID"]) && message.Author.Id == ulong.Parse(_config["OwnerID"])) { if (_subscriptions.CurrentlyCheckingAccounts()) { await message.ReplyAsync("Already doing that."); } else { // Run this async to avoid blocking the current thread: // Use discard since im not interested in the output, only the process. _ = _subscriptions.GetLatestsPosts(); //Let the user know its being worked on: await message.ReplyAsync("Working on it."); } } } else if (message.Content.ToLower().StartsWith("overwrite")) { if (!string.IsNullOrEmpty(_config["OwnerID"]) && message.Author.Id == ulong.Parse(_config["OwnerID"])) { // Load all registered commands: var commands = await _client.Rest.GetGlobalApplicationCommands(); // Delete all commands: foreach (var command in commands) { await command.DeleteAsync(); } // Re-register commands: await _interact.RegisterCommandsGloballyAsync(true); // Alert user: await message.ReplyAsync("Slash commands resynced."); } } else if (message.Content.ToLower().StartsWith("clearstate")) { if (!string.IsNullOrEmpty(_config["OwnerID"]) && message.Author.Id == ulong.Parse(_config["OwnerID"])) { // Clear statefiles: string stateFile = Path.Combine(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "StateFiles"); if (Directory.Exists(stateFile)) { Directory.Delete(stateFile, true); Directory.CreateDirectory(stateFile); } else { await message.ReplyAsync("Folder not found. Skipping folder removal."); } // Clear loaded accounts: InstagramProcessor.AccountFinder.Accounts = new List <IGAccount>(); InstagramProcessor.AccountFinder.LoadAccounts(); await message.ReplyAsync("State files removed."); } } return; } // sets the argument position away from the prefix we set int argPos = 0; int endUrlLength = 0; bool foundPrefix = false; // get each prefix from the configuration file foreach (string prefix in _config.GetSection("Prefix").GetChildren().ToArray().Select(c => c.Value).ToArray()) { //check for valid prefix: if (message.Content.Contains(prefix)) { argPos = message.Content.IndexOf(prefix) + prefix.Length; endUrlLength = message.Content.Substring(argPos).Replace("\n", " ").IndexOf(" "); foundPrefix = true; break; } } if (!foundPrefix) { return; } var context = new ShardedCommandContext(_client, message); //create new string from command string commandText; if (endUrlLength <= 0) { commandText = message.Content.Substring(argPos).Replace("/", " "); } else { commandText = message.Content.Substring(argPos, endUrlLength).Replace("/", " "); } //Check for profile link: if (InstagramProcessor.isProfileLink(new Uri("https://instagram.com/" + commandText.Replace(" ", "/")))) { //Little hack to add command to url (profile is also reserved by ig so no conflicts): commandText = "profile " + commandText; } //Split url down to params: String[] userInput = commandText.Split(" "); foreach (CommandInfo command in _commands.Commands) { if (command.Name.Equals(userInput[0])) { await _commands.ExecuteAsync(context, commandText, _services); } else if (command.Name.Equals(userInput[1])) { commandText = commandText.Replace(userInput[0] + " ", ""); Console.WriteLine(commandText); await _commands.ExecuteAsync(context, commandText, _services); } } }
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()); }
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()); }
public async Task Link(string url, [Summary(description: "The post number for the desired post in a carousel.")][MinValue(1)] int index = 1, [Summary(description: "Set to true to mark the image/video and caption as a spoiler.")] bool HasSpoilers = false) { // 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; } //Buy more time to process posts: await DeferAsync(false); // Get IG account: InstagramProcessor instagram = new InstagramProcessor(InstagramProcessor.AccountFinder.GetIGAccount()); //Process Post: InstagramProcessorResponse response = await instagram.PostRouter(url, Context.Guild, index); if (!response.success) { //Failed to process post: await FollowupAsync(response.error, ephemeral : true); return; } //Create embed builder: IGEmbedBuilder embed = new IGEmbedBuilder(response, Context.User.Username, HasSpoilers); //Create component builder: IGComponentBuilder component = new IGComponentBuilder(response, Context.User.Id); 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.", isSpoiler: HasSpoilers); await Context.Interaction.FollowupWithFileAsync(attachment, embed : embed.AutoSelector(), components : component.AutoSelector()); } } else { //Response without stream: await FollowupAsync(response.contentURL.ToString(), embed : embed.AutoSelector(), components : component.AutoSelector()); } } else { if (response.stream != null) { using (Stream stream = new MemoryStream(response.stream)) { FileAttachment attachment = new FileAttachment(stream, "IGMedia.jpg", "An Instagram Image.", isSpoiler: HasSpoilers); await Context.Interaction.FollowupWithFileAsync(attachment, embed : embed.AutoSelector(), allowedMentions : AllowedMentions.None, components : component.AutoSelector()); } } else { await FollowupAsync(embed : embed.AutoSelector(), components : component.AutoSelector()); } } }
public async Task Subscribe([Summary("username", "The username of the Instagram user.")] string username) { // 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 more time to process posts: await DeferAsync(true); // Get IG account: InstagramProcessor instagram = new InstagramProcessor(InstagramProcessor.AccountFinder.GetIGAccount()); // Account limits: int subcount = await _subscriptions.GuildSubscriptionCountAsync(Context.Guild.Id); int maxcount = await _subscriptions.MaxSubscriptionsCountForGuildAsync(Context.Guild.Id); if (subcount >= maxcount) { await FollowupAsync("You are already subscribed to " + subcount + " Instagram accounts which is greater than or equal to your limit of " + maxcount + " accounts. use `/unsubscribe` to remove these accounts."); return; } long IGID; try { IGID = await instagram.GetUserIDFromUsername(username); } catch (Exception e) { //Possibly incorrect username: Console.WriteLine("Get username failure: " + e); await FollowupAsync("Failed to get Instagram ID. Is the account name correct?"); return; } if (!await instagram.AccountIsPublic(IGID)) { await FollowupAsync("The account appears to be private and cannot be viewed by the bot."); return; } //Subscribe: try { await _subscriptions.SubscribeToAccount(IGID, Context.Channel.Id, Context.Guild.Id); }catch (ArgumentException e) when(e.Message.Contains("Already subscribed")) { await FollowupAsync("You are already subscribed to this account."); return; } //Notify: await Context.Channel.SendMessageAsync("This channel has been subscribed to " + username + " on Instagram by " + Context.User.Mention, allowedMentions : AllowedMentions.None); await FollowupAsync("Success! You will receive new posts to this channel. They will not be instant and accounts are checked on a time interval."); }
/// <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."); } }
/// <summary> /// Centralized method to handle all Instagram links and respond to text based messages (No slash commands). /// </summary> /// <param name="url">The Instagram URL of the content</param> /// <param name="context">The discord context of the message</param> /// <returns></returns> private static async Task Responder(string url, ICommandContext context) { // Check whitelist: if (!Whitelist.IsServerOnList(context.Guild.Id)) { // Ignore if not on list: return; } using (context.Channel.EnterTypingState()) { // Get IG account: InstagramProcessor instagram = new InstagramProcessor(InstagramProcessor.AccountFinder.GetIGAccount()); //Process Post: InstagramProcessorResponse response = await instagram.PostRouter(url, (int)context.Guild.PremiumTier, 1); //Check for failed post: if (!response.success) { await context.Message.ReplyAsync(response.error); return; } // Embed builder: IGEmbedBuilder embed = new IGEmbedBuilder(response, context.User.Username); IGComponentBuilder component = new IGComponentBuilder(response, context.User.Id); 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."); await context.Message.Channel.SendFileAsync(attachment, embed : embed.AutoSelector(), components : component.AutoSelector()); } } else { //Response without stream: await context.Message.ReplyAsync(response.contentURL.ToString(), embed : embed.AutoSelector(), allowedMentions : AllowedMentions.None, components : component.AutoSelector()); } } else { if (response.stream != null) { using (Stream stream = new MemoryStream(response.stream)) { FileAttachment attachment = new FileAttachment(stream, "IGMedia.jpg", "An Instagram Image."); await context.Channel.SendFileAsync(attachment, embed : embed.AutoSelector(), components : component.AutoSelector()); } } else { await context.Message.ReplyAsync(embed : embed.AutoSelector(), allowedMentions : AllowedMentions.None, components : component.AutoSelector()); } } //Try to remove the embeds on the command post: DiscordTools.SuppressEmbeds(context); } }