2019-10-04 03:35:06 -07:00
import {
IHookFunctions ,
IWebhookFunctions ,
} from 'n8n-core' ;
import {
2020-09-04 01:28:04 -07:00
IDataObject ,
2019-10-04 03:35:06 -07:00
INodeType ,
2020-09-04 01:28:04 -07:00
INodeTypeDescription ,
2019-10-11 04:02:44 -07:00
IWebhookResponseData ,
2019-10-04 03:35:06 -07:00
} from 'n8n-workflow' ;
import {
apiRequest ,
2020-09-04 01:28:04 -07:00
getImageBySize ,
2019-10-04 03:35:06 -07:00
} from './GenericFunctions' ;
2020-09-04 01:28:04 -07:00
import {
IEvent ,
} from './IEvent' ;
2019-10-04 03:35:06 -07:00
export class TelegramTrigger implements INodeType {
description : INodeTypeDescription = {
displayName : 'Telegram Trigger' ,
name : 'telegramTrigger' ,
2021-02-04 00:50:39 -08:00
icon : 'file:telegram.svg' ,
2019-10-04 03:35:06 -07:00
group : [ 'trigger' ] ,
version : 1 ,
subtitle : '=Updates: {{$parameter["updates"].join(", ")}}' ,
2021-07-03 05:40:16 -07:00
description : 'Starts the workflow on a Telegram update' ,
2019-10-04 03:35:06 -07:00
defaults : {
name : 'Telegram Trigger' ,
} ,
inputs : [ ] ,
outputs : [ 'main' ] ,
credentials : [
{
name : 'telegramApi' ,
required : true ,
2020-09-04 01:28:04 -07:00
} ,
2019-10-04 03:35:06 -07:00
] ,
webhooks : [
{
name : 'default' ,
httpMethod : 'POST' ,
responseMode : 'onReceived' ,
path : 'webhook' ,
} ,
] ,
properties : [
{
displayName : 'Updates' ,
name : 'updates' ,
type : 'multiOptions' ,
options : [
{
name : '*' ,
value : '*' ,
description : 'All updates.' ,
} ,
{
name : 'message' ,
value : 'message' ,
description : 'Trigger on new incoming message of any kind — text, photo, sticker, etc..' ,
} ,
{
name : 'edited_message' ,
value : 'edited_message' ,
description : 'Trigger on new version of a channel post that is known to the bot and was edited.' ,
} ,
{
name : 'channel_post' ,
value : 'channel_post' ,
description : 'Trigger on new incoming channel post of any kind — text, photo, sticker, etc..' ,
} ,
{
name : 'edited_channel_post' ,
value : 'edited_channel_post' ,
description : 'Trigger on new version of a channel post that is known to the bot and was edited.' ,
} ,
{
name : 'inline_query' ,
value : 'inline_query' ,
description : 'Trigger on new incoming inline query.' ,
} ,
{
name : 'callback_query' ,
value : 'callback_query' ,
description : 'Trigger on new incoming callback query.' ,
} ,
{
name : 'shipping_query' ,
value : 'shipping_query' ,
description : 'Trigger on new incoming shipping query. Only for invoices with flexible price.' ,
} ,
{
name : 'pre_checkout_query' ,
value : 'pre_checkout_query' ,
description : 'Trigger on new incoming pre-checkout query. Contains full information about checkout.' ,
} ,
{
name : 'poll' ,
value : 'poll' ,
description : 'Trigger on new poll state. Bots receive only updates about stopped polls and polls, which are sent by the bot.' ,
} ,
] ,
required : true ,
2019-10-04 13:16:26 -07:00
default : [ ] ,
2019-10-04 03:35:06 -07:00
description : 'The update types to listen to.' ,
} ,
2020-09-04 01:28:04 -07:00
{
displayName : 'Additional Fields' ,
name : 'additionalFields' ,
type : 'collection' ,
placeholder : 'Add Field' ,
default : { } ,
options : [
{
displayName : 'Download Images/Files' ,
2020-09-04 01:30:22 -07:00
name : 'download' ,
2020-09-04 01:28:04 -07:00
type : 'boolean' ,
default : false ,
2022-02-18 07:09:44 -08:00
description : ` Telegram delivers the image in multiple sizes. By default, just the large image would be downloaded. If you want to change the size, set the field 'Image Size'. ` ,
2020-09-04 01:28:04 -07:00
} ,
{
displayName : 'Image Size' ,
name : 'imageSize' ,
type : 'options' ,
2020-09-08 00:48:07 -07:00
displayOptions : {
show : {
download : [
true ,
] ,
} ,
} ,
2020-09-04 01:28:04 -07:00
options : [
{
name : 'Small' ,
value : 'small' ,
} ,
{
name : 'Medium' ,
value : 'medium' ,
} ,
{
name : 'Large' ,
value : 'large' ,
} ,
2022-02-18 07:09:44 -08:00
{
name : 'Extra Large' ,
value : 'extraLarge' ,
} ,
2020-09-04 01:28:04 -07:00
] ,
default : 'large' ,
description : 'The size of the image to be downloaded' ,
} ,
] ,
} ,
2019-10-04 03:35:06 -07:00
] ,
} ;
// @ts-ignore (because of request)
webhookMethods = {
default : {
2019-10-04 06:17:24 -07:00
async checkExists ( this : IHookFunctions ) : Promise < boolean > {
2020-09-02 01:53:38 -07:00
const endpoint = 'getWebhookInfo' ;
const webhookReturnData = await apiRequest . call ( this , 'POST' , endpoint , { } ) ;
2020-09-02 05:36:30 -07:00
const webhookUrl = this . getNodeWebhookUrl ( 'default' ) ;
2020-09-02 01:53:38 -07:00
2020-09-02 05:36:30 -07:00
if ( webhookReturnData . result . url === webhookUrl ) {
return true ;
2020-09-02 01:53:38 -07:00
}
2020-09-02 05:36:30 -07:00
return false ;
2019-10-04 06:17:24 -07:00
} ,
2019-10-04 03:35:06 -07:00
async create ( this : IHookFunctions ) : Promise < boolean > {
const webhookUrl = this . getNodeWebhookUrl ( 'default' ) ;
let allowedUpdates = this . getNodeParameter ( 'updates' ) as string [ ] ;
if ( allowedUpdates . includes ( '*' ) ) {
allowedUpdates = [ ] ;
}
const endpoint = 'setWebhook' ;
const body = {
url : webhookUrl ,
allowed_updates : allowedUpdates ,
} ;
await apiRequest . call ( this , 'POST' , endpoint , body ) ;
return true ;
} ,
async delete ( this : IHookFunctions ) : Promise < boolean > {
const endpoint = 'deleteWebhook' ;
const body = { } ;
try {
await apiRequest . call ( this , 'POST' , endpoint , body ) ;
2021-04-16 09:33:36 -07:00
} catch ( error ) {
2019-10-04 03:35:06 -07:00
return false ;
}
return true ;
} ,
} ,
} ;
2020-09-04 01:28:04 -07:00
async webhook ( this : IWebhookFunctions ) : Promise < IWebhookResponseData > {
2019-10-04 03:35:06 -07:00
2021-08-20 09:57:30 -07:00
const credentials = await this . getCredentials ( 'telegramApi' ) as IDataObject ;
2019-10-04 03:35:06 -07:00
2020-09-04 01:28:04 -07:00
const bodyData = this . getBodyData ( ) as IEvent ;
const additionalFields = this . getNodeParameter ( 'additionalFields' ) as IDataObject ;
2020-09-04 01:30:22 -07:00
if ( additionalFields . download === true ) {
2020-09-04 01:28:04 -07:00
let imageSize = 'large' ;
2021-12-02 23:53:20 -08:00
let key : 'message' | 'channel_post' = 'message' ;
if ( bodyData . channel_post ) {
key = 'channel_post' ;
}
if ( ( bodyData [ key ] && bodyData [ key ] ? . photo && Array . isArray ( bodyData [ key ] ? . photo ) || bodyData [ key ] ? . document ) ) {
2020-09-04 01:28:04 -07:00
if ( additionalFields . imageSize ) {
imageSize = additionalFields . imageSize as string ;
}
let fileId ;
2021-12-02 23:53:20 -08:00
if ( bodyData [ key ] ? . photo ) {
2020-09-04 01:28:04 -07:00
2021-12-02 23:53:20 -08:00
let image = getImageBySize ( bodyData [ key ] ? . photo as IDataObject [ ] , imageSize ) as IDataObject ;
2020-09-04 01:28:04 -07:00
// When the image is sent from the desktop app telegram does not resize the image
// So return the only image avaiable
// Basically the Image Size parameter would work just when the images comes from the mobile app
if ( image === undefined ) {
2021-12-02 23:53:20 -08:00
image = bodyData [ key ] ! . photo ! [ 0 ] ;
2020-09-04 01:28:04 -07:00
}
fileId = image . file_id ;
} else {
2021-12-02 23:53:20 -08:00
fileId = bodyData [ key ] ? . document ? . file_id ;
2020-09-04 01:28:04 -07:00
}
const { result : { file_path } } = await apiRequest . call ( this , 'GET' , ` getFile?file_id= ${ fileId } ` , { } ) ;
const file = await apiRequest . call ( this , 'GET' , '' , { } , { } , { json : false , encoding : null , uri : ` https://api.telegram.org/file/bot ${ credentials . accessToken } / ${ file_path } ` , resolveWithFullResponse : true } ) ;
const data = Buffer . from ( file . body as string ) ;
const fileName = file_path . split ( '/' ) . pop ( ) ;
const binaryData = await this . helpers . prepareBinaryData ( data as unknown as Buffer , fileName ) ;
return {
workflowData : [
[
{
json : bodyData as unknown as IDataObject ,
binary : {
data : binaryData ,
} ,
2020-10-22 06:46:03 -07:00
} ,
] ,
2020-09-04 01:28:04 -07:00
] ,
} ;
}
}
2019-10-04 03:35:06 -07:00
return {
workflowData : [
2020-10-22 06:46:03 -07:00
this . helpers . returnJsonArray ( [ bodyData as unknown as IDataObject ] ) ,
2019-10-04 03:35:06 -07:00
] ,
} ;
}
}