job-feed

招聘推送(Job Feed)

招聘推送负责把一条已发布的职位,变成 Discord 频道里的一张格式化卡片。它位于 youteacher_discord 服务内部,由一个小型应用服务(JobFeedService)加一对 HTTP 路由组成。

职位如何进来

职位通过一个 ingest 端点进入:POST /discord/v1/job-feed/ingest。上游的 job 服务在职位发布时,应带着服务凭据调用它。请求体会逐字段校验——jobIdtitlecitycountry、一个合法的 url,以及可选的 salaryMin / salaryMax / currency / salaryPeriod / jobType / description / benefits——校验通过后才进入后续处理。

职位去往哪里

一个 Discord 频道通过一条配置记录来订阅推送:一个 channelId,加上可选的 countriescities 过滤。职位进来时,服务会遍历每一个已配置的频道,逐个频道判断这条职位是否该出现在该频道。

匹配规则是「默认全放行」:国家或城市列表为空表示「不限制」,因此没有过滤条件的频道会收到全部职位。列表非空则收窄为精确匹配——职位的 country 必须在该频道的国家列表里、city 在城市列表里,职位才能通过。

不重复推送同一条职位

去重的键同时按「职位」和「频道」——键是 jobId:channelId。同一条职位仍可到达两个不同频道,但同一个频道永不会收到同一条职位两次。已推送集合只在成功推送后才标记,因此一次发送失败不会白白吃掉这条职位;发布失败是记录日志、而非抛出,因此一个坏频道不会拖垮其它频道。

Discord 卡片

每条职位渲染成一个 Discord embed。标题链接到完整职位页。地点(城市, 国家)和格式化后的薪资构成开头一行,其后是职位描述的截断片段。结构化字段承载相同信息——地点、薪资、工作类型、福利——每一项都只在有值时才出现。薪资格式化会把最小/最大值合成一个区间(或单值加 +),附上货币,并把发薪周期映射为 /month/year/hour。工作类型被规范为展示形式(Full-time、Part-time、Contract、Internship)。所有自由文本都会折叠空白并做长度上限截断,使卡片保持在 Discord 的限制之内。

Owner 控制与默认值

频道配置通过 PUT /discord/v1/job-feed/config 写入,并加了守卫:只有 admin 用户能改动它。在此之上,可以在启动时从环境设置里自动注册一个默认频道:若环境中存在默认频道 id,服务会在进程启动时以「无过滤」注册它,使推送开箱即用,无需手动调用配置接口。

当前形态

按服务自身注释,配置与去重集合都保存在内存中,是一种 MVP 取舍——持久化(落数据库)是注释里点明的下一步。因此一次重启会同时清空频道配置(除环境播种的默认频道外)和「已推送过什么」的记录。

about this entry

One of sijie's wiki entries. The AI on this site is grounded in the same corpus and answers in sijie's voice, with citations back to entries like this one — answering costs sijie money, so it waits behind a code: enter an access code →