Skip to content

Commit

Permalink
refa: support generic satori
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Oct 22, 2023
1 parent 9cdb980 commit 0395ebc
Show file tree
Hide file tree
Showing 64 changed files with 257 additions and 294 deletions.
4 changes: 2 additions & 2 deletions adapters/dingtalk/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import { Internal } from './internal'
const logger = new Logger('dingtalk')

// https://open.dingtalk.com/document/orgapp/enterprise-created-chatbot
export class DingtalkBot extends Bot<DingtalkBot.Config> {
export class DingtalkBot<C extends Context = Context> extends Bot<C, DingtalkBot.Config> {
static MessageEncoder = DingtalkMessageEncoder

public oldHttp: Quester
public http: Quester
public internal: Internal
private refreshTokenTimer: NodeJS.Timeout

constructor(ctx: Context, config: DingtalkBot.Config) {
constructor(ctx: C, config: DingtalkBot.Config) {
super(ctx, config)
this.platform = 'dingtalk'
this.selfId = config.appkey
Expand Down
8 changes: 2 additions & 6 deletions adapters/dingtalk/src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,10 @@ import crypto from 'node:crypto'
import { Message } from './types'
import { decodeMessage } from './utils'

export class HttpServer extends Adapter<DingtalkBot> {
export class HttpServer<C extends Context = Context> extends Adapter<C, DingtalkBot<C>> {
logger = new Logger('dingtalk')

constructor(ctx: Context, bot: DingtalkBot) {
super()
}

async connect(bot: DingtalkBot) {
async connect(bot: DingtalkBot<C>) {
await bot.refreshToken()
await bot.getLogin()

Expand Down
4 changes: 2 additions & 2 deletions adapters/dingtalk/src/message.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Dict, h, MessageEncoder } from '@satorijs/satori'
import { Context, Dict, h, MessageEncoder } from '@satorijs/satori'
import { DingtalkBot } from './bot'
import FormData from 'form-data'
import { SendMessageData } from './types'
Expand All @@ -14,7 +14,7 @@ export const unescape = (val: string) =>
val
.replace(/\u200b([\*_~`])/g, '$1')

export class DingtalkMessageEncoder extends MessageEncoder<DingtalkBot> {
export class DingtalkMessageEncoder<C extends Context = Context> extends MessageEncoder<C, DingtalkBot<C>> {
buffer = ''

/**
Expand Down
4 changes: 2 additions & 2 deletions adapters/dingtalk/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { h, Session } from '@satorijs/satori'
import { Context, h } from '@satorijs/satori'
import { Message } from './types'
import { DingtalkBot } from './bot'

export async function decodeMessage(bot: DingtalkBot, body: Message): Promise<Session> {
export async function decodeMessage<C extends Context>(bot: DingtalkBot<C>, body: Message) {
const session = bot.session()
session.type = 'message'
session.messageId = body.msgId
Expand Down
4 changes: 2 additions & 2 deletions adapters/dingtalk/src/ws.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Adapter, Schema } from '@satorijs/satori'
import { Adapter, Context, Schema } from '@satorijs/satori'
import { DingtalkBot } from './bot'
import { decodeMessage } from './utils'

export class WsClient extends Adapter.WsClient<DingtalkBot> {
export class WsClient<C extends Context = Context> extends Adapter.WsClient<C, DingtalkBot<C>> {
async prepare() {
await this.bot.refreshToken()
await this.bot.getLogin()
Expand Down
4 changes: 2 additions & 2 deletions adapters/discord/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { version } from '../package.json'

const logger = new Logger('discord')

export class DiscordBot extends Bot<DiscordBot.Config> {
export class DiscordBot<C extends Context = Context> extends Bot<C, DiscordBot.Config> {
static MessageEncoder = DiscordMessageEncoder

public http: Quester
Expand All @@ -18,7 +18,7 @@ export class DiscordBot extends Bot<DiscordBot.Config> {
public webhookLock: Record<string, Promise<Webhook>> = {}
public commands: Universal.Command[] = []

constructor(ctx: Context, config: DiscordBot.Config) {
constructor(ctx: C, config: DiscordBot.Config) {
super(ctx, config)
this.platform = 'discord'
this.http = ctx.http.extend({
Expand Down
4 changes: 2 additions & 2 deletions adapters/discord/src/message.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Dict, h, Logger, MessageEncoder, Quester, Schema, Universal } from '@satorijs/satori'
import { Context, Dict, h, Logger, MessageEncoder, Quester, Schema, Universal } from '@satorijs/satori'
import FormData from 'form-data'
import { DiscordBot } from './bot'
import { ActionRow, Button, ButtonStyles, Channel, ComponentType, Message } from './types'
Expand All @@ -18,7 +18,7 @@ class State {
constructor(public type: 'message' | 'forward') { }
}

export class DiscordMessageEncoder extends MessageEncoder<DiscordBot> {
export class DiscordMessageEncoder<C extends Context = Context> extends MessageEncoder<C, DiscordBot<C>> {
private stack: State[] = [new State('message')]
private buffer: string = ''
private addition: Dict = {}
Expand Down
4 changes: 2 additions & 2 deletions adapters/discord/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Dict, h, pick, Session, Universal, valueMap } from '@satorijs/satori'
import { Context, Dict, h, pick, Session, Universal, valueMap } from '@satorijs/satori'
import { DiscordBot } from './bot'
import * as Discord from './types'

Expand Down Expand Up @@ -170,7 +170,7 @@ function setupReaction(session: Session, data: ReactionEvent) {
session.content = id ? `${name}:${id}` : name
}

export async function adaptSession(bot: DiscordBot, input: Discord.Gateway.Payload) {
export async function adaptSession<C extends Context>(bot: DiscordBot<C>, input: Discord.Gateway.Payload) {
const session = bot.session()
session.setInternal('discord', input)
if (input.t === 'MESSAGE_CREATE') {
Expand Down
4 changes: 2 additions & 2 deletions adapters/discord/src/ws.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Adapter, Logger, Schema } from '@satorijs/satori'
import { Adapter, Context, Logger, Schema } from '@satorijs/satori'
import { Gateway } from './types'
import { adaptSession, decodeUser } from './utils'
import { DiscordBot } from './bot'

const logger = new Logger('discord')

export class WsClient extends Adapter.WsClient<DiscordBot> {
export class WsClient<C extends Context = Context> extends Adapter.WsClient<C, DiscordBot<C>> {
_d = 0
_ping: NodeJS.Timeout
_sessionId = ''
Expand Down
4 changes: 2 additions & 2 deletions adapters/kook/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { WsClient } from './ws'
import { HttpServer } from './http'
import { isDirectChannel, KookMessageEncoder } from './message'

export class KookBot<T extends KookBot.Config = KookBot.Config> extends Bot<T> {
export class KookBot<C extends Context = Context, T extends KookBot.Config = KookBot.Config> extends Bot<C, T> {
static MessageEncoder = KookMessageEncoder

http: Quester
internal: Kook.Internal

constructor(ctx: Context, config: T) {
constructor(ctx: C, config: T) {
super(ctx, config)
this.platform = 'kook'
this.http = ctx.http.extend({
Expand Down
4 changes: 2 additions & 2 deletions adapters/kook/src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { adaptSession } from './utils'

const logger = new Logger('kook')

export class HttpServer extends Adapter<KookBot<KookBot.BaseConfig & HttpServer.Config>> {
constructor(ctx: Context, bot: KookBot) {
export class HttpServer<C extends Context = Context> extends Adapter<C, KookBot<C, KookBot.BaseConfig & HttpServer.Config>> {
constructor(ctx: C, bot: KookBot<C>) {
super()
let { path } = bot.config as HttpServer.Config
path = sanitize(path)
Expand Down
4 changes: 2 additions & 2 deletions adapters/kook/src/message.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { h, MessageEncoder, Schema } from '@satorijs/satori'
import { Context, h, MessageEncoder, Schema } from '@satorijs/satori'
import FormData from 'form-data'
import { KookBot } from './bot'
import * as Kook from './types'
Expand All @@ -10,7 +10,7 @@ export function isDirectChannel(channelId: string) {
return channelId.length > 30
}

export class KookMessageEncoder extends MessageEncoder<KookBot> {
export class KookMessageEncoder<C extends Context = Context> extends MessageEncoder<C, KookBot<C>> {
private path: string
private params = {} as Partial<Kook.MessageParams>
private additional = {} as Partial<Kook.MessageParams>
Expand Down
4 changes: 2 additions & 2 deletions adapters/kook/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Bot, h, hyphenate, isNullable, Session, Universal } from '@satorijs/satori'
import { Bot, Context, h, hyphenate, isNullable, Session, Universal } from '@satorijs/satori'
import * as Kook from './types'

export * from './types'
Expand Down Expand Up @@ -147,7 +147,7 @@ function adaptReaction(body: Kook.NoticeBody, session: Session) {
session['emoji'] = body.emoji.id
}

export function adaptSession(bot: Bot, input: any) {
export function adaptSession<C extends Context>(bot: Bot<C>, input: any) {
const session = bot.session()
session.setInternal('kook', input)
if (input.type === Kook.Type.system) {
Expand Down
4 changes: 2 additions & 2 deletions adapters/kook/src/ws.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Adapter, Logger, Schema, Time, Universal } from '@satorijs/satori'
import { Adapter, Context, Logger, Schema, Time, Universal } from '@satorijs/satori'
import { KookBot } from './bot'
import { adaptSession } from './utils'
import { Payload, Signal } from './types'
Expand All @@ -7,7 +7,7 @@ const logger = new Logger('kook')

const heartbeatIntervals = [6, 2, 4]

export class WsClient extends Adapter.WsClient<KookBot<KookBot.BaseConfig & WsClient.Config>> {
export class WsClient<C extends Context = Context> extends Adapter.WsClient<C, KookBot<C, KookBot.BaseConfig & WsClient.Config>> {
_sn = 0
_ping: NodeJS.Timeout
_heartbeat: NodeJS.Timeout
Expand Down
4 changes: 2 additions & 2 deletions adapters/lark/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as Utils from './utils'

const logger = new Logger('lark')

export class LarkBot extends Bot<LarkBot.Config> {
export class LarkBot<C extends Context = Context> extends Bot<C, LarkBot.Config> {
static MessageEncoder = LarkMessageEncoder

_token?: string
Expand All @@ -16,7 +16,7 @@ export class LarkBot extends Bot<LarkBot.Config> {
assetsQuester: Quester
internal: Internal

constructor(ctx: Context, config: LarkBot.Config) {
constructor(ctx: C, config: LarkBot.Config) {
super(ctx, config)

// lark bot needs config.selfUrl to be set as it should be serve on a public url
Expand Down
4 changes: 2 additions & 2 deletions adapters/lark/src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import { adaptSession, Cipher } from './utils'

const logger = new Logger('lark')

export class HttpServer extends Adapter<FeishuBot> {
export class HttpServer<C extends Context = Context> extends Adapter<C, FeishuBot<C>> {
private ciphers: Record<string, Cipher> = {}

fork(ctx: Context, bot: FeishuBot) {
fork(ctx: C, bot: FeishuBot<C>) {
super.fork(ctx, bot)

this._refreshCipher()
Expand Down
4 changes: 2 additions & 2 deletions adapters/lark/src/message.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createReadStream } from 'fs'
import internal from 'stream'

import { h, MessageEncoder, Quester } from '@satorijs/satori'
import { Context, h, MessageEncoder, Quester } from '@satorijs/satori'
import FormData from 'form-data'

import { LarkBot } from './bot'
Expand All @@ -13,7 +13,7 @@ export interface Addition {
type: MessageType
}

export class LarkMessageEncoder extends MessageEncoder<LarkBot> {
export class LarkMessageEncoder<C extends Context = Context> extends MessageEncoder<C, LarkBot<C>> {
private quote: string | undefined
private content = ''
private addition: Addition
Expand Down
4 changes: 2 additions & 2 deletions adapters/lark/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import crypto from 'crypto'
import { Channel, Guild, Message, User } from '@satorijs/protocol'
import { h, Session, trimSlash } from '@satorijs/satori'
import { Context, h, Session, trimSlash } from '@satorijs/satori'
import { FeishuBot, LarkBot } from './bot'
import { AllEvents, Events, Lark, Message as LarkMessage, MessageContentType, MessageType } from './types'

Expand Down Expand Up @@ -68,7 +68,7 @@ export function adaptMessage(bot: FeishuBot, data: Events['im.message.receive_v1
return session
}

export function adaptSession(bot: FeishuBot, body: AllEvents): Session {
export function adaptSession<C extends Context>(bot: FeishuBot<C>, body: AllEvents) {
const session = bot.session()
session.setInternal('lark', body)

Expand Down
4 changes: 2 additions & 2 deletions adapters/line/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import { LineMessageEncoder } from './message'

const logger = new Logger('line')

export class LineBot extends Bot<LineBot.Config> {
export class LineBot<C extends Context = Context> extends Bot<C, LineBot.Config> {
static MessageEncoder = LineMessageEncoder
public http: Quester
public contentHttp: Quester
public internal: Internal

constructor(ctx: Context, config: LineBot.Config) {
constructor(ctx: C, config: LineBot.Config) {
super(ctx, config)
if (!ctx.root.config.selfUrl) {
logger.warn('selfUrl is not set, some features may not work')
Expand Down
6 changes: 3 additions & 3 deletions adapters/line/src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { WebhookRequestBody } from './types'
import { adaptSessions } from './utils'
import internal from 'stream'

export class HttpServer extends Adapter<LineBot> {
export class HttpServer<C extends Context = Context> extends Adapter<C, LineBot<C>> {
logger = new Logger('line')

constructor(ctx: Context, bot: LineBot) {
constructor(ctx: C, bot: LineBot) {
super()
}

async connect(bot: LineBot) {
async connect(bot: LineBot<C>) {
bot.ctx.router.post('/line', async (ctx) => {
const sign = ctx.headers['x-line-signature']?.toString()
const parsed = ctx.request.body as WebhookRequestBody
Expand Down
4 changes: 2 additions & 2 deletions adapters/line/src/message.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Dict, h, MessageEncoder } from '@satorijs/satori'
import { Context, Dict, h, MessageEncoder } from '@satorijs/satori'
import { LineBot } from './bot'
import * as Line from './types'

Expand All @@ -10,7 +10,7 @@ export const unescape = (val: string) =>
val
.replace(/\u200b([\*_~`])/g, '$1')

export class LineMessageEncoder extends MessageEncoder<LineBot> {
export class LineMessageEncoder<C extends Context = Context> extends MessageEncoder<C, LineBot<C>> {
buffer = ''
blocks: Line.Message[] = []
sender: Line.Sender = {}
Expand Down
50 changes: 6 additions & 44 deletions adapters/mail/src/bot.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,19 @@
import { Bot, Context, Logger, Schema, Universal } from '@satorijs/satori'
import { ParsedMail } from 'mailparser'
import { Bot, Context, Schema } from '@satorijs/satori'
import { IMAP, SMTP } from './mail'
import { MailMessageEncoder } from './message'
import { dispatchSession } from './utils'

const logger = new Logger('adapter-mail')

export class MailBot extends Bot<MailBot.Config> {
export class MailBot<C extends Context = Context> extends Bot<C, MailBot.Config> {
static MessageEncoder = MailMessageEncoder

imap: IMAP
smtp: SMTP
internal: SMTP

constructor(ctx: Context, config: MailBot.Config) {
constructor(ctx: C, config: MailBot.Config) {
super(ctx, config)
this.selfId = config.selfId || config.username
this.platform = 'mail'
}

async start() {
this.user.name = this.config.username
await super.start()
this.imap = new IMAP(
this.config,
this.online.bind(this),
this.onClose.bind(this),
this.onMail.bind(this),
this.onError.bind(this),
)
this.smtp = new SMTP(this.config)
}

async stop() {
await super.stop()
this.imap.stop()
}

onError(error: Error) {
logger.error(error)
}

onMail(mail: ParsedMail) {
dispatchSession(this, mail)
}

onClose() {
if (!this.isActive) return
logger.info('IMAP disconnected, will reconnect in 3s...')
this.status = Universal.Status.RECONNECT
setTimeout(() => {
if (!this.isActive) return
this.imap.connect()
}, 3000)
this.internal = new SMTP(this.config)
this.ctx.plugin(IMAP)
}
}

Expand Down
Loading

0 comments on commit 0395ebc

Please sign in to comment.