Esempio n. 1
0
        internal static FB_ParticipantRemoved _from_fetch(FB_Thread thread, JToken data)
        {
            (FB_User author, long at) = FB_ParticipantRemoved._parse_fetch(thread.session, data);
            var removed = new FB_User(data?.get("participants_removed")?.FirstOrDefault()?.get("id")?.Value <string>(), thread.session);

            return(new FB_ParticipantRemoved()
            {
                author = author,
                thread = thread as FB_Group,
                removed = removed,
                at = at
            });
        }
Esempio n. 2
0
        /// <summary>
        /// Fetches`Message` object from the message id
        /// </summary>
        /// <param name="thread">Thread containing this message</param>
        /// <param name="mid">Message ID to fetch from</param>
        /// <returns>`FB_Message` object</returns>
        public static async Task <FB_Message> _from_fetch(FB_Thread thread, string mid)
        {
            /*
             * Fetches`Message` object from the message id
             * :param thread: Thread containing this message
             * :param mid: Message ID to fetch from
             * :return: `Message` object
             * :rtype: Message
             * :raises: FBchatException if request failed
             * */
            var message_info = ((JToken)await thread._forcedFetch(mid))?.get("message");

            return(FB_Message._from_graphql(message_info, thread));
        }
Esempio n. 3
0
        internal static FB_NicknameSet _from_fetch(FB_Thread thread, JToken data)
        {
            (FB_User author, long at) = FB_NicknameSet._parse_fetch(thread.session, data);
            var extra    = data?.get("extensible_message_admin_text");
            var subject  = new FB_User(extra?.get("participant_id")?.Value <string>(), thread.session);
            var nickname = extra?.get("nickname")?.Value <string>();

            return(new FB_NicknameSet()
            {
                author = author,
                thread = thread,
                subject = subject,
                nickname = nickname,
                at = at
            });
        }
Esempio n. 4
0
        internal static FB_Message _from_pull(JToken data, FB_Thread thread, string author = null, string timestamp = null)
        {
            var metadata = data?.get("messageMetadata");
            var tags     = metadata?.get("tags")?.ToObject <List <string> >();

            var rtn = new FB_Message(
                session: thread.session,
                text: data.get("body")?.Value <string>());

            rtn.uid       = metadata?.get("messageId")?.Value <string>();
            rtn.session   = thread.session;
            rtn.thread_id = thread.uid;
            rtn.author    = author;
            rtn.timestamp = timestamp;
            rtn.mentions  = JToken.Parse(data.get("data")?.get("prng")?.Value <string>() ?? "{}")?.Select((m) =>
                                                                                                          FB_Mention._from_prng(m)
                                                                                                          ).ToList();

            if (data.get("attachments") != null)
            {
                try
                {
                    foreach (var a in data.get("attachments"))
                    {
                        var mercury = a.get("mercury");
                        if (mercury.get("blob_attachment") != null)
                        {
                            var image_metadata = a.get("imageMetadata");
                            var attach_type    = mercury.get("blob_attachment")?.get("__typename")?.Value <string>();
                            var attachment     = FB_Attachment.graphql_to_attachment(
                                mercury.get("blob_attachment")
                                );

                            if (new string[] { "MessageFile", "MessageVideo", "MessageAudio" }.Contains(attach_type))
                            {
                                // TODO: Add more data here for audio files
                                if (attachment is FB_FileAttachment)
                                {
                                    ((FB_FileAttachment)attachment).size = a?.get("fileSize")?.Value <int>() ?? 0;
                                }
                                if (attachment is FB_VideoAttachment)
                                {
                                    ((FB_VideoAttachment)attachment).size = a?.get("fileSize")?.Value <int>() ?? 0;
                                }
                            }
                            rtn.attachments.Add(attachment);
                        }
                        else if (mercury.get("sticker_attachment") != null)
                        {
                            rtn.sticker = FB_Sticker._from_graphql(
                                mercury.get("sticker_attachment")
                                );
                        }
                        else if (mercury.get("extensible_attachment") != null)
                        {
                            var attachment = FB_Attachment.graphql_to_extensible_attachment(
                                mercury.get("extensible_attachment")
                                );
                            if (attachment is FB_UnsentMessage)
                            {
                                rtn.unsent = true;
                            }
                            else if (attachment != null)
                            {
                                rtn.attachments.Add(attachment);
                            }
                        }
                    }
                }
                catch
                {
                    Debug.WriteLine(string.Format("An exception occured while reading attachments: {0}", data.get("attachments")));
                }
            }

            rtn.emoji_size = EmojiSizeMethods._from_tags(tags);
            rtn.forwarded  = FB_Message._get_forwarded_from_tags(tags);
            return(rtn);
        }
