add odysee
parent
288a9b1a27
commit
03d829c3f6
@ -0,0 +1,174 @@
|
||||
if(typeof process === 'object') {
|
||||
var fetch = require('node-fetch');
|
||||
var EventEmitter = require('events');
|
||||
}
|
||||
|
||||
class OdyseeApi extends EventEmitter {
|
||||
constructor(settings) {
|
||||
super();
|
||||
|
||||
settings = settings || {};
|
||||
|
||||
this.apiUrl = settings.apiUrl || 'https://api.odysee.com';
|
||||
this.apiProxyUrl = settings.apiProxyUrl || 'https://api.na-backend.odysee.com/api/v1/proxy';
|
||||
this.commentsApiUrl = settings.commentsApiUrl || 'https://comments.odysee.com/api/v2';
|
||||
this.lbryAuthToken = settings.lbryAuthToken;
|
||||
}
|
||||
|
||||
post(postData, options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var fetchData = {
|
||||
method: 'POST',
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
'Content-type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(postData, 2)
|
||||
};
|
||||
|
||||
this.emit('verbose', 'POST>' + fetchData.body);
|
||||
|
||||
if(!options || !options.noAuth) {
|
||||
if(!this.authToken) {
|
||||
reject(new Error('No access token'));
|
||||
return;
|
||||
}
|
||||
|
||||
fetchData.headers.authorization = this.authToken;
|
||||
}
|
||||
|
||||
fetch(this.apiUrl, fetchData)
|
||||
.then((response) => {
|
||||
return response.json();
|
||||
})
|
||||
.then((json) => {
|
||||
this.emit('verbose', 'POST<' + JSON.stringify(json));
|
||||
if(json.error) {
|
||||
reject(new Error(JSON.stringify(json.error)));
|
||||
} else if(json.errors) {
|
||||
reject(new Error(JSON.stringify(json.errors)));
|
||||
} else {
|
||||
if(json && json.data) {
|
||||
resolve(json.data);
|
||||
} else {
|
||||
reject(new Error(json));
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
})
|
||||
;
|
||||
});
|
||||
}
|
||||
|
||||
loginWithAuthToken(email, authToken) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(!email) {
|
||||
reject('User not specified');
|
||||
return;
|
||||
}
|
||||
|
||||
if(!authToken) {
|
||||
reject('Auth token not specified');
|
||||
return;
|
||||
}
|
||||
|
||||
this.authToken = authToken;
|
||||
|
||||
resolve(true);
|
||||
});
|
||||
}
|
||||
|
||||
channelSign(channelId, lbryAuthToken, data) {
|
||||
return fetch(this.apiProxyUrl + '?m=channel_sign', {
|
||||
method: 'POST',
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
'Authority': 'api.na-backend.odysee.com',
|
||||
'Content-type': 'application/json',
|
||||
'x-lbry-auth-token': lbryAuthToken,
|
||||
'content-type': 'application/json-rpc',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
jsonrpc: "2.0",
|
||||
method: "channel_sign",
|
||||
params: {
|
||||
"channel_id":channelId,
|
||||
"hexdata": Buffer.from(data).toString('hex')
|
||||
}
|
||||
})
|
||||
}).then(response => response.json());
|
||||
}
|
||||
|
||||
commentCreate(data) {
|
||||
return fetch(this.commentsApiUrl+'?m=comment.Create', {
|
||||
method: 'POST',
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
'Origin': 'https://odysee.com',
|
||||
'Referer': 'https://odysee.com/',
|
||||
'Content-type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
jsonrpc: '2.0',
|
||||
id: 1,
|
||||
method: 'comment.Create',
|
||||
params: data
|
||||
})
|
||||
}).then(response => response.json());
|
||||
}
|
||||
|
||||
sendStreamChatMessage(message, channelName, channelId, claimId, lbryAuthToken) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.channelSign(channelId, lbryAuthToken, message).then(response => {
|
||||
this.commentCreate({
|
||||
comment: message,
|
||||
channel_id: channelId,
|
||||
channel_name: channelName,
|
||||
claim_id: claimId,
|
||||
signature: response.result.signature,
|
||||
signing_ts: response.result.signing_ts
|
||||
}).then(response => {
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
apiPost(method, params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let body = new URLSearchParams(params).toString();
|
||||
return fetch(this.apiUrl+'/'+method, {
|
||||
headers: {
|
||||
"content-type": "application/x-www-form-urlencoded",
|
||||
"sec-fetch-dest": "empty",
|
||||
"sec-fetch-mode": "cors",
|
||||
"sec-fetch-site": "same-site",
|
||||
"sec-gpc": "1"
|
||||
},
|
||||
referrer: "https://odysee.com/",
|
||||
referrerPolicy: "strict-origin-when-cross-origin",
|
||||
body,
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
credentials: "omit"
|
||||
}).then(response => response.json()).then(response => {
|
||||
if(response.success)
|
||||
resolve(response.data)
|
||||
else
|
||||
reject(response.error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
userNew() {
|
||||
return this.apiPost('user/new', {});
|
||||
}
|
||||
|
||||
userSignin(auth_token, email, password) {
|
||||
return this.apiPost('user/signin', { auth_token, email, password });
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = OdyseeApi;
|
@ -0,0 +1,729 @@
|
||||
if(typeof process === 'object') {
|
||||
var Channel = require('./Channel');
|
||||
}
|
||||
|
||||
class OdyseeChannel extends Channel {
|
||||
constructor(chat, channelData) {
|
||||
super(chat, channelData);
|
||||
|
||||
this.claim = channelData.claim;
|
||||
this.messageSubId = this.chat.ws.startStreamMessageSubscription(this.claim);
|
||||
this.viewerCount = 0;
|
||||
this.state = 'joined';
|
||||
setTimeout(() => {this.emit('joined');});
|
||||
|
||||
this.chat.ws.addListener('data', (data) => {
|
||||
switch(data.type) {
|
||||
case 'viewers':
|
||||
if(data.data)
|
||||
this.viewerCount = data.data.connected || 0;
|
||||
break;
|
||||
case 'delta':
|
||||
// sticker
|
||||
// {"type":"delta","data":{"comment":{"channel_id":"6a6f4ead96853304bec9647ade538f6009777c38","channel_name":"@vampirefrog","channel_url":"lbry://@vampirefrog#6a6f4ead96853304bec9647ade538f6009777c38","claim_id":"4d7499b149f4a3f40f58175d05dff7e925370556","comment":"\u003cstkr\u003e:SLIME:\u003cstkr\u003e","comment_id":"f9094fdf3cca3faa4bf931905551355456416bebe64616d21da012b843a9b45a","currency":"","is_fiat":false,"is_hidden":false,"is_pinned":false,"signature":"2570eb1b1ef709e2a68eb607ff3a1f489ec14f698d32f91744c0f295b0237a2581552ece96e53c696e49ed165aa1ce607020f2a18f5136ff583a6d921636dc1d","signing_ts":"1635634345","support_amount":0,"timestamp":1635634345}}}
|
||||
// donation 1 lbc
|
||||
// {"type":"delta","data":{"comment":{"channel_id":"6a6f4ead96853304bec9647ade538f6009777c38","channel_name":"@vampirefrog","channel_url":"lbry://@vampirefrog#6a6f4ead96853304bec9647ade538f6009777c38","claim_id":"4d7499b149f4a3f40f58175d05dff7e925370556","comment":"ding dong","comment_id":"2d17b811d779758a2252f8b3803a285907c52f7cf355ffb74157c05d8f710742","currency":"","is_fiat":false,"is_hidden":false,"is_pinned":false,"signature":"360c2490ae6d9fff41db1458f77a406634a181e349c23307c3b9c18666dc3ab28b32bfdd712a2eefd9017f03bb85aadca28c7b908d4e2c9e830544d5652a85c0","signing_ts":"1635634392","support_amount":1,"timestamp":1635634392}}}
|
||||
if(data.data && data.data.comment) {
|
||||
this.emit('message', {
|
||||
type: 'chat',
|
||||
id: data.data.comment.comment_id,
|
||||
original: data.data,
|
||||
|
||||
username: data.data.comment.channel_name,
|
||||
displayName: data.data.comment.channel_name,
|
||||
avatar: null,
|
||||
|
||||
text: data.data.comment.comment,
|
||||
spans: [data.data.comment.comment]
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
sendChat(message) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.chat.api.sendStreamChatMessage(message, this.chat.channelName, this.chat.channelId, this.claim, this.chat.lbryAuthToken).then((message) => {
|
||||
resolve(message);
|
||||
}, (err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_makeId(length) {
|
||||
var result = '';
|
||||
|
||||
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
var charactersLength = characters.length;
|
||||
for ( var i = 0; i < length; i++ ) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
_getGiftValue(type) {
|
||||
var giftValues = {
|
||||
LEMON: 1,
|
||||
ICE_CREAM: 10,
|
||||
DIAMOND: 100,
|
||||
NINJAGHINI: 1000,
|
||||
NINJET: 10000
|
||||
};
|
||||
if(!type in giftValues)
|
||||
return 1;
|
||||
return giftValues[type];
|
||||
}
|
||||
|
||||
_processEmotes(text, emotes) {
|
||||
if(!emotes) {
|
||||
return [ text ];
|
||||
}
|
||||
|
||||
let spans = [];
|
||||
|
||||
let previ = 0;
|
||||
for(let i = 0; i < emotes.length; i += 2) {
|
||||
let emoteStart = emotes[i];
|
||||
let emoteEnd = emotes[i + 1];
|
||||
let between = text.substr(previ, emoteStart - previ);
|
||||
let emote = text.substr(emoteStart, emoteEnd - emoteStart + 1);
|
||||
spans.push(between);
|
||||
spans.push({
|
||||
type: 'image',
|
||||
size: 'small',
|
||||
class: 'emote',
|
||||
src: 'https://images.prd.Odyseecdn.com/emoji/' + emote,
|
||||
alt: emote
|
||||
});
|
||||
previ = emoteEnd + 1;
|
||||
}
|
||||
let last = text.substr(previ);
|
||||
if(last) {
|
||||
spans.push(last);
|
||||
}
|
||||
|
||||
return spans;
|
||||
}
|
||||
|
||||
handleStreamMessage(msg, source) {
|
||||
var testMessages = {
|
||||
Ban2: {"__typename":"ChatBan","type":"Ban","id":"chatban:Odysee-woabgpyuop|kaspaa","sender":{"__typename":"StreamchatUser","id":"streamchatuser:Odysee-woabgpyuop","username":"Odysee-woabgpyuop","displayname":"M_o_h_a_m_a_d","avatar":"https://image.Odyseecdn.com/avatar/default7.png","partnerStatus":"NONE","badges":[],"effect":null},"role":"None","roomRole":"Member","subscribing":false,"bannedBy":{"__typename":"StreamchatUser","id":"streamchatuser:kaspaa","username":"kaspaa","displayname":"Kaspaa","avatar":"https://images.prd.Odyseecdn.com/avatar/efd649c5-0378-11ea-9529-e2443572cd01","partnerStatus":"NONE"},"bannedByRoomRole":"Moderator"},
|
||||
Ban: {"__typename":"ChatBan","type":"Ban","id":"chatban:Odysee-bzmuytbvmk|tctv","sender":{"__typename":"StreamchatUser","id":"streamchatuser:Odysee-bzmuytbvmk","username":"Odysee-bzmuytbvmk","displayname":"PERKY_PAWG_BREAST","avatar":"https://image.Odyseecdn.com/avatar/default8.png","partnerStatus":"NONE","badges":[],"effect":null},"role":"None","roomRole":"Member","subscribing":false,"bannedBy":{"__typename":"StreamchatUser","id":"streamchatuser:tctv","username":"tctv","displayname":"Tctv","avatar":"https://images.prd.Odyseecdn.com/avatar/9da26d8b-1ce5-11ea-9529-e2443572cd01","partnerStatus":"AFFILIATE"},"bannedByRoomRole":"Moderator"},
|
||||
ExtendSub: {"__typename":"ChatExtendSub","id":"b9e5e15b-d754-46a4-b71d-63571975b09f","length":3,"month":1,"role":"None","roomRole":"Member","sender":{"__typename":"StreamchatUser","avatar":"https://images.prd.Odyseecdn.com/avatar/f85df577-6e2f-11ea-8119-a272e850df75","badges":[],"displayname":"PROPRBOY","effect":null,"id":"streamchatuser:proprboy","partnerStatus":"NONE","username":"proprboy"},"subscribing":true,"type":"ExtendSub"},
|
||||
ExtendSub2: {"__typename":"ChatExtendSub","type":"ExtendSub","id":"0ac2a31f-eba4-42cd-980d-e4e524165c9d","sender":{"__typename":"StreamchatUser","id":"streamchatuser:datdoctor","username":"datdoctor","displayname":"WilliamDunham","avatar":"https://images.prd.Odyseecdn.com/avatar/f3559b21-3b9e-11ea-9fd3-a272e850df75","partnerStatus":"NONE","badges":[],"effect":null},"role":"None","roomRole":"Member","subscribing":true,"month":1,"length":1},
|
||||
Follow: {"__typename":"ChatFollow","id":"f936fcb8-ebd5-4f88-9db6-6d4aa18e74d9","role":"None","roomRole":"Member","sender":{"__typename":"StreamchatUser","avatar":"https://images.prd.Odyseecdn.com/avatar/f7fda7f0-bc94-11ea-b737-e2443572cd01","badges":[],"displayname":"r-eVan","effect":null,"id":"streamchatuser:r-evan","partnerStatus":"NONE","username":"r-evan"},"subscribing":false,"type":"Follow"},
|
||||
GiftSub: {"__typename":"ChatGiftSub","type":"GiftSub","id":"7c5741ce-4d68-4904-9a22-15c684bb936b","sender":{"__typename":"StreamchatUser","id":"streamchatuser:thomas42","username":"thomas42","displayname":"thomasthefam","avatar":"https://images.prd.Odyseecdn.com/avatar/69b8b18d-4432-11ea-9529-e2443572cd01","partnerStatus":"NONE","badges":[],"effect":"https://images.prd.Odyseecdn.com/effect/trxsmall"},"role":"None","roomRole":"Moderator","subscribing":true,"receiver":"greenbaywacky","count":null},
|
||||
GiftSubReceive: {"__typename":"ChatGiftSubReceive","type":"GiftSubReceive","id":"6253dfab-10e0-47fd-889e-c8ada929ac02","sender":{"__typename":"StreamchatUser","id":"streamchatuser:greenbaywacky","username":"greenbaywacky","displayname":"greenbaywacky","avatar":"https://images.prd.Odyseecdn.com/avatar/f7672f4e-63f2-11e9-bc94-460601ac0a66","partnerStatus":"VERIFIED_PARTNER","badges":[],"effect":null},"role":"None","roomRole":"Moderator","subscribing":true,"gifter":"thomasthefam"},
|
||||
Host: {"__typename":"ChatHost","id":"8ecb00e0-1061-4d52-804c-b5e7b5ef7ff4","role":"None","roomRole":"Member","sender":{"__typename":"StreamchatUser","avatar":"https://images.prd.Odyseecdn.com/avatar/799c0ae0-a4e2-11ea-b737-e2443572cd01","badges":[],"displayname":"FerociousChihuahua","effect":null,"id":"streamchatuser:ferociouschihuahua","partnerStatus":"AFFILIATE","username":"ferociouschihuahua"},"subscribing":false,"type":"Host","viewer":2},
|
||||
Lemon: {"__typename":"ChatGift","type":"Gift","id":"688b3a22-34c0-4fe5-afbb-e82434013c35","sender":{"__typename":"StreamchatUser","id":"streamchatuser:soren.invicta","username":"soren.invicta","displayname":"Soren.Invicta","avatar":"https://image.Odyseecdn.com/avatar/default12.png","partnerStatus":"NONE","badges":[],"effect":null},"role":"None","roomRole":"Member","subscribing":true,"createdAt":"1610073419355881366","gift":"LEMON","amount":"1","recentCount":1,"expireDuration":0,"message":""},
|
||||
Lemons: {"__typename":"ChatGift","amount":"5","createdAt":"1593804669046558744","expireDuration":0,"gift":"LEMON","id":"5ac8bdb9-8e72-4418-8b37-d0e616e91098","recentCount":1,"role":"None","roomRole":"Moderator","sender":{"__typename":"StreamchatUser","avatar":"https://images.prd.Odyseecdn.com/avatar/799c0ae0-a4e2-11ea-b737-e2443572cd01","badges":[],"displayname":"FerociousChihuahua","effect":null,"id":"streamchatuser:ferociouschihuahua","partnerStatus":"AFFILIATE","username":"ferociouschihuahua"},"subscribing":true,"type":"Gift"},
|
||||
IceCream: {"__typename":"ChatGift","amount":"1","createdAt":"1593804669046558744","expireDuration":0,"gift":"ICE_CREAM","id":"5ac8bdb9-8e72-4418-8b37-d0e616e91098","recentCount":1,"role":"None","roomRole":"Moderator","sender":{"__typename":"StreamchatUser","avatar":"https://images.prd.Odyseecdn.com/avatar/799c0ae0-a4e2-11ea-b737-e2443572cd01","badges":[],"displayname":"FerociousChihuahua","effect":null,"id":"streamchatuser:ferociouschihuahua","partnerStatus":"AFFILIATE","username":"ferociouschihuahua"},"subscribing":true,"type":"Gift"},
|
||||
IceCreams: {"__typename":"ChatGift","amount":"3","createdAt":"1593804669046558744","expireDuration":0,"gift":"ICE_CREAM","id":"5ac8bdb9-8e72-4418-8b37-d0e616e91098","recentCount":1,"role":"None","roomRole":"Moderator","sender":{"__typename":"StreamchatUser","avatar":"https://images.prd.Odyseecdn.com/avatar/799c0ae0-a4e2-11ea-b737-e2443572cd01","badges":[],"displayname":"FerociousChihuahua","effect":null,"id":"streamchatuser:ferociouschihuahua","partnerStatus":"AFFILIATE","username":"ferociouschihuahua"},"subscribing":true,"type":"Gift"},
|
||||
Diamond: {"__typename":"ChatGift","amount":"1","createdAt":"1593804669046558744","expireDuration":0,"gift":"DIAMOND","id":"5ac8bdb9-8e72-4418-8b37-d0e616e91098","message":"Hello Frens","recentCount":1,"role":"None","roomRole":"Moderator","sender":{"__typename":"StreamchatUser","avatar":"https://images.prd.Odyseecdn.com/avatar/799c0ae0-a4e2-11ea-b737-e2443572cd01","badges":[],"displayname":"FerociousChihuahua","effect":null,"id":"streamchatuser:ferociouschihuahua","partnerStatus":"AFFILIATE","username":"ferociouschihuahua"},"subscribing":true,"type":"Gift"},
|
||||
Diamond2: {"__typename":"ChatGift","type":"Gift","id":"a466fc18-58aa-4659-b166-012646cc144d","sender":{"__typename":"StreamchatUser","id":"streamchatuser:Odysee-kphjutjxyt","username":"Odysee-kphjutjxyt","displayname":"97123_vegas","avatar":"https://images.prd.Odyseecdn.com/avatar/default20.png","partnerStatus":"NONE","badges":["CHRISTMAS_TREE","SANTA"],"effect":null},"role":"None","roomRole":"Member","subscribing":true,"createdAt":"1609390512462873916","gift":"DIAMOND","amount":"1","recentCount":1,"expireDuration":0,"message":"2.00 a round for ammo now?"},
|
||||
Diamond3: {"__typename":"ChatGift","type":"Gift","id":"a466fc18-58aa-4659-b166-012646cc144d","sender":{"__typename":"StreamchatUser","id":"streamchatuser:Odysee-kphjutjxyt","username":"Odysee-kphjutjxyt","displayname":"97123_vegas","avatar":"https://images.prd.Odyseecdn.com/avatar/default20.png","partnerStatus":"NONE","badges":["CHRISTMAS_TREE","SANTA"],"effect":null},"role":"None","roomRole":"Member","subscribing":true,"createdAt":"1609390512462873916","gift":"DIAMOND","amount":"1","recentCount":1,"expireDuration":0,"message":"pipipupu https://www.youtube.com/watch?v=3w-r3VtZl_k pupupuipi"},
|
||||
Ninjaghini2: {"__typename":"ChatText","type":"Message","id":"fa701547-daa5-438d-a9b7-30c37dcf70d7","content":"6 ninjaghinis","createdAt":"1609390611166389797","subLength":1,"sender":{"__typename":"StreamchatUser","id":"streamchatuser:iamcheese","username":"iamcheese","displayname":"CEOofWamen","avatar":"https://images.prd.Odyseecdn.com/avatar/bd5c25ca-153b-11eb-aed2-be53b0f89a8c","partnerStatus":"NONE","badges":["CHRISTMAS_TREE"],"effect":null},"role":"None","roomRole":"Member","subscribing":true,"emojis":[]},
|
||||
Ninjaghini: {"__typename":"ChatGift","amount":"1","createdAt":"1593804669046558744","expireDuration":0,"gift":"NINJAGHINI","id":"5ac8bdb9-8e72-4418-8b37-d0e616e91098","message":"Pee Pee poo Poo","recentCount":1,"role":"None","roomRole":"Moderator","sender":{"__typename":"StreamchatUser","avatar":"https://images.prd.Odyseecdn.com/avatar/799c0ae0-a4e2-11ea-b737-e2443572cd01","badges":[],"displayname":"FerociousChihuahua","effect":null,"id":"streamchatuser:ferociouschihuahua","partnerStatus":"AFFILIATE","username":"ferociouschihuahua"},"subscribing":true,"type":"Gift"},
|
||||
Ninjet: {"__typename":"ChatGift","amount":"1","createdAt":"1593804669046558744","expireDuration":0,"gift":"NINJET","id":"5ac8bdb9-8e72-4418-8b37-d0e616e91098","message":"Dee Dee Get Out Of My laboratory","recentCount":1,"role":"None","roomRole":"Moderator","sender":{"__typename":"StreamchatUser","avatar":"https://images.prd.Odyseecdn.com/avatar/799c0ae0-a4e2-11ea-b737-e2443572cd01","badges":[],"displayname":"FerociousChihuahua","effect":null,"id":"streamchatuser:ferociouschihuahua","partnerStatus":"AFFILIATE","username":"ferociouschihuahua"},"subscribing":true,"type":"Gift"},
|
||||
Mod: {"__typename":"ChatModerator","type":"Mod","id":"4ba35866-7b3d-4922-b1e0-a25907f9555e","sender":{"__typename":"StreamchatUser","id":"streamchatuser:thestoryofdori","username":"thestoryofdori","displayname":"TheStoryOfDori13","avatar":"https://images.prd.Odyseecdn.com/avatar/1b0c639f-208d-11ea-bd1e-563a837bad22","partnerStatus":"AFFILIATE","badges":[],"effect":"https://images.prd.Odyseecdn.com/effect/trx"},"role":"None","roomRole":"Moderator","subscribing":true,"add":true},
|
||||
Subscription: {"__typename":"ChatSubscription","type":"Subscription","id":"cc51028f-4042-45b5-9b64-8ce03fb0b5c5","sender":{"__typename":"StreamchatUser","id":"streamchatuser:Odysee-51995646","username":"Odysee-51995646","displayname":"GrimGriz","avatar":"https://images.prd.Odyseecdn.com/avatar/c8e244e6-5c97-11e9-ab17-865634f95b6b","partnerStatus":"NONE","badges":[],"effect":null},"role":"None","roomRole":"Member","subscribing":true,"month":3},
|
||||
SubStreak: {"__typename":"ChatSubStreak","id":"3bd0a19e-8791-410d-b3b2-9f044ba33881","length":2,"role":"None","roomRole":"Member","sender":{"__typename":"StreamchatUser","avatar":"https://images.prd.Odyseecdn.com/avatar/f85df577-6e2f-11ea-8119-a272e850df75","badges":[],"displayname":"PROPRBOY","effect":null,"id":"streamchatuser:proprboy","partnerStatus":"NONE","username":"proprboy"},"subscribing":true,"type":"SubStreak"},
|
||||
TCValue: {"__typename":"ChatTCValueAdd","type":"TCValue","id":"47f8158d-2006-418f-9954-99c160349a5d","sender":{"__typename":"StreamchatUser","id":"streamchatuser:vampirefrog","username":"vampirefrog","displayname":"vampirefrog","avatar":"https://images.prd.Odyseecdn.com/avatar/e3d74c4e-d4fc-11ea-8cd4-c20daac9fa96","partnerStatus":"AFFILIATE","badges":[],"effect":null},"role":"None","roomRole":"Owner","subscribing":false,"amount":"3000000","totalAmount":"5139478"},
|
||||
Timeout: {"__typename":"ChatTimeout","type":"Timeout","id":"0320ec61-2679-4a3e-9f61-c09bcddad6a0","sender":{"__typename":"StreamchatUser","id":"streamchatuser:Odysee-woabgpyuop","username":"Odysee-woabgpyuop","displayname":"M_o_h_a_m_a_d","avatar":"https://image.Odyseecdn.com/avatar/default7.png","partnerStatus":"NONE","badges":[],"effect":null},"role":"None","roomRole":"Member","subscribing":false,"bannedBy":{"__typename":"StreamchatUser","id":"streamchatuser:cascadiannationalist","username":"cascadiannationalist","displayname":"CascadiaPNW","avatar":"https://images.prd.Odyseecdn.com/avatar/52b10bde-b03d-11ea-b737-e2443572cd01","partnerStatus":"NONE"},"minute":5,"bannedByRoomRole":"Moderator"},
|
||||
ValueUpdated: {"id":"1","payload":{"data":{"treasureChestMessageReceived":{"__typename":"TreasureChestValueUpdated","type":"ValueUpdated","value":"659998"}}},"type":"data"},
|
||||
ValueUpdated2: {"payload":{"data":{"treasureChestMessageReceived":{"__typename":"TreasureChestValueUpdated","type":"ValueUpdated","value":"58949778"}}},"id":"1","type":"data"},
|
||||
|
||||
|
||||
// {
|
||||
// "id": "2",
|
||||
// "payload": {
|
||||
// "data": {
|
||||
// "streamMessageReceived": [
|
||||
// {
|
||||
// "__typename": "ChatText",
|
||||
// "content": "not worth what they're asking right now",
|
||||
// "createdAt": "1616108683715187197",
|
||||
// "emojis": [],
|
||||
// "id": "a2548765-a482-4915-8728-0afc02d32b9c",
|
||||
// "role": "None",
|
||||
// "roomRole": "Member",
|
||||
// "sender": {
|
||||
// "__typename": "StreamchatUser",
|
||||
// "avatar": "https://images.prd.Odyseecdn.com/avatar/0645add3-77f0-11eb-8905-b23d0cea717c",
|
||||
// "badges": [
|
||||
// "CHRISTMAS_TREE"
|
||||
// ],
|
||||
// "displayname": "derwiking",
|
||||
// "effect": null,
|
||||
// "id": "streamchatuser:derwiking",
|
||||
// "partnerStatus": "AFFILIATE",
|
||||
// "username": "derwiking"
|
||||
// },
|
||||
// "subLength": 1,
|
||||
// "subscribing": true,
|
||||
// "type": "Message"
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// },
|
||||
// "type": "data"
|
||||
// }
|
||||
|
||||
|
||||
// {
|
||||
// "id": "2",
|
||||
// "payload": {
|
||||
// "data": {
|
||||
// "streamMessageReceived": [
|
||||
// {
|
||||
// "__typename": "ChatText",
|
||||
// "content": "sorry regs.....looks like I am gonna have to hire you....and meme too I guess",
|
||||
// "createdAt": "1616108749441585339",
|
||||
// "emojis": [],
|
||||
// "id": "6a7128e8-a71e-4a10-9744-c06965826abe",
|
||||
// "role": "None",
|
||||
// "roomRole": "Member",
|
||||
// "sender": {
|
||||
// "__typename": "StreamchatUser",
|
||||
// "avatar": "https://images.prd.Odyseecdn.com/avatar/010b90f7-70ca-11eb-8905-b23d0cea717c",
|
||||
// "badges": [
|
||||
// "CHRISTMAS_TREE",
|
||||
// "SANTA"
|
||||
// ],
|
||||
// "displayname": "Rainbow_Raider",
|
||||
// "effect": null,
|
||||
// "id": "streamchatuser:Odysee-44756068",
|
||||
// "partnerStatus": "NONE",
|
||||
// "username": "Odysee-44756068"
|
||||
// },
|
||||
// "subLength": 16,
|
||||
// "subscribing": true,
|
||||
// "type": "Message"
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// },
|
||||
// "type": "data"
|
||||
// }
|
||||
|
||||
|
||||
// {
|
||||
// "id": "2",
|
||||
// "payload": {
|
||||
// "data": {
|
||||
// "streamMessageReceived": [
|
||||
// {
|
||||
// "__typename": "ChatText",
|
||||
// "content": "why is tts so slow, lol",
|
||||
// "createdAt": "1616108964891998893",
|
||||
// "emojis": [],
|
||||
// "id": "27c35945-424f-4a06-84e0-5b6498d79073",
|
||||
// "role": "None",
|
||||
// "roomRole": "Member",
|
||||
// "sender": {
|
||||
// "__typename": "StreamchatUser",
|
||||
// "avatar": "https://images.prd.Odyseecdn.com/avatar/cec35eae-59ed-11eb-8d87-b23d0cea717c",
|
||||
// "badges": [],
|
||||
// "displayname": "jon_jones",
|
||||
// "effect": null,
|
||||
// "id": "streamchatuser:soappy1",
|
||||
// "partnerStatus": "NONE",
|
||||
// "username": "soappy1"
|
||||
// },
|
||||
// "subLength": 1,
|
||||
// "subscribing": true,
|
||||
// "type": "Message"
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// },
|
||||
// "type": "data"
|
||||
// }
|
||||
|
||||
// {
|
||||
// "id": "2",
|
||||
// "payload": {
|
||||
// "data": {
|
||||
// "streamMessageReceived": [
|
||||
// {
|
||||
// "__typename": "ChatText",
|
||||
// "content": "meme the t t s is being tarded",
|
||||
// "createdAt": "1616108967093334840",
|
||||
// "emojis": [],
|
||||
// "id": "39966f91-fcfc-440b-b388-bbbd81c4517f",
|
||||
// "role": "None",
|
||||
// "roomRole": "Member",
|
||||
// "sender": {
|
||||
// "__typename": "StreamchatUser",
|
||||
// "avatar": "https://images.prd.Odyseecdn.com/avatar/010b90f7-70ca-11eb-8905-b23d0cea717c",
|
||||
// "badges": [
|
||||
// "CHRISTMAS_TREE",
|
||||
// "SANTA"
|
||||
// ],
|
||||
// "displayname": "Rainbow_Raider",
|
||||
// "effect": null,
|
||||
// "id": "streamchatuser:Odysee-44756068",
|
||||
// "partnerStatus": "NONE",
|
||||
// "username": "Odysee-44756068"
|
||||
// },
|
||||
// "subLength": 16,
|
||||
// "subscribing": true,
|
||||
// "type": "Message"
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// },
|
||||
// "type": "data"
|
||||
// }
|
||||
|
||||
// {
|
||||
// "id": "2",
|
||||
// "payload": {
|
||||
// "data": {
|
||||
// "streamMessageReceived": [
|
||||
// {
|
||||
// "__typename": "ChatText",
|
||||
// "content": ":emote/mine/regulusmusic/36221b0860053aa_128128:",
|
||||
// "createdAt": "1616109615426339442",
|
||||
// "emojis": [],
|
||||
// "id": "93533540-78f5-41ff-97a0-e3bf40a154de",
|
||||
// "role": "None",
|
||||
// "roomRole": "Moderator",
|
||||
// "sender": {
|
||||
// "__typename": "StreamchatUser",
|
||||
// "avatar": "https://images.prd.Odyseecdn.com/avatar/a4b3b02b-60ba-11e9-bc94-460601ac0a66",
|
||||
// "badges": [
|
||||
// "FOUNDING_MEMBER"
|
||||
// ],
|
||||
// "displayname": "RegulusMusic",
|
||||
// "effect": null,
|
||||
// "id": "streamchatuser:regulusmusic",
|
||||
// "partnerStatus": "AFFILIATE",
|
||||
// "username": "regulusmusic"
|
||||
// },
|
||||
// "subLength": 14,
|
||||
// "subscribing": true,
|
||||
// "type": "Message"
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// },
|
||||
// "type": "data"
|
||||
// }
|
||||
|
||||
// {
|
||||
// "id": "2",
|
||||
// "payload": {
|
||||
// "data": {
|
||||
// "streamMessageReceived": [
|
||||
// {
|
||||
// "__typename": "ChatText",
|
||||
// "content": "hey mememan ",
|
||||
// "createdAt": "1616111126563039849",
|
||||
// "emojis": [],
|
||||
// "id": "0551be02-84a8-4056-8e14-67a0c1c5d288",
|
||||
// "role": "None",
|
||||
// "roomRole": "Moderator",
|
||||
// "sender": {
|
||||
// "__typename": "StreamchatUser",
|
||||
// "avatar": "https://images.prd.Odyseecdn.com/avatar/d4402057-15a5-11eb-b3bd-626a2067d975",
|
||||
// "badges": [
|
||||
// "CHRISTMAS_TREE"
|
||||
// ],
|
||||
// "displayname": "MarkusDP",
|
||||
// "effect": null,
|
||||
// "id": "streamchatuser:markusdp",
|
||||
// "partnerStatus": "VERIFIED_PARTNER",
|
||||
// "username": "markusdp"
|
||||
// },
|
||||
// "subLength": 0,
|
||||
// "subscribing": false,
|
||||
// "type": "Message"
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// },
|
||||
// "type": "data"
|
||||
// }
|
||||
|
||||
};
|
||||
if(msg.type == 'Message' && this.username == msg.sender.username && testMessages[msg.content]) {
|
||||
msg = testMessages[msg.content];
|
||||
msg.id = this._makeId(24);
|
||||
}
|
||||
|
||||
switch(msg.type) {
|
||||
case 'Message':
|
||||
{
|
||||
let spans = [];
|
||||
|
||||
var text = msg.content;
|
||||
var m = text.match(/:emote\/([^/]+)\/([^/]+)\/([^:]+):/);
|
||||
if(m && m[3]) {
|
||||
// If we detect a sticker
|
||||
spans.push({
|
||||
type: 'image',
|
||||
size: 'large',
|
||||
class: 'sticker',
|
||||
src: 'https://images.prd.Odyseecdn.com/emote/'+m[3],
|
||||
alt: m[3]
|
||||
});
|
||||
this.emit('message', {
|
||||
type: 'chat',
|
||||
id: msg.id,
|
||||
original: msg,
|
||||
|
||||
username: msg.sender.username,
|
||||
displayName: msg.sender.displayname,
|
||||
avatar: msg.sender.avatar,
|
||||
|
||||
text: text,
|
||||
spans: spans
|
||||
});
|
||||
} else {
|
||||
this.emit('message', {
|
||||
type: 'chat',
|
||||
id: msg.id,
|
||||
original: msg,
|
||||
|
||||
username: msg.sender.username,
|
||||
displayName: msg.sender.displayname,
|
||||
avatar: msg.sender.avatar,
|
||||
|
||||
text: text,
|
||||
spans: this._processEmotes(text, msg.emojis)
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'Gift':
|
||||
this.emit('message', {
|
||||
type: 'gift',
|
||||
id: msg.id,
|
||||
original: msg,
|
||||
|
||||
username: msg.sender.username,
|
||||
displayName: msg.sender.displayname,
|
||||
avatar: msg.sender.avatar,
|
||||
|
||||
message: msg.message,
|
||||
giftType: msg.gift,
|
||||
currency: 'LEMON',
|
||||
value: this._getGiftValue(msg.gift),
|
||||
amount: parseInt(msg.amount)
|
||||
});
|
||||
break;
|
||||
case 'Follow':
|
||||
this.emit('message', {
|
||||
type: 'follow',
|
||||
id: msg.id,
|
||||
original: msg,
|
||||
|
||||
username: msg.sender.username,
|
||||
displayName: msg.sender.displayname,
|
||||
avatar: msg.sender.avatar
|
||||
});
|
||||
break;
|
||||
case 'Host':
|
||||
this.emit('message', {
|
||||
type: 'host',
|
||||
id: msg.id,
|
||||
original: msg,
|
||||
|
||||
username: msg.sender.username,
|
||||
displayName: msg.sender.displayname,
|
||||
avatar: msg.sender.avatar,
|
||||
|
||||
viewers: msg.viewer
|
||||
});
|
||||
break;
|
||||
case 'Subscription':
|
||||
this.emit('message', {
|
||||
type: 'subscribe',
|
||||
id: msg.id,
|
||||
original: msg,
|
||||
|
||||
username: msg.sender.username,
|
||||
displayName: msg.sender.displayname,
|
||||
avatar: msg.sender.avatar,
|
||||
|
||||
months: msg.month
|
||||
});
|
||||
break;
|
||||
case 'ExtendSub':
|
||||
this.emit('message', {
|
||||
type: 'resubscribe',
|
||||
id: msg.id,
|
||||
original: msg,
|
||||
|
||||
username: msg.sender.username,
|
||||
displayName: msg.sender.displayname,
|
||||
avatar: msg.sender.avatar,
|
||||
|
||||
length: msg.length,
|
||||
months: msg.month
|
||||
});
|
||||
break;
|
||||
case 'GiftSub':
|
||||
this.emit('message', {
|
||||
type: 'giftSub',
|
||||
id: msg.id,
|
||||
original: msg,
|
||||
|
||||
username: msg.sender.username,
|
||||
displayName: msg.sender.displayname,
|
||||
avatar: msg.sender.avatar,
|
||||
|
||||
receiver: msg.receiver
|
||||
});
|
||||
break;
|
||||
case 'GiftSubReceive':
|
||||
this.emit('message', {
|
||||
type: 'giftSubReceive',
|
||||
id: msg.id,
|
||||
original: msg,
|
||||
|
||||
username: msg.sender.username,
|
||||
displayName: msg.sender.displayname,
|
||||
avatar: msg.sender.avatar,
|
||||
|
||||
gifter: msg.gifter
|
||||
});
|
||||
break;
|
||||
case 'SubStreak':
|
||||
this.emit('message', {
|
||||
type: 'subStreak',
|
||||
id: msg.id,
|
||||
original: msg,
|
||||
|
||||
username: msg.sender.username,
|
||||
displayName: msg.sender.displayname,
|
||||
avatar: msg.sender.avatar,
|
||||
|
||||
length: msg.length
|
||||
});
|
||||
break;
|
||||
case 'TCValue':
|
||||
this.emit('message', {
|
||||
type: 'chestValue',
|
||||
id: msg.id,
|
||||
original: msg,
|
||||
|
||||
username: msg.sender.username,
|
||||
displayName: msg.sender.displayname,
|
||||
avatar: msg.sender.avatar,
|
||||
|
||||
currency: 'lemon',
|
||||
currencyPlural: 'lemons',
|
||||
amount: msg.amount / 100000.0,
|
||||
totalAmount: msg.totalAmount / 100000.0
|
||||
});
|
||||
break;
|
||||
case 'TCValueAdd':
|
||||
break;
|
||||
case 'Clip':
|
||||
break;
|
||||
case 'Delete':
|
||||
this.emit('message', {
|
||||
type: 'delete',
|
||||
id: msg.id,
|
||||
original: msg,
|
||||
|
||||
ids: msg.ids
|
||||
});
|
||||
break;
|
||||
case 'Ban':
|
||||
this.emit('message', {
|
||||
type: 'ban',
|
||||
id: msg.id,
|
||||
original: msg,
|
||||
|
||||
username: msg.sender.username,
|
||||
displayName: msg.sender.displayname,
|
||||
avatar: msg.sender.avatar,
|
||||
|
||||
bannedByUsername: msg.bannedBy.username,
|
||||
bannedByDisplayName: msg.bannedBy.displayname,
|
||||
bannedByAvatar: msg.bannedBy.avatar,
|
||||
bannedByPartnerStatus: msg.bannedBy.partnerStatus,
|
||||
bannedByRoomRole: msg.bannedByRoomRole
|
||||
});
|
||||
break;
|
||||
case 'Timeout':
|
||||
// Timeout is from 1 to 60 minutes
|
||||
this.emit('message', {
|
||||
type: 'timeout',
|
||||
id: msg.id,
|
||||
original: msg,
|
||||
|
||||
username: msg.sender.username,
|
||||
displayName: msg.sender.displayname,
|
||||
avatar: msg.sender.avatar,
|
||||
|
||||
seconds: msg.minute * 60
|
||||
});
|
||||
break;
|
||||
case 'Mod':
|
||||
this.emit('message', {
|
||||
type: 'moderator',
|
||||
id: msg.id,
|
||||
original: msg,
|
||||
|
||||
username: msg.sender.username,
|
||||
displayName: msg.sender.displayname,
|
||||
avatar: msg.sender.avatar,
|
||||
|
||||
add: msg.add
|
||||
});
|
||||
break;
|
||||
case 'ChangeMode':
|
||||
break;
|
||||
case 'EmoteAdd':
|
||||
break;
|
||||
default:
|
||||
this.emit('message', {
|
||||
type: 'unknown',
|
||||
id: msg.id,
|
||||
original: msg
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
isJoined() {
|
||||
return this.state == 'joined';
|
||||
}
|
||||
|
||||
getNumViewers() {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve({ viewers: this.viewerCount, platform: this.chat.getPlatformName() });
|
||||
});
|
||||
}
|
||||
|
||||
getStatus(original) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.chat.api.post({
|
||||
operationName: 'LivestreamPageRefetch',
|
||||
variables: {
|
||||
username: this.username
|
||||
},
|
||||
query: `
|
||||
query LivestreamPageRefetch(
|
||||
$username: String!
|
||||
) {
|
||||
user(username: $username) {
|
||||
avatar
|
||||
chatDisabled
|
||||
chatInterval
|
||||
chatLinkDisabled
|
||||
chatMode
|
||||
chatVerifiedOnly
|
||||
displayname
|
||||
donateDisabled
|
||||
effect
|
||||
followChatDelay
|
||||
isFollowing
|
||||
isMe
|
||||
isSubscribing
|
||||
followers {
|
||||
totalCount
|
||||
}
|
||||
following {
|
||||
totalCount
|
||||
}
|
||||
ongoingGiftSub {
|
||||
gifter {
|
||||
displayname
|
||||
id
|
||||
username
|
||||
avatar
|
||||
}
|
||||
count
|
||||
}
|
||||
partnerStatus
|
||||
role
|
||||
subscribeDisabled
|
||||
username
|
||||
livestream {
|
||||
id
|
||||
permlink
|
||||
title
|
||||
totalReward
|
||||
watchingCount
|
||||
createdAt
|
||||
category {
|
||||
id
|
||||
title
|
||||
}
|
||||
creator {
|
||||
displayname
|
||||
id
|
||||
username
|
||||
}
|
||||
language {
|
||||
id
|
||||
language
|
||||
}
|
||||
thumbnailUrl
|
||||
ageRestriction
|
||||
earnRestriction
|
||||
}
|
||||
subSetting {
|
||||
badgeColor
|
||||
badgeText
|
||||
benefits
|
||||
streakTextColor
|
||||
textColor
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
}).then((data) => {
|
||||
if(original) {
|
||||
resolve(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!data || !data.user) {
|
||||
reject(data ? data : 'No data');
|
||||
return;
|
||||
}
|
||||
|
||||
resolve({
|
||||
platform: this.chat.getPlatformName(),
|
||||
clientId: this.chat.id,
|
||||
channelId: this.id,
|
||||
user: {
|
||||
avatar: data.user.avatar,
|
||||
displayName: data.user.displayname,
|
||||
followers: data.user.followers.totalCount,
|
||||
following: data.user.following.totalCount,
|
||||
},
|
||||
stream: data.user.livestream ? {
|
||||
isLive: true,
|
||||
startTime: data.user.livestream.createdAt / 1000,
|
||||
viewers: data.user.livestream.watchingCount,
|
||||
title: data.user.livestream.title,
|
||||
preview: data.user.livestream.thumbnailUrl,
|
||||
language: data.user.livestream.language.language,
|
||||
audienceType: data.user.livestream.ageRestriction ? 'X-Tag' : data.user.livestream.earnRestriction ? 'Mature-Tag' : null,
|
||||
category: {
|
||||
id: data.user.livestream.category.id,
|
||||
name: data.user.livestream.category.title,
|
||||
}
|
||||
} : { isLive: false },
|
||||
chat: {
|
||||
interval: data.user.chatInterval
|
||||
}
|
||||
});
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(typeof process === 'object') {
|
||||
module.exports = OdyseeChannel;
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
// node.js only
|
||||
var Chat = require('./Chat');
|
||||
var OdyseeChannel = require('./OdyseeChannel');
|
||||
var OdyseeSocket = require('./OdyseeSocket');
|
||||
var OdyseeApi = require('./OdyseeApi');
|
||||
var fetch = require('node-fetch');
|
||||
|
||||
class OdyseeChat extends Chat {
|
||||
constructor(settings) {
|
||||
super(settings);
|
||||
|
||||
settings = settings || {};
|
||||
|
||||
this.ws = new OdyseeSocket({ claim: settings.claim });
|
||||
this.ws.addListener('verbose', (msg) => { this.log(msg); });
|
||||
|
||||
this.api = new OdyseeApi(settings.apiUrl);
|
||||
this.api.addListener('verbose', (msg) => { this.log(msg); });
|
||||
|
||||
this.channelName = settings.channelName;
|
||||
this.channelId = settings.channelId;
|
||||
|
||||
if(settings.lbryAuthToken) {
|
||||
this.lbryAuthToken = settings.lbryAuthToken;
|
||||
setTimeout(() => {
|
||||
this.state = 'ready';
|
||||
this.emit('ready');
|
||||
});
|
||||
} else {
|
||||
this.api.userNew().then(response => {
|
||||
this.lbryAuthToken = response.auth_token
|
||||
if(settings.username && settings.password) {
|
||||
this.api.userSignin(this.lbryAuthToken, settings.username, settings.password).then(response => {
|
||||
this.state = 'ready';
|
||||
this.emit('ready');
|
||||
}).catch(e => {
|
||||
console.error('Error signing in to Odysee', e);
|
||||
});
|
||||
}
|
||||
}).catch(e => {
|
||||
console.error('Error getting Odysee auth token', e);
|
||||
});
|
||||
}
|
||||
|
||||
// if(settings.email) {
|
||||
// if(settings.authToken) {
|
||||
// this.log('logging in with access token', settings.email);
|
||||
// this.api.loginWithAuthToken(settings.email, settings.authToken)
|
||||
// .then((login) => {
|
||||
// this.state = 'ready';
|
||||
// this.emit('ready');
|
||||
// }, (err) => {
|
||||
// throw new Error('Could not login with authToken: '+err.toString());
|
||||
// })
|
||||
// ;
|
||||
// } else if(settings.password) {
|
||||
// this.api.login(settings.email, settings.password)
|
||||
// .then((login) => {
|
||||
// this.state = 'ready';
|
||||
// this.emit('ready');
|
||||
// }, (err) => {
|
||||
// throw new Error('Could not login with password: '+err.toString());
|
||||
// })
|
||||
// ;
|
||||
// } else {
|
||||
// this.state = 'ready';
|
||||
// this.emit('ready');
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
getPlatformName() { return 'odysee'; }
|
||||
|
||||
_joinChannelByUsername(channelData) {
|
||||
let channel = new OdyseeChannel(this, channelData);
|
||||
|
||||
channel.id = channelData.claim + '-' + this._generateRandomString(8);
|
||||
|
||||
this.channels[channel.id] = channel;
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
joinChannel(channelData) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(channelData.claim) {
|
||||
return resolve(this._joinChannelByUsername(channelData));
|
||||
} else reject(new Error('No claim specified!'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(typeof process === 'object') {
|
||||
module.exports = OdyseeChat;
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
var WebSocket = require('isomorphic-ws');
|
||||
var EventEmitter = require('events');
|
||||
|
||||
class OdyseeSocket extends EventEmitter {
|
||||
constructor(config) {
|
||||
super();
|
||||
|
||||
config = config || {};
|
||||
|
||||
this.wsUrl = 'wss://sockety.odysee.com/ws/commentron';
|
||||
|
||||
this.id = 1;
|
||||
this.subscriptions = {};
|
||||
this.queue = [];
|
||||
|
||||
// Keepalive
|
||||
this.expectedPingInterval = config.expectedPingInterval || 20000; // miliseconds
|
||||
this.reconnectDelay = config.reconnectDelay || 2000;
|
||||
this.pingTimeout = null;
|
||||
|
||||
this.webSocket = null;
|
||||
}
|
||||
|
||||
_sendToWebsocket(json) {
|
||||
this.webSocket.send(json);
|
||||
this.emit('verbose', 'SEND ' + json);
|
||||
}
|
||||
|
||||
send(data) {
|
||||
var json = JSON.stringify(data);
|
||||
|
||||
if(!this.webSocket || this.webSocket.readyState != 1) {
|
||||
this.queue.push(json);
|
||||
return;
|
||||
}
|
||||
|
||||
this._sendToWebsocket(json);
|
||||
}
|
||||
|
||||
clearPingTimeout() {
|
||||
if(this.pingTimeout)
|
||||
clearTimeout(this.pingTimeout);
|
||||
}
|
||||
|
||||
setPingTimeout() {
|
||||
this.clearPingTimeout();
|
||||
this.pingTimeout = setTimeout(() => { this.connect(); }, this.expectedPingInterval + this.reconnectDelay);
|
||||
}
|
||||
|
||||
connect() {
|
||||
let wsUrl = this.wsUrl + '?id='+this.claim+'&category='+this.claim;
|
||||
console.log('Connecting to WS', wsUrl);
|
||||
this.emit('verbose', 'Opening WebSocket ' + wsUrl);
|
||||
this.webSocket = new WebSocket(wsUrl, { headers: { 'Accept-Language': 'en-US,en;q=0.9', 'Origin': 'https://odysee.com'}});
|
||||
this.webSocket.onopen = (evt) => {
|
||||
this.emit('verbose', 'websocket open');
|
||||
this.emit('open');
|
||||
if(this.queue.length > 0) {
|
||||
for(let i in this.queue) {
|
||||
if(this.webSocket.readyState != 1)
|
||||
continue; // prevent losses
|
||||
this._sendToWebsocket(this.queue[i]);
|
||||
}
|
||||
this.queue = [];
|
||||
}
|
||||
};
|
||||
this.webSocket.onclose = (evt) => {
|
||||
this.emit('verbose', 'websocket close');
|
||||
if(this.webSocket)
|
||||
this.webSocket.onopen = this.webSocket.onclose = this.webSocket.onerror = this.webSocket.onmessage = undefined;
|
||||
this.webSocket = null;
|
||||
this.clearPingTimeout();
|
||||
setTimeout(() => { this.connect(); }, this.reconnectDelay);
|
||||
};
|
||||
this.webSocket.onerror = (evt) => {
|
||||
this.emit('verbose', 'websocket error');
|
||||
if(this.webSocket)
|
||||
this.webSocket.onopen = this.webSocket.onclose = this.webSocket.onerror = this.webSocket.onmessage = undefined;
|
||||
this.webSocket = null;
|
||||
this.clearPingTimeout();
|
||||
setTimeout(() => { this.connect(); }, this.reconnectDelay);
|
||||
};
|
||||
this.webSocket.onmessage = (ev) => {
|
||||
this.emit('verbose', 'RECV ' + ev.data.replace(/\s*$/, ''));
|
||||
var data;
|
||||
try {
|
||||
data = JSON.parse(ev.data);
|
||||
} catch(e) {
|
||||
this.error('Could not parse JSON', ev.data, e);
|
||||
}
|
||||
if(data)
|
||||
this.handleWebsocketMessage(data);
|
||||
};
|
||||
}
|
||||
|
||||
isConnected() {
|
||||
return this.webSocket && this.webSocket.readyState == 1;
|
||||
}
|
||||
|
||||
handleWebsocketMessage(data) {
|
||||
this.emit('data', data);
|
||||
}
|
||||
|
||||
startStreamMessageSubscription(claim) {
|
||||
this.claim = claim;
|
||||
this.connect();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = OdyseeSocket;
|
Loading…
Reference in New Issue