Skip to content

Commit

Permalink
✨ Manage communication templates for moderation purposes (#2045)
Browse files Browse the repository at this point in the history
* ✨ Add initial lexicons to manage communication templates

* ✨ All 3 endpoints are functional

* ✨ Add list and delete endpoints

* ✅ Add tests for communication template CRUD

* 🔒 Allow only admins to create and update templates

* 🧹 Cleanup according to PR review

* ✨ Make updatedBy and createdBy optional in lexicon

* ✨ Typo

* ✨ Allow string id and update lexicon language

* ✅ Fix tests

* ✨ content -> contentMarkdown

* ✨ Change column name in db table

* add changeset

---------

Co-authored-by: Devin Ivy <[email protected]>
  • Loading branch information
foysalit and devinivy authored Jan 19, 2024
1 parent 8932a44 commit 15f3856
Show file tree
Hide file tree
Showing 52 changed files with 2,581 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/old-meals-approve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@atproto/api': patch
---

support new lexicons for admin communication templates
43 changes: 43 additions & 0 deletions lexicons/com/atproto/admin/createCommunicationTemplate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"lexicon": 1,
"id": "com.atproto.admin.createCommunicationTemplate",
"defs": {
"main": {
"type": "procedure",
"description": "Administrative action to create a new, re-usable communication (email for now) template.",
"input": {
"encoding": "application/json",
"schema": {
"type": "object",
"required": ["subject", "contentMarkdown", "name"],
"properties": {
"name": {
"type": "string",
"description": "Name of the template."
},
"contentMarkdown": {
"type": "string",
"description": "Content of the template, markdown supported, can contain variable placeholders."
},
"subject": {
"type": "string",
"description": "Subject of the message, used in emails."
},
"createdBy": {
"type": "string",
"format": "did",
"description": "DID of the user who is creating the template."
}
}
}
},
"output": {
"encoding": "application/json",
"schema": {
"type": "ref",
"ref": "com.atproto.admin.defs#communicationTemplateView"
}
}
}
}
}
32 changes: 32 additions & 0 deletions lexicons/com/atproto/admin/defs.json
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,38 @@
"description": "Additional comment about the outgoing comm."
}
}
},
"communicationTemplateView": {
"type": "object",
"required": [
"id",
"name",
"contentMarkdown",
"disabled",
"lastUpdatedBy",
"createdAt",
"updatedAt"
],
"properties": {
"id": { "type": "string" },
"name": { "type": "string", "description": "Name of the template." },
"subject": {
"type": "string",
"description": "Content of the template, can contain markdown and variable placeholders."
},
"contentMarkdown": {
"type": "string",
"description": "Subject of the message, used in emails."
},
"disabled": { "type": "boolean" },
"lastUpdatedBy": {
"type": "string",
"format": "did",
"description": "DID of the user who last updated the template."
},
"createdAt": { "type": "string", "format": "datetime" },
"updatedAt": { "type": "string", "format": "datetime" }
}
}
}
}
20 changes: 20 additions & 0 deletions lexicons/com/atproto/admin/deleteCommunicationTemplate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"lexicon": 1,
"id": "com.atproto.admin.deleteCommunicationTemplate",
"defs": {
"main": {
"type": "procedure",
"description": "Delete a communication template.",
"input": {
"encoding": "application/json",
"schema": {
"type": "object",
"required": ["id"],
"properties": {
"id": { "type": "string" }
}
}
}
}
}
}
26 changes: 26 additions & 0 deletions lexicons/com/atproto/admin/listCommunicationTemplates.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"lexicon": 1,
"id": "com.atproto.admin.listCommunicationTemplates",
"defs": {
"main": {
"type": "query",
"description": "Get list of all communication templates.",
"output": {
"encoding": "application/json",
"schema": {
"type": "object",
"required": ["communicationTemplates"],
"properties": {
"communicationTemplates": {
"type": "array",
"items": {
"type": "ref",
"ref": "com.atproto.admin.defs#communicationTemplateView"
}
}
}
}
}
}
}
}
50 changes: 50 additions & 0 deletions lexicons/com/atproto/admin/updateCommunicationTemplate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"lexicon": 1,
"id": "com.atproto.admin.updateCommunicationTemplate",
"defs": {
"main": {
"type": "procedure",
"description": "Administrative action to update an existing communication template. Allows passing partial fields to patch specific fields only.",
"input": {
"encoding": "application/json",
"schema": {
"type": "object",
"required": ["id"],
"properties": {
"id": {
"type": "string",
"description": "ID of the template to be updated."
},
"name": {
"type": "string",
"description": "Name of the template."
},
"contentMarkdown": {
"type": "string",
"description": "Content of the template, markdown supported, can contain variable placeholders."
},
"subject": {
"type": "string",
"description": "Subject of the message, used in emails."
},
"updatedBy": {
"type": "string",
"format": "did",
"description": "DID of the user who is updating the template."
},
"disabled": {
"type": "boolean"
}
}
}
},
"output": {
"encoding": "application/json",
"schema": {
"type": "ref",
"ref": "com.atproto.admin.defs#communicationTemplateView"
}
}
}
}
}
72 changes: 72 additions & 0 deletions packages/api/src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import {
} from '@atproto/xrpc'
import { schemas } from './lexicons'
import { CID } from 'multiformats/cid'
import * as ComAtprotoAdminCreateCommunicationTemplate from './types/com/atproto/admin/createCommunicationTemplate'
import * as ComAtprotoAdminDefs from './types/com/atproto/admin/defs'
import * as ComAtprotoAdminDeleteAccount from './types/com/atproto/admin/deleteAccount'
import * as ComAtprotoAdminDeleteCommunicationTemplate from './types/com/atproto/admin/deleteCommunicationTemplate'
import * as ComAtprotoAdminDisableAccountInvites from './types/com/atproto/admin/disableAccountInvites'
import * as ComAtprotoAdminDisableInviteCodes from './types/com/atproto/admin/disableInviteCodes'
import * as ComAtprotoAdminEmitModerationEvent from './types/com/atproto/admin/emitModerationEvent'
Expand All @@ -20,12 +22,14 @@ import * as ComAtprotoAdminGetModerationEvent from './types/com/atproto/admin/ge
import * as ComAtprotoAdminGetRecord from './types/com/atproto/admin/getRecord'
import * as ComAtprotoAdminGetRepo from './types/com/atproto/admin/getRepo'
import * as ComAtprotoAdminGetSubjectStatus from './types/com/atproto/admin/getSubjectStatus'
import * as ComAtprotoAdminListCommunicationTemplates from './types/com/atproto/admin/listCommunicationTemplates'
import * as ComAtprotoAdminQueryModerationEvents from './types/com/atproto/admin/queryModerationEvents'
import * as ComAtprotoAdminQueryModerationStatuses from './types/com/atproto/admin/queryModerationStatuses'
import * as ComAtprotoAdminSearchRepos from './types/com/atproto/admin/searchRepos'
import * as ComAtprotoAdminSendEmail from './types/com/atproto/admin/sendEmail'
import * as ComAtprotoAdminUpdateAccountEmail from './types/com/atproto/admin/updateAccountEmail'
import * as ComAtprotoAdminUpdateAccountHandle from './types/com/atproto/admin/updateAccountHandle'
import * as ComAtprotoAdminUpdateCommunicationTemplate from './types/com/atproto/admin/updateCommunicationTemplate'
import * as ComAtprotoAdminUpdateSubjectStatus from './types/com/atproto/admin/updateSubjectStatus'
import * as ComAtprotoIdentityResolveHandle from './types/com/atproto/identity/resolveHandle'
import * as ComAtprotoIdentityUpdateHandle from './types/com/atproto/identity/updateHandle'
Expand Down Expand Up @@ -147,8 +151,10 @@ import * as AppBskyUnspeccedGetTimelineSkeleton from './types/app/bsky/unspecced
import * as AppBskyUnspeccedSearchActorsSkeleton from './types/app/bsky/unspecced/searchActorsSkeleton'
import * as AppBskyUnspeccedSearchPostsSkeleton from './types/app/bsky/unspecced/searchPostsSkeleton'