Esempio n. 5
0
        internal static FB_Message _from_reply(JToken data, FB_Thread thread)
        {
            var tags = data.get("messageMetadata")?.get("tags")?.ToObject <List <string> >();

            var rtn = new FB_Message(
                session: thread.session,
                text: data.get("body")?.Value <string>(),
                mentions: JToken.Parse(data.get("data")?.get("prng")?.Value <string>() ?? "{}")?.Select((m) =>
                                                                                                        FB_Mention._from_prng(m)
                                                                                                        ).ToList(),
                emoji_size: EmojiSizeMethods._from_tags(tags));

            var metadata = data.get("messageMetadata");

            rtn.forwarded   = FB_Message._get_forwarded_from_tags(tags);
            rtn.uid         = metadata?.get("messageId")?.Value <string>();
            rtn.thread_id   = thread.uid; // Added
            rtn.author      = metadata?.get("actorFbId")?.Value <string>();
            rtn.timestamp   = metadata?.get("timestamp")?.Value <string>();
            rtn.reply_to_id = data?.get("messageReply")?.get("replyToMessageId")?.get("id")?.Value <string>();
            rtn.unsent      = false;

            if (data.get("data")?.get("platform_xmd") != null)
            {
                var quick_replies = JToken.Parse(data.get("data")?.get("platform_xmd").Value <string>()).get("quick_replies");
                if (quick_replies.Type == JTokenType.Array)
                {
                    rtn.quick_replies = quick_replies.Select((q) => FB_QuickReply.graphql_to_quick_reply(q)).ToList();
                }
                else
                {
                    rtn.quick_replies = new List <FB_QuickReply>()
                    {
                        FB_QuickReply.graphql_to_quick_reply(quick_replies)
                    }
                };
            }
            foreach (var atc in data.get("attachments") ?? Enumerable.Empty <JToken>())
            {
                var attachment = JToken.Parse(atc.get("mercuryJSON")?.Value <string>());
                if (attachment.get("blob_attachment") != null)
                {
                    rtn.attachments.Add(
                        FB_Attachment.graphql_to_attachment(attachment.get("blob_attachment"))
                        );
                }
                if (attachment.get("extensible_attachment") != null)
                {
                    var ext_attachment = FB_Attachment.graphql_to_extensible_attachment(attachment.get("extensible_attachment"));
                    if (ext_attachment is FB_UnsentMessage)
                    {
                        rtn.unsent = true;
                    }
                    else if (ext_attachment != null)
                    {
                        rtn.attachments.Add(ext_attachment);
                    }
                }
            }

            return(rtn);
        }
Esempio n. 6
0
        internal static FB_Message _from_graphql(JToken data, FB_Thread thread, JToken read_receipts = null)
        {
            if (data["message_sender"] == null)
            {
                data["message_sender"] = new JObject(new JProperty("id", 0));
            }
            if (data["message"] == null)
            {
                data["message"] = new JObject(new JProperty("text", ""));
            }

            var tags = data.get("tags_list")?.ToObject <List <string> >();

            var rtn = new FB_Message(
                session: thread.session,
                text: data.get("message")?.get("text")?.Value <string>(),
                mentions: data.get("message")?.get("ranges")?.Select((m) =>
                                                                     FB_Mention._from_range(m)
                                                                     ).ToList(),
                emoji_size: EmojiSizeMethods._from_tags(tags),
                sticker: FB_Sticker._from_graphql(data.get("sticker")));

            rtn.forwarded = FB_Message._get_forwarded_from_tags(tags);
            rtn.uid       = data.get("message_id")?.Value <string>();
            rtn.thread_id = thread.uid; // Added
            rtn.author    = data.get("message_sender")?.get("id")?.Value <string>();
            rtn.timestamp = data.get("timestamp_precise")?.Value <string>();
            rtn.unsent    = false;

            if (data.get("unread") != null)
            {
                rtn.is_read = !data.get("unread").Value <bool>();
            }

            rtn.reactions = new Dictionary <string, string>();
            foreach (var r in data.get("message_reactions"))
            {
                rtn.reactions.Add(r.get("user")?.get("id")?.Value <string>(), r.get("reaction").Value <string>());
            }
            if (data.get("blob_attachments") != null)
            {
                rtn.attachments = new List <FB_Attachment>();
                foreach (var attachment in data.get("blob_attachments"))
                {
                    rtn.attachments.Add(FB_Attachment.graphql_to_attachment(attachment));
                }
            }
            if (data.get("platform_xmd_encoded") != null)
            {
                var quick_replies = JToken.Parse(data.get("platform_xmd_encoded")?.Value <string>()).get("quick_replies");
                if (quick_replies != null)
                {
                    if (quick_replies.Type == JTokenType.Array)
                    {
                        rtn.quick_replies = quick_replies.Select((q) => FB_QuickReply.graphql_to_quick_reply(q)).ToList();
                    }
                    else
                    {
                        rtn.quick_replies = new List <FB_QuickReply>()
                        {
                            FB_QuickReply.graphql_to_quick_reply(quick_replies)
                        }
                    };
                }
            }
            if (data.get("extensible_attachment") != null)
            {
                var attachment = FB_Attachment.graphql_to_extensible_attachment(data.get("extensible_attachment"));
                if (attachment is FB_UnsentMessage)
                {
                    rtn.unsent = true;
                }
                else if (attachment != null)
                {
                    rtn.attachments.Add(attachment);
                }
            }
            if (data.get("replied_to_message") != null && data.get("replied_to_message").get("message") != null)
            {
                // data["replied_to_message"]["message"] is None if the message is deleted
                rtn.replied_to  = FB_Message._from_graphql(data.get("replied_to_message").get("message"), thread);
                rtn.reply_to_id = rtn.replied_to.uid;
            }
            if (read_receipts != null)
            {
                rtn.read_by = read_receipts.Where(r => long.Parse(r.get("watermark")?.Value <string>()) >= long.Parse(rtn.timestamp))
                              .Select(r => r.get("actor")?.get("id")?.Value <string>()).ToList();
            }
            return(rtn);
        }
Esempio n. 7
0
        /// <summary>
        /// Searches for messages in all threads
        /// Intended to be used alongside `FB_Thread.searchMessages`
        /// </summary>
        /// <param name="query">Text to search for</param>
        /// <param name="offset">Number of messages to skip</param>
        /// <param name="limit">Max. number of threads to retrieve</param>
        /// <returns>Iterable with tuples of threads, and the total amount of matching messages in each</returns>
        public async Task <List <(FB_Thread thread, int count)> > searchMessages(string query, int offset = 0, int limit = 5)
        {
            /*
             * Search for messages in all threads.
             * Intended to be used alongside `FB_Thread.searchMessages`
             * Warning! If someone send a message to a thread that matches the query, while
             * we're searching, some snippets will get returned twice.
             * Not sure if we should handle it, Facebook's implementation doesn't...
             * Args:
             *   query: Text to search for
             *   limit: Max. number of threads to retrieve. If ``None``, all threads will be
             *   retrieved.
             *   Returns:
             *     Iterable with tuples of threads, and the total amount of matching messages in each.
             */

            var data = new Dictionary <string, object>()
            {
                { "query", query },
                { "offset", offset.ToString() },
                { "limit", limit.ToString() }
            };
            var j = await this._session._payload_post("/ajax/mercury/search_snippets.php?dpr=1", data);

            var total_snippets = j?.get("search_snippets")?.get(query);

            var rtn = new List <(FB_Thread, int)>();

            foreach (var node in j?.get("graphql_payload")?.get("message_threads"))
            {
                FB_Thread thread = null;
                var       type_  = node?.get("thread_type")?.Value <string>();
                if (type_ == "GROUP")
                {
                    thread = new FB_Group(
                        session: _session, uid: node?.get("thread_key")?.get("thread_fbid")?.Value <string>()
                        );
                }
                else if (type_ == "ONE_TO_ONE")
                {
                    thread = new FB_Thread(
                        session: _session, uid: node?.get("thread_key")?.get("other_user_id")?.Value <string>()
                        );
                }
                //if True:  // TODO: This check!
                // thread = UserData._from_graphql(self.session, node)
                //else:
                // thread = PageData._from_graphql(self.session, node)
                else
                {
                    throw new FBchatException(string.Format("Unknown thread type: {0}", type_));
                }
                if (thread != null)
                {
                    rtn.Add((thread, total_snippets?.get(thread.uid)?.get("num_total_snippets")?.Value <int>() ?? 0));
                }
                else
                {
                    rtn.Add((null, 0));
                }
            }
            return(rtn);
        }