Skip to content

Commit 1066664

Browse files
committed
bidirectional images! dupes when sent from matrix
1 parent ef35c29 commit 1066664

File tree

7 files changed

+67
-43
lines changed

7 files changed

+67
-43
lines changed

config.sample.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"registrationPath": "imessage-registration.yaml",
33
"ichatArchives": "~/Library/Containers/com.apple.iChat/Data/Library/Messages/Archive/**/*.ichat",
4+
"attachmentsDir": "~/Library/Messages/Attachments",
45
"port": 8090,
56
"bridge": {
67
"homeserverUrl":"https://yourserver.com",

index.js

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@ const {
66
Cli, AppServiceRegistration
77
},
88
Puppet,
9-
MatrixPuppetBridgeBase
9+
MatrixPuppetBridgeBase,
10+
utils: { download }
1011
} = require("matrix-puppet-bridge");
1112
const puppet = new Puppet('./config.json');
12-
13+
const sizeOf = require('image-size');
14+
const mime = require('mime-types');
15+
const findAttachment = require('./src/find-attachment');
1316

1417
class App extends MatrixPuppetBridgeBase {
1518
getServicePrefix() {
1619
return "imessage";
1720
}
18-
defaultDeduplicationTag() {
19-
return " \ufeff"; // Zero width non-breaking space
20-
}
21-
defaultDeduplicationTagPattern() {
22-
return " \\ufeff$"; // Zero width non-breaking space
21+
getServiceName() {
22+
return "iMessage";
2323
}
2424
initThirdPartyClient() {
2525
this.roomData = {};
@@ -57,24 +57,37 @@ class App extends MatrixPuppetBridgeBase {
5757
topic: isMultiParty ? 'iMessage: group chat' : 'iMessage: 1-on-1 chat'
5858
};
5959

60-
if ( files.length > 0 ) {
61-
message = `[This iMessage has ${files.length} attachments!]\n${message}`;
62-
}
63-
6460
// too hard to get one thru applescripting contacts, just allow null
6561
// so that we can use bang commands and have them persist forever.
6662
// by preventing base class from calling setDisplayName when senderName is null
6763
this.allowNullSenderName = true;
6864

69-
return Promise.all([
70-
this.setRoomService(roomId, service),
71-
this.handleThirdPartyRoomMessage({
65+
return this.setRoomService(roomId, service).then(()=>{
66+
let payload = {
7267
roomId,
7368
senderName: isMultiParty ? null : fileRecipient,
7469
senderId: senderIsMe ? undefined : sender,
7570
text: message
76-
})
77-
]).then(() => {
71+
};
72+
if ( files.length > 0 ) {
73+
return Promise.map(files, (file)=>{
74+
return findAttachment(file.id, file.name).then(filepath=>{
75+
payload.path = filepath;
76+
payload.mimetype = mime.lookup(payload.path);
77+
if ( payload.mimetype.match(/^image/) ) {
78+
const dim = sizeOf(payload.path);
79+
payload.h = dim.height;
80+
payload.w = dim.width;
81+
return this.handleThirdPartyRoomImageMessage(payload);
82+
} else {
83+
return this.sendStatusMsg({}, "dont know how to deal with filetype", payload);
84+
}
85+
});
86+
});
87+
} else {
88+
return this.handleThirdPartyRoomMessage(payload);
89+
}
90+
}).then(() => {
7891
return this.getOrCreateMatrixRoomFromThirdPartyRoomId(roomId);
7992
}).then((matrixRoomId) => {
8093
// we need to pre-emptively put all the participants into the room
@@ -132,12 +145,17 @@ class App extends MatrixPuppetBridgeBase {
132145
return isGroup ? sendGroupMessage(handles, text) : sendMessage(id, service, text);
133146
});
134147
}
135-
sendPictureMessageAsPuppetToThirdPartyRoomWithId(id, text, img, matrixEvent) {
148+
149+
sendImageMessageAsPuppetToThirdPartyRoomWithId(id, { url, text }, matrixEvent) {
136150
const { sendGroupMessage, sendMessage } = this.client;
137-
return this.prepareToSend(id, matrixEvent).then(({isGroup, handles, service})=>{
138-
return isGroup ? sendGroupMessage(handles, text, img) : sendMessage(id, service, text, img);
151+
return download.getTempfile(url).then(({path}) => {
152+
const img = path;
153+
return this.prepareToSend(id, matrixEvent).then(({isGroup, handles, service})=>{
154+
return isGroup ? sendGroupMessage(handles, text, img) : sendMessage(id, service, text, img);
155+
});
139156
});
140157
}
158+
141159
handleMatrixUserBangCommand(bangCmd, matrixMsgEvent) {
142160
const { bangcommand, command, body } = bangCmd;
143161
const { room_id } = matrixMsgEvent;

mr-goldenfold.png

-255 KB
Binary file not shown.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
"JSONStream": "^1.3.0",
2121
"bluebird": "^3.4.7",
2222
"chokidar": "^1.6.1",
23-
"matrix-puppet-bridge": "^1.9.0",
23+
"image-size": "^0.5.1",
24+
"matrix-puppet-bridge": "^1.12.0",
25+
"mime-types": "^2.1.15",
2426
"moment": "^2.17.1",
2527
"node-persist": "^2.0.7",
2628
"queue": "^4.0.1"

src/find-attachment.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const Promise = require('bluebird');
2+
const exec = require('child_process').exec;
3+
const config = require('../config.json');
4+
5+
module.exports = function(id, name) {
6+
return new Promise(function(resolve, reject) {
7+
exec(`find ${config.attachmentsDir}/*/*/${name}/${id}`, function(err, stdout, stderr) {
8+
if (err) {
9+
console.error(stderr);
10+
return reject(err);
11+
} else {
12+
return resolve(stdout.trim());
13+
}
14+
});
15+
});
16+
};

src/imessage-send-group.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,22 @@ module.exports = function(handles, _message, file) {
1616
buddySetters.push(`set ${buddyVar} to first buddy whose handle is "${handle}"`);
1717
});
1818

19-
const attachment = () => {
19+
const tellBody = () => {
2020
if ( file ){
2121
return `
2222
set theAttachment1 to POSIX file "${file}"
2323
send theAttachment1 to thisChat
2424
`;
2525
} else {
26-
return '';
26+
return `send "${message}" to thisChat`;
2727
}
2828
};
2929

3030
args.push(`tell application "Messages"
3131
activate
3232
${buddySetters.join('\n\t')}
3333
set thisChat to make new text chat with properties {participants:{${buddyVars.join(',')}}}
34-
${attachment()}
35-
send "${message}" to thisChat
34+
${tellBody()}
3635
end tell`);
3736

3837
console.log('full applescript', args[1]);

src/imessage-send.js

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,22 @@ module.exports = function(to, _method, _message, file) {
1212
console.log('escaped to', message);
1313
let args = ['-e'];
1414

15-
const attachment = (method, buddy) => {
15+
const tellBody = () => {
1616
if ( file ){
1717
return `
1818
set theAttachment1 to POSIX file "${file}"
19-
send theAttachment1 to buddy ${buddy} of ${method}
19+
send theAttachment1 to buddy "${to}" of ${method}
2020
`;
2121
} else {
22-
return '';
22+
return `send "${message}" to buddy "${to}" of ${method}`;
2323
}
2424
};
2525

26-
27-
// If string contains letters, it must be a contact name so
28-
// find the relevant phone number first
29-
if (/[a-z]/i.test(to)) {
30-
args.push(`tell application "Contacts"
31-
set i to value of phone 1 of (person 1 whose name = "${to}")
32-
end tell
33-
tell application "Messages"
34-
${attachment(method, 'i')}
35-
send "${message}" to buddy i of ${method}
36-
end tell`);
37-
} else {
38-
args.push(`tell application "Messages"
39-
${attachment(method, '"'+to+'"')}
40-
send "${message}" to buddy "${to}" of ${method}
26+
args.push(`tell application "Messages"
27+
activate
28+
${tellBody()}
4129
end tell`);
42-
}
30+
4331
console.log('full applescript', args[1]);
4432

4533
return new Promise(function(resolve, reject) {

0 commit comments

Comments
 (0)