export * as ComAtprotoAdminCreateCommunicationTemplate from './types/com/atproto/admin/createCommunicationTemplate'
export * as ComAtprotoAdminDefs from './types/com/atproto/admin/defs'
export * as ComAtprotoAdminDeleteAccount from './types/com/atproto/admin/deleteAccount'
export * as ComAtprotoAdminDeleteCommunicationTemplate from './types/com/atproto/admin/deleteCommunicationTemplate'
export * as ComAtprotoAdminDisableAccountInvites from './types/com/atproto/admin/disableAccountInvites'
export * as ComAtprotoAdminDisableInviteCodes from './types/com/atproto/admin/disableInviteCodes'
export * as ComAtprotoAdminEmitModerationEvent from './types/com/atproto/admin/emitModerationEvent'
Expand All @@ -160,12 +166,14 @@ export * as ComAtprotoAdminGetModerationEvent from './types/com/atproto/admin/ge
export * as ComAtprotoAdminGetRecord from './types/com/atproto/admin/getRecord'
export * as ComAtprotoAdminGetRepo from './types/com/atproto/admin/getRepo'
export * as ComAtprotoAdminGetSubjectStatus from './types/com/atproto/admin/getSubjectStatus'
export * as ComAtprotoAdminListCommunicationTemplates from './types/com/atproto/admin/listCommunicationTemplates'
export * as ComAtprotoAdminQueryModerationEvents from './types/com/atproto/admin/queryModerationEvents'
export * as ComAtprotoAdminQueryModerationStatuses from './types/com/atproto/admin/queryModerationStatuses'
export * as ComAtprotoAdminSearchRepos from './types/com/atproto/admin/searchRepos'
export * as ComAtprotoAdminSendEmail from './types/com/atproto/admin/sendEmail'
export * as ComAtprotoAdminUpdateAccountEmail from './types/com/atproto/admin/updateAccountEmail'
export * as ComAtprotoAdminUpdateAccountHandle from './types/com/atproto/admin/updateAccountHandle'
export * as ComAtprotoAdminUpdateCommunicationTemplate from './types/com/atproto/admin/updateCommunicationTemplate'
export * as ComAtprotoAdminUpdateSubjectStatus from './types/com/atproto/admin/updateSubjectStatus'
export * as ComAtprotoIdentityResolveHandle from './types/com/atproto/identity/resolveHandle'
export * as ComAtprotoIdentityUpdateHandle from './types/com/atproto/identity/updateHandle'
Expand Down Expand Up @@ -377,6 +385,22 @@ export class ComAtprotoAdminNS {
this._service = service
}

