import { operation, requestBodySchema, response200, response500, security, statusSchema, tags, } from '../chunks.ts'; const MESSAGE_TAGS = [ 'Alert', 'Alliance', 'Attack', 'Colonization', 'Complaint', 'Correspondence', 'Excavator', 'Intelligence', 'Medal', 'Mission', 'Parliament', 'Probe', 'Spies', 'Trade', 'Tutorial', ]; const messageSummarySchema = { type: 'object', required: [ 'id', 'subject', 'date', 'from', 'from_id', 'to', 'to_id', 'has_read', 'has_replied', 'body_preview', 'tags', ], properties: { id: { type: 'integer' }, subject: { type: 'string' }, date: { type: 'string' }, from: { type: 'string' }, from_id: { type: 'integer' }, to: { type: 'string' }, to_id: { type: 'integer' }, has_read: { type: 'integer', enum: [1, 0] }, has_replied: { type: 'integer', enum: [1, 0] }, body_preview: { type: 'string' }, tags: { type: 'array', items: { type: 'string', enum: MESSAGE_TAGS } }, }, }; const viewInboxRequestBody = requestBodySchema({ type: 'object', properties: { options: { type: 'object', description: 'Optional extra options.', properties: { page_number: { type: 'integer', description: 'Which page of messages to view. 25 per page. Defaults to 1.', }, tags: { type: 'array', items: { type: 'string', enum: MESSAGE_TAGS }, description: 'Only messages carrying at least one of these tags are returned.', }, empire: { type: 'string', description: 'The name or id of a baby empire whose inbox to view.', }, }, }, }, }); const viewInboxResponses = (description: string) => ({ ...response200(description, { type: 'object', required: ['messages', 'message_count', 'status'], properties: { messages: { type: 'array', items: messageSummarySchema }, message_count: { type: 'integer' }, status: statusSchema(), }, }), ...response500(), }); export const inbox = { '/v2/inbox/view_inbox': { post: { ...tags('inbox'), ...security(), ...operation( 'List inbox messages.', "Displays a list of the messages in the empire's inbox, 25 per page, sorted newest to oldest. Throws 1002 and 1006." ), ...viewInboxRequestBody, responses: viewInboxResponses( "Displays a list of the messages in the empire's inbox, 25 per page, newest to oldest." ), }, }, '/v2/inbox/view_archived': { post: { ...tags('inbox'), ...security(), ...operation( 'List archived messages.', 'Exactly the same as view_inbox, except it shows archived messages instead.' ), ...viewInboxRequestBody, responses: viewInboxResponses('Same as view_inbox, but shows archived messages.'), }, }, '/v2/inbox/view_trashed': { post: { ...tags('inbox'), ...security(), ...operation( 'List trashed messages.', 'Exactly the same as view_inbox, except it shows trashed messages instead.' ), ...viewInboxRequestBody, responses: viewInboxResponses('Same as view_inbox, but shows trashed messages.'), }, }, '/v2/inbox/view_sent': { post: { ...tags('inbox'), ...security(), ...operation( 'List sent messages.', 'Exactly the same as view_inbox, except it shows sent messages instead.' ), ...viewInboxRequestBody, responses: viewInboxResponses('Same as view_inbox, but shows sent messages.'), }, }, '/v2/inbox/view_unread': { post: { ...tags('inbox'), ...security(), ...operation( 'List unread messages.', 'Exactly the same as view_inbox, except it shows only the unread messages in the inbox.' ), ...viewInboxRequestBody, responses: viewInboxResponses('Same as view_inbox, but shows only unread messages.'), }, }, '/v2/inbox/read_message': { post: { ...tags('inbox'), ...security(), ...operation( 'Read a message.', 'Retrieves a message and marks it read if it was not already. Throws 1002, 1006, and 1010.' ), ...requestBodySchema({ type: 'object', required: ['message_id'], properties: { message_id: { type: 'integer', description: 'A message id returned by view_inbox or one of the other view_ methods.', }, }, }), responses: { ...response200('Retrieves a message and marks it read if it was not already.', { type: 'object', required: ['message', 'status'], properties: { message: { type: 'object', required: [ 'id', 'from', 'from_id', 'to', 'to_id', 'subject', 'body', 'date', 'has_read', 'has_replied', 'has_archived', 'has_trashed', 'in_reply_to', 'recipients', 'tags', ], properties: { id: { type: 'integer' }, from: { type: 'string' }, from_id: { type: 'integer' }, to: { type: 'string' }, to_id: { type: 'integer' }, subject: { type: 'string' }, body: { type: 'string' }, date: { type: 'string' }, has_read: { type: 'integer', enum: [1, 0] }, has_replied: { type: 'integer', enum: [1, 0] }, has_archived: { type: 'integer', enum: [1, 0] }, has_trashed: { type: 'integer', enum: [1, 0] }, in_reply_to: { type: 'integer' }, recipients: { type: 'array', items: { type: 'integer' }, description: 'The complete list of empires who received the message. `to`/`to_id` above is just the empire that owns this particular copy of the message.', }, tags: { type: 'array', items: { type: 'string', enum: MESSAGE_TAGS } }, attachments: { type: 'object', description: 'At most one of each attachment type per message.', properties: { image: { type: 'object', required: ['url', 'title'], properties: { url: { type: 'string' }, title: { type: 'string' }, link: { type: 'string' }, }, }, link: { type: 'object', required: ['url', 'label'], properties: { url: { type: 'string' }, label: { type: 'string' } }, }, table: { type: 'array', items: { type: 'array', items: { type: 'string' } } }, map: { type: 'object', required: ['surface', 'buildings'], properties: { surface: { type: 'string' }, buildings: { type: 'array', items: { type: 'object', required: ['x', 'y', 'image'], properties: { x: { type: 'integer' }, y: { type: 'integer' }, image: { type: 'string' }, }, }, }, }, }, }, }, }, }, status: statusSchema(), }, }), ...response500(), }, }, }, '/v2/inbox/archive_messages': { post: { ...tags('inbox'), ...security(), ...operation( 'Archive messages.', 'Archives a list of messages, marking them read in the process. Sent messages cannot be archived; a message that is already archived or otherwise un-archivable is returned in failure.' ), ...requestBodySchema({ type: 'object', required: ['message_ids'], properties: { message_ids: { type: 'array', items: { type: 'integer' }, description: 'The message ids to archive.', }, }, }), responses: { ...response200( 'Archives a list of messages (marked as read in the process). Sent messages cannot be archived.', { type: 'object', required: ['success', 'failure', 'status'], properties: { success: { type: 'array', items: { type: 'integer' } }, failure: { type: 'array', items: { type: 'integer' } }, status: statusSchema(), }, } ), ...response500(), }, }, }, '/v2/inbox/trash_messages': { post: { ...tags('inbox'), ...security(), ...operation( 'Trash messages.', 'Trashes a list of messages, marking them read in the process. Only messages sent to you can be trashed.' ), ...requestBodySchema({ type: 'object', required: ['message_ids'], properties: { message_ids: { type: 'array', items: { type: 'integer' }, description: 'The message ids to trash.', }, }, }), responses: { ...response200( 'Trashes a list of messages (marked as read in the process). Only messages sent to you can be trashed.', { type: 'object', required: ['success', 'status'], properties: { success: { type: 'array', items: { type: 'integer' } }, status: statusSchema(), }, } ), ...response500(), }, }, }, '/v2/inbox/trash_messages_where': { post: { ...tags('inbox'), ...security(), ...operation( 'Trash messages matching a spec.', 'Trashes every message that matches all keys of at least one spec entry, marking them read in the process. It is an error to supply an empty spec.' ), ...requestBodySchema({ type: 'object', required: ['spec'], properties: { spec: { type: 'array', description: 'A list of match specifications. A message must match every key of an entry to be trashed; entries are OR-ed together. Use a subject of "%" to match all non-archived messages.', items: { type: 'object', properties: { tags: { type: 'array', items: { type: 'string', enum: MESSAGE_TAGS }, description: 'A message carrying any of these tags is eligible. Defaults to all tags.', }, subject: { oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], description: 'A subject to match. Use % as a wildcard, e.g. "Pass:%". An array is treated as a set of exact subjects, OR-ed together. Defaults to any subject.', }, from: { type: 'array', items: { type: 'string' }, description: 'Full empire names. A message from any of these is eligible.', }, }, }, }, save_ids: { type: 'boolean', description: 'When true, the trashed message ids are gathered and returned in `deleted`. Off by default, since gathering them adds server work and response size; `deleted_count` is returned either way.', }, }, }), responses: { ...response200( 'Trashes all messages matching every key of at least one spec entry (marked as read in the process).', { type: 'object', required: ['deleted_count', 'status'], properties: { deleted: { type: 'array', items: { type: 'integer' }, description: 'Only present when save_ids is true.', }, deleted_count: { type: 'integer' }, status: statusSchema(), }, } ), ...response500(), }, }, }, '/v2/inbox/send_message': { post: { ...tags('inbox'), ...security(), ...operation( 'Send a message to other players.', 'Sends a message to other players. Throws 1002, 1005, and 1006.' ), ...requestBodySchema({ type: 'object', required: ['recipients', 'subject', 'body'], properties: { recipients: { type: 'string', description: 'Comma separated empire names. "@ally" is a shortcut for all members of your alliance.', }, subject: { type: 'string', maxLength: 100, description: 'A subject for the message. Fewer than 100 characters and cannot contain &, @, ;, <, or >.', }, body: { type: 'string', maxLength: 200000, description: 'The body of the message. Fewer than 200,000 characters and cannot contain < or >.', }, options: { type: 'object', description: 'Optional extra options.', properties: { in_reply_to: { type: 'integer', description: 'The id of the message this one is in reply to, if any.', }, forward: { type: 'integer', description: 'A message id whose attachments should be sent along with this message. The original text is not forwarded; include it in the body yourself if you want it.', }, }, }, }, }), responses: { ...response200('Sends a message to other players.', { type: 'object', required: ['status'], properties: { status: statusSchema() }, }), ...response500(), }, }, }, };