RocketChat / RocketChat/Rocket.Chat
Error sending message error-not-allowed when call public api
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 46.1k
- Forks
- 13.9k
- Avg merge
- 3d 3h
- Merged PRs (30d)
- 130
Description
I wrote an app to send messages with the block and action below:
import { IHttp, IModify, IPersistence, IRead } from '@rocket.chat/apps-engine/definition/accessors';
import { ApiEndpoint, IApiEndpointInfo, IApiRequest, IApiResponse } from '@rocket.chat/apps-engine/definition/api';
import { IButtonElement } from '@rocket.chat/apps-engine/definition/uikit';
import { IUser } from '@rocket.chat/apps-engine/definition/users';
import { IRoom, RoomType } from '@rocket.chat/apps-engine/definition/rooms';
export class MyEndpoint extends ApiEndpoint {
public path = 'notifyMessage';
public async post(
request: IApiRequest,
endpoint: IApiEndpointInfo,
read: IRead,
modify: IModify,
http: IHttp,
persis: IPersistence,
): Promise<IApiResponse> {
console.log("MyEndpoint 1 --------------------------------------------------")
const data = request.content;
await this.createNotification(data, read, modify);
console.log("\tMyEndpoint 3")
return this.success();
}
private async createNotification(data: any, read: IRead, modify: IModify) {
console.log("\tMyEndpoint 2")
const botUserId: string = data.botId ? `${data.botId}` : '';
let botUser: IUser;
if (botUserId.length > 0)
botUser = await read.getUserReader().getByUsername(botUserId);
else
botUser = await read.getUserReader().getByUsername('rocket.cat');
const username = data.actions[0].queueBack.data.kvs.username;
let channel: IRoom | undefined = await read.getRoomReader().getDirectByUsernames([username]);
console.log("\tMyEndpoint 2.1")
if (!channel) {
const builder = modify.getCreator().startRoom()
.setCreator(botUser)
.setType(RoomType.DIRECT_MESSAGE)
.setDisplayName('WANDA')
.setMembersToBeAddedByUsernames([username]);
const roomId = await modify.getCreator().finish(builder);
channel = await read.getRoomReader().getById(roomId);
}
if (!botUser || !channel) {
console.error('Error MyEndpoint: bot user or channel not found');
return;
}
console.log("\tMyEndpoint 2.2")
const builder = await modify.getCreator().startMessage()
.setSender(botUser)
.setRoom(channel);
const text = `${data.markdownMessage}`;
const block = await modify.getCreator().getBlockBuilder();
block.addSectionBlock({
text: block.newMarkdownTextObject(text),
});
const buttonElements: Array<IButtonElement> = [];
for (const button of data.actions) {
buttonElements.push(
block.newButtonElement({
text: block.newPlainTextObject(button.label),
actionId: button.actionId,
value: button.urlCallback
})
);
}
block.addActionsBlock({
elements: buttonElements
});
builder.setBlocks(block);
console.log("\tMyEndpoint 2.3")
const messageId = await modify.getCreator().finish(builder);
console.log("message ID " + JSON.stringify(messageId));
for (const action of data.actions) {
console.log("\t" + action.actionId + '> Incoming queueBack:' + JSON.stringify(action.queueBack));
await addCustomFieldToMessage(modify, messageId, 'queueBack',
action.queueBack, botUser, action.actionId); // you might loop through actions if multiple queueBack data exist
console.log("\t" + action.actionId + '> Incoming feedbackInputs:' + action.feedbackInputs);
await addCustomFieldToMessage(modify, messageId, 'feedbackInputs',
action.feedbackInputs, botUser, action.actionId); // you might loop through actions if multiple queueBack data exist
}
console.log("\tMyEndpoint 2.4")
await addCustomFieldToMessage(modify, messageId, 'originalActions',
data.actions, botUser); // you might loop through actions if multiple queueBack data exist
console.log("MyEndpoint End --------------------------------------------------")
}
}
async function addCustomFieldToMessage(
modify: IModify, messageId: string | undefined,
fieldName: string, fieldValue: any,
user: IUser, actionId?: string
): Promise<void> {
if (!messageId) {
console.error('MessageId not provided');
return;
}
if (!fieldValue) {
console.error(`${fieldName} data not provided`);
return;
}
console.log("addCustomFieldToMessage 1")
const messageExtender = await modify.getExtender().extendMessage(messageId, user);
console.log("addCustomFieldToMessage 2")
const fullFieldName = actionId ? `${fieldName}-${actionId}` : fieldName;
messageExtender.addCustomField(fullFieldName, fieldValue);
console.log("addCustomFieldToMessage 3")
await modify.getExtender().finish(messageExtender);
}
when i call api public with request.body:
{
"botId": "rocket.cat",
"source": "cosic",
"markdownMessage": "Xin chào @hoanvx",
"actions": [
{
"actionId": "ok_button",
"label": "Chấp thuận",
"queueBack": {
"type": "com.hivetech.hiro.notification.model.CosicData",
"data": {
"kvs": {
"action": "APPROVE",
"id": "null",
"username": "hoanvx"
}
}
},
"feedbackInputs": [
{
"type": "com.hivetech.hiro.notification.model.CosicData",
"comment": {
"label": "Comment",
"required": false,
"type": "input"
}
}
]
}
]
}
Error:
MyEndpoint 1 --------------------------------------------------
MyEndpoint 2
MyEndpoint 2.1
MyEndpoint 2.2
MyEndpoint 2.3
{"level":50,"time":"2023-11-14T07:30:40.876Z","pid":1,"hostname":"1c122cd24d2c","name":"System","msg":"Error sending message:","err":{"type":"Error","message":"error-not-allowed","stack":"Error: error-not-allowed\n at app/authorization/server/functions/canSendMessage.ts:26:9\n at /app/bundle/programs/server/npm/node_modules/meteor/promise/node_modules/meteor-promise/fiber_pool.js:43:40\n => awaited here:\n at Function.Promise.await (/app/bundle/programs/server/npm/node_modules/meteor/promise/node_modules/meteor-promise/promise_server.js:56:12)\n at app/authorization/server/functions/canSendMessage.ts:58:2\n at /app/bundle/programs/server/npm/node_modules/meteor/promise/node_modules/meteor-promise/fiber_pool.js:43:40\n => awaited here:\n at Function.Promise.await (/app/bundle/programs/server/npm/node_modules/meteor/promise/node_modules/meteor-promise/promise_server.js:56:12)\n at app/lib/server/methods/sendMessage.ts:82:13\n at /app/bundle/programs/server/npm/node_modules/meteor/promise/node_modules/meteor-promise/fiber_pool.js:43:40"}}
how to fix it
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading app/authorization/server/functions/canSendMessage.ts at line 26 and app/lib/server/methods/sendMessage.ts at line 82, then compare the public API request with the bot user used by the Apps Engine code. Reproduce the request and trace the authorization failure; done means the intended message can be sent without error-not-allowed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, authorization
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100