createCommunicationTemplate(
data?: ComAtprotoAdminCreateCommunicationTemplate.InputSchema,
opts?: ComAtprotoAdminCreateCommunicationTemplate.CallOptions,
): Promise<ComAtprotoAdminCreateCommunicationTemplate.Response> {
return this._service.xrpc
.call(
'com.atproto.admin.createCommunicationTemplate',
opts?.qp,
data,
opts,
)
.catch((e) => {
throw ComAtprotoAdminCreateCommunicationTemplate.toKnownErr(e)
})
}

deleteAccount(
data?: ComAtprotoAdminDeleteAccount.InputSchema,
opts?: ComAtprotoAdminDeleteAccount.CallOptions,
Expand All @@ -388,6 +412,22 @@ export class ComAtprotoAdminNS {
})
}

deleteCommunicationTemplate(
data?: ComAtprotoAdminDeleteCommunicationTemplate.InputSchema,
opts?: ComAtprotoAdminDeleteCommunicationTemplate.CallOptions,
): Promise<ComAtprotoAdminDeleteCommunicationTemplate.Response> {
return this._service.xrpc
.call(
'com.atproto.admin.deleteCommunicationTemplate',
opts?.qp,
data,
opts,
)
.catch((e) => {
throw ComAtprotoAdminDeleteCommunicationTemplate.toKnownErr(e)
})
}

disableAccountInvites(
data?: ComAtprotoAdminDisableAccountInvites.InputSchema,
opts?: ComAtprotoAdminDisableAccountInvites.CallOptions,
Expand Down Expand Up @@ -509,6 +549,22 @@ export class ComAtprotoAdminNS {
})
}

listCommunicationTemplates(
params?: ComAtprotoAdminListCommunicationTemplates.QueryParams,
opts?: ComAtprotoAdminListCommunicationTemplates.CallOptions,
): Promise<ComAtprotoAdminListCommunicationTemplates.Response> {
return this._service.xrpc
.call(
'com.atproto.admin.listCommunicationTemplates',
params,
undefined,
opts,
)
.catch((e) => {
throw ComAtprotoAdminListCommunicationTemplates.toKnownErr(e)
})
}

queryModerationEvents(
params?: ComAtprotoAdminQueryModerationEvents.QueryParams,
opts?: ComAtprotoAdminQueryModerationEvents.CallOptions,
Expand Down Expand Up @@ -580,6 +636,22 @@ export class ComAtprotoAdminNS {
})
}

updateCommunicationTemplate(
data?: ComAtprotoAdminUpdateCommunicationTemplate.InputSchema,
opts?: ComAtprotoAdminUpdateCommunicationTemplate.CallOptions,
): Promise<ComAtprotoAdminUpdateCommunicationTemplate.Response> {
return this._service.xrpc
.call(
'com.atproto.admin.updateCommunicationTemplate',
opts?.qp,
data,
opts,
)
.catch((e) => {
throw ComAtprotoAdminUpdateCommunicationTemplate.toKnownErr(e)
})
}

updateSubjectStatus(
data?: ComAtprotoAdminUpdateSubjectStatus.InputSchema,
opts?: ComAtprotoAdminUpdateSubjectStatus.CallOptions,
Expand Down
Loading

0 comments on commit 15f3856

Please sign in to comment.