-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement most of the appservice code from scratch
- Loading branch information
1 parent
39b1861
commit 5d2fab4
Showing
12 changed files
with
303 additions
and
148 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import type { TimelineEvents } from './deps.ts'; | ||
import type { matrix_user, matrix_config } from './matrix_types.ts'; | ||
|
||
export class appservice { | ||
cfg: matrix_config; | ||
request_id = 0; | ||
user_store: Map<string, matrix_user>; | ||
|
||
constructor(cfg: matrix_config, store: Map<string, matrix_user>) { | ||
this.cfg = cfg; | ||
this.user_store = store; | ||
} | ||
|
||
async request( | ||
path: string, | ||
method: string, | ||
body?: Record<string, unknown> | Blob, | ||
) { | ||
return await (await fetch( | ||
`${this.cfg.homeserver_url}/_matrix/client/${path}`, | ||
{ | ||
method, | ||
body: body | ||
? body instanceof Blob ? body : JSON.stringify(body) | ||
: undefined, | ||
headers: { | ||
'Authorization': `Bearer ${this.cfg.appservice_token}`, | ||
}, | ||
}, | ||
)).json(); | ||
} | ||
|
||
async ensure_user(localpart: string) { | ||
if (this.user_store.has(localpart)) return; | ||
|
||
if ( | ||
!(await this.request( | ||
`v3/register/available?username=${ | ||
encodeURIComponent(localpart) | ||
}`, | ||
'GET', | ||
)).available | ||
) return; | ||
|
||
const register_req = await this.request( | ||
`v3/register`, | ||
'POST', | ||
{ username: localpart, type: 'm.login.application_service' }, | ||
); | ||
|
||
if (register_req.user_id) return; | ||
|
||
throw new Error( | ||
`recieved ${register_req.errcode} when registering for ${localpart}`, | ||
{ cause: register_req }, | ||
); | ||
} | ||
|
||
async redact_event(room_id: string, id: string) { | ||
await this.request( | ||
`v3/rooms/${room_id}/redact/${id}/${this.request_id++}`, | ||
'PUT', | ||
{ | ||
reason: 'bridge message deletion', | ||
}, | ||
); | ||
} | ||
|
||
async join_room(room_id: string) { | ||
await this.request(`v3/join/${room_id}`, 'POST'); | ||
} | ||
|
||
async upload_content(blob: Blob) { | ||
return (await this.request('v3/upload', 'POST', blob)) | ||
.content_uri as string; | ||
} | ||
|
||
async send_message( | ||
room_id: string, | ||
msg: TimelineEvents["m.room.message"], | ||
user_id?: string, | ||
) { | ||
return (await this.request( | ||
`v3/rooms/${room_id}/send/m.room.message/${this | ||
.request_id++}?user_id=${ | ||
user_id || | ||
`@${this.cfg.homeserver_localpart}:${this.cfg.homeserver_domain}` | ||
}`, | ||
'PUT', | ||
msg as unknown as Record<string, unknown>, | ||
)).event_id as string; | ||
} | ||
|
||
async get_profile_info(user_id: string) { | ||
return await this.request( | ||
`v3/profile/${user_id}`, | ||
'GET', | ||
) as matrix_user; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,10 @@ | ||
export { render } from 'jsr:@deno/gfm@0.8.2'; | ||
export { existsSync } from 'jsr:@std/fs@0.229.3/exists'; | ||
export { Buffer } from 'node:buffer'; | ||
export { | ||
AppServiceRegistration, | ||
Bridge, | ||
Intent, | ||
Request, | ||
type WeakEvent, | ||
MatrixUser | ||
} from 'npm:matrix-appservice-bridge@10.1.0'; | ||
export { | ||
type bridge_channel, | ||
type lightning, | ||
type message, | ||
plugin, | ||
} from '../lightning/mod.ts'; | ||
export { Hono } from 'jsr:@hono/hono@4.5.0-rc.1'; | ||
export type { TimelineEvents } from 'npm:matrix-js-sdk@33.1.0'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { Hono } from './deps.ts'; | ||
import type { | ||
matrix_client_event, | ||
matrix_user, | ||
matrix_config | ||
} from './matrix_types.ts'; | ||
|
||
export function start_matrix_server( | ||
cfg: matrix_config, | ||
store: Map<string, matrix_user>, | ||
on_event: (e: matrix_client_event) => Promise<void>, | ||
) { | ||
const app = new Hono(); | ||
const processed_events = new Set<string>(); | ||
|
||
app.use('/_matrix/*', async (c, next) => { | ||
if (c.req.header()['Authorization'] !== cfg.homeservice_token) { | ||
return c.json({ | ||
errcode: 'M_FORBIDDEN', | ||
error: 'for this route, you need to authenticate', | ||
}, 403); | ||
} else { | ||
await next(); | ||
} | ||
}); | ||
|
||
app.put('/_matrix/app/v1/transactions/:txn_id', async (c) => { | ||
if (processed_events.has(c.req.param('txn_id'))) { | ||
return c.json({}, 200); | ||
} | ||
|
||
const body = await c.req.json(); | ||
|
||
await on_event(body); | ||
|
||
return c.json({}, 200); | ||
}); | ||
|
||
app.post('/_matrix/app/v1/ping', (c) => { | ||
return c.json({}, 200); | ||
}); | ||
|
||
app.get('/_matrix/app/v1/users/:user_id', (c) => { | ||
if (store.has(c.req.param('user_id'))) return c.json({}); | ||
|
||
return c.json({ | ||
'errcode': 'dev.williamhorning.lightning.notfound', | ||
'error': "that user doesn't exist", | ||
}, 404); | ||
}); | ||
|
||
Deno.serve({ | ||
port: cfg.plugin_port, | ||
}, app.fetch); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
export interface matrix_client_event { | ||
content: Record<string, unknown>; | ||
event_id: string; | ||
origin_server_ts: number; | ||
room_id: string; | ||
sender: string; | ||
state_key?: string; | ||
type: string; | ||
unsigned?: matrix_unsigned_data; | ||
} | ||
|
||
export interface matrix_unsigned_data { | ||
age?: number; | ||
membership?: string; | ||
prev_content?: Record<string, unknown>; | ||
redacted_because?: matrix_client_event; | ||
transaction_id?: string; | ||
} | ||
|
||
export interface matrix_user { | ||
display_name?: string; | ||
avatar_url?: string; | ||
avatar_mxc?: string; | ||
} | ||
|
||
export interface matrix_config { | ||
/** token used to authenticate to the homeserver */ | ||
appservice_token: string; | ||
/** token used to authenticate to the plugin */ | ||
homeservice_token: string; | ||
/** id used to identify the appservice on the homeserver */ | ||
appservice_id: string; | ||
/** the username of the bot on the homeserver */ | ||
homeserver_localpart: string; | ||
/** the url the plugin's server is accessable from */ | ||
plugin_url: string; | ||
/** the port the plugin listens on */ | ||
plugin_port: number; | ||
/** the prefix for bridged users (such as `lightning-`) */ | ||
homeserver_prefix: string; | ||
/** the path to store the registration file */ | ||
registration_file: string; | ||
/** the url where the homeserver is at */ | ||
homeserver_url: string; | ||
/** the domain users on the homeservers are associated with */ | ||
homeserver_domain: string; | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.