From abdea10b9851bde8b9ef231b845c487d8b029d23 Mon Sep 17 00:00:00 2001 From: Mike Shi Date: Sun, 9 Apr 2017 13:01:26 -0400 Subject: [PATCH 1/3] Added mentions sendMessage handler + docs. --- DOCS.md | 24 ++++++++++++++++++++++++ src/sendMessage.js | 18 +++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/DOCS.md b/DOCS.md index c8ece101..3a699541 100644 --- a/DOCS.md +++ b/DOCS.md @@ -875,6 +875,7 @@ Various types of message can be sent: * *File or image:* Set field `attachment` to a readable stream or an array of readable streams. * *URL:* set a field `url` to the desired URL. * *Emoji:* set field `emoji` to the desired emoji as a string and set field `emojiSize` with size of the emoji (`small`, `medium`, `large`) +* *Mentions:* set field `mentions` to an array of objects. Objects should have the `tag` field set to the text that should be highlighted in the mention (NOTE: the first instance of `tag` is highlighted in the text). Additionally, the object should have an `id` field, where the `id` is the user id of the person being mentioned. Note that a message can only be a regular message (which can be empty) and optionally one of the following: a sticker, an attachment or a url. @@ -912,6 +913,29 @@ login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, ap }); ``` +__Example (Mention)__ +```js +const login = require("facebook-chat-api"); + +login({email: "EMAIL", password: "PASSWORD"}, (err, api) => { + if(err) return console.error(err); + + api.listen((err, message) => { + if (message && message.body) { + // Getting the actual sender name from ID involves calling + // `api.getThreadInfo` and `api.getUserInfo` + api.sendMessage({ + body: 'Hello @Sender!', + mentions: [{ + tag: '@Sender', + id: message.senderID, + }], + }, message.threadID); + } + }); +}); +``` + --------------------------------------- diff --git a/src/sendMessage.js b/src/sendMessage.js index 66c6a7c3..3408f3b0 100644 --- a/src/sendMessage.js +++ b/src/sendMessage.js @@ -11,6 +11,7 @@ var allowedProperties = { emoji: true, emojiSize: true, body: true, + mentions: true, }; module.exports = function(defaultFuncs, api, ctx) { @@ -236,6 +237,20 @@ module.exports = function(defaultFuncs, api, ctx) { } } + function handleMention(msg, form, callback, cb) { + if (msg.mentions) { + for (let i=0; i < msg.mentions.length; i++) { + let mention = msg.mentions[i]; + let tag = mention.tag || ''; + let id = mention.id || 0; + form['profile_xmd[' + i + '][offset]'] = msg.body.indexOf(tag); + form['profile_xmd[' + i + '][length]'] = tag.length; + form['profile_xmd[' + i + '][id]'] = id; + } + } + cb(); + } + return function sendMessage(msg, threadID, callback) { if(!callback && (utils.getType(threadID) === 'Function' || utils.getType(threadID) === 'AsyncFunction')) { return callback({error: "Pass a threadID as a second argument."}); @@ -303,6 +318,7 @@ module.exports = function(defaultFuncs, api, ctx) { () => handleAttachment(msg, form, callback, () => handleUrl(msg, form, callback, () => handleEmoji(msg, form, callback, - () => send(form, threadID, messageAndOTID, callback))))); + () => handleMention(msg, form, callback, + () => send(form, threadID, messageAndOTID, callback)))))); }; }; From b359e86c5cad39b4d949ce5ef60e493a1c40fe8e Mon Sep 17 00:00:00 2001 From: Mike Shi Date: Wed, 12 Apr 2017 00:06:28 -0400 Subject: [PATCH 2/3] Mentions: Added fromIndex, checks and warnings --- DOCS.md | 9 ++++++--- src/sendMessage.js | 31 ++++++++++++++++++++++--------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/DOCS.md b/DOCS.md index 3a699541..c51142f0 100644 --- a/DOCS.md +++ b/DOCS.md @@ -493,7 +493,7 @@ function loadNextThreadHistory(api){ if(err) return console.error(err); /* - Since the timestamp is from a previous loaded message, + Since the timestamp is from a previous loaded message, that message will be included in this history so we can discard it unless it is the first load. */ if(timestamp != undefined) history.pop(); @@ -875,7 +875,9 @@ Various types of message can be sent: * *File or image:* Set field `attachment` to a readable stream or an array of readable streams. * *URL:* set a field `url` to the desired URL. * *Emoji:* set field `emoji` to the desired emoji as a string and set field `emojiSize` with size of the emoji (`small`, `medium`, `large`) -* *Mentions:* set field `mentions` to an array of objects. Objects should have the `tag` field set to the text that should be highlighted in the mention (NOTE: the first instance of `tag` is highlighted in the text). Additionally, the object should have an `id` field, where the `id` is the user id of the person being mentioned. +* *Mentions:* set field `mentions` to an array of objects. Objects should have the `tag` field set to the text that should be highlighted in the mention. The object should have an `id` field, where the `id` is the user id of the person being mentioned. The instance of `tag` that is highlighted is determined through indexOf, an optional `fromIndex` +can be passed in to specify the start index to start searching for the `tag` text +in `body` (default=0). (See below for an example.) Note that a message can only be a regular message (which can be empty) and optionally one of the following: a sticker, an attachment or a url. @@ -925,10 +927,11 @@ login({email: "EMAIL", password: "PASSWORD"}, (err, api) => { // Getting the actual sender name from ID involves calling // `api.getThreadInfo` and `api.getUserInfo` api.sendMessage({ - body: 'Hello @Sender!', + body: 'Hello @Sender! @Sender!', mentions: [{ tag: '@Sender', id: message.senderID, + fromIndex: 9, // Highlight the second occurrence of @Sender }], }, message.threadID); } diff --git a/src/sendMessage.js b/src/sendMessage.js index 3408f3b0..d15bfb0a 100644 --- a/src/sendMessage.js +++ b/src/sendMessage.js @@ -187,7 +187,7 @@ module.exports = function(defaultFuncs, api, ctx) { } cb(); } - + function handleEmoji(msg, form, callback, cb) { if (msg.emojiSize != null && msg.emoji == null) { return callback({error: "emoji property is empty"}); @@ -239,14 +239,27 @@ module.exports = function(defaultFuncs, api, ctx) { function handleMention(msg, form, callback, cb) { if (msg.mentions) { - for (let i=0; i < msg.mentions.length; i++) { - let mention = msg.mentions[i]; - let tag = mention.tag || ''; - let id = mention.id || 0; - form['profile_xmd[' + i + '][offset]'] = msg.body.indexOf(tag); - form['profile_xmd[' + i + '][length]'] = tag.length; - form['profile_xmd[' + i + '][id]'] = id; - } + for (let i=0; i < msg.mentions.length; i++) { + const mention = msg.mentions[i]; + + const tag = mention.tag; + if (typeof tag !== "string") + return callback({error: "Mention tags must be strings."}); + + const offset = msg.body.indexOf(tag, mention.fromIndex || 0); + + if (offset < 0) + log.warn("handleMention", "Mention for \"" + tag + + "\" not found in message string."); + + if (mention.id == null) + log.warn("handleMention", "Mention id should be non-null."); + + const id = mention.id || 0; + form['profile_xmd[' + i + '][offset]'] = offset; + form['profile_xmd[' + i + '][length]'] = tag.length; + form['profile_xmd[' + i + '][id]'] = id; + } } cb(); } From 4c17adad62b1d1d3108f2c4856ba150591f88a7c Mon Sep 17 00:00:00 2001 From: Mike Shi Date: Wed, 12 Apr 2017 12:33:54 -0400 Subject: [PATCH 3/3] Added curly braces to ifs --- src/sendMessage.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sendMessage.js b/src/sendMessage.js index d15bfb0a..f7552d93 100644 --- a/src/sendMessage.js +++ b/src/sendMessage.js @@ -243,17 +243,20 @@ module.exports = function(defaultFuncs, api, ctx) { const mention = msg.mentions[i]; const tag = mention.tag; - if (typeof tag !== "string") + if (typeof tag !== "string") { return callback({error: "Mention tags must be strings."}); + } const offset = msg.body.indexOf(tag, mention.fromIndex || 0); - if (offset < 0) + if (offset < 0) { log.warn("handleMention", "Mention for \"" + tag + "\" not found in message string."); + } - if (mention.id == null) + if (mention.id == null) { log.warn("handleMention", "Mention id should be non-null."); + } const id = mention.id || 0; form['profile_xmd[' + i + '][offset]'] = offset;