B4A=true Group=Default Group ModulesStructureVersion=1 Type=Service Version=11 @EndOfDesignText@ #Region Service Attributes #StartAtBoot: False #End Region Sub Process_Globals 'These global variables will be declared once when the application starts. 'These variables can be accessed from all modules. Dim rp As ReplyAuto Dim status As String = "Servicio Activo" Dim notisMap2 As Map Dim nsStatus, starterStatus As Map Dim mapReglas As Map = CreateMap() ' Type reglasUsuario(numero As String, histRegas As List) Type notificacionesGuardadasType(numero As String, notif As StatusBarNotification) Dim notificacionesGuardadas As Map Dim notificacionesPorContestar As List Dim histReglas As Map Dim reqManager As DBRequestManager Dim cmd As DBCommand Dim numRemitente As String = "" Dim cont As Int = 0 Dim espera As Int = 100 Dim procesandoNotificaciones As Boolean = False Dim notisIds As Map Dim DBRChecked As Boolean Dim pruebaPaso As Int = 0 End Sub Sub Service_Create If status = "Servicio Activo" Then rp.Initialize("Bow2") ' notisMap2.Initialize ' If starter.Logger Then LogColor("notiService Created", Colors.Magenta) If Not(nsStatus.IsInitialized) Then nsStatus.Initialize nsStatus.put(Subs.fechaKMT(DateTime.now),"inicia") mapReglas = Subs.traeReglas notificacionesGuardadas.Initialize notificacionesPorContestar.Initialize histReglas.Initialize reqManager.Initialize(Me, Starter.DBRServer) Service.StartForeground(747, CreateNotification("Servicio Activo")) notisIds.Initialize End If End Sub Sub Service_Start (StartingIntent As Intent) If status = "Servicio Activo" Then ' If starter.Logger Then LogColor("notiService Start - " & cont, Colors.Magenta) If cont > 25 Then 'Regeneramos la notificación permanente despues de 25 notificaciones varias. Service.StartForeground(747, CreateNotification(status)) cont = 0 End If cont = cont + 1 If Not(notisMap2.IsInitialized) Then notisMap2.Initialize If notisMap2.Size = 0 And Starter.notisMap2.IsInitialized Then ' If starter.Logger Then Log($"nsNotisMap2.size=${notisMap2.Size}, Starter.notisMap2=${Starter.notisMap2.size}"$) notisMap2.Initialize notisMap2 = Starter.notisMap2 ' If starter.Logger Then LogColor("Copie notisMap2 desde Starter.notisMap2, tamaño=" & notisMap2.Size, Colors.Green) End If If Not(nsStatus.IsInitialized) Then nsStatus.Initialize If Starter.nsStatus.IsInitialized Then nsStatus = Starter.nsStatus If Starter.starterStatus.IsInitialized Then starterStatus.Initialize starterStatus = Starter.starterStatus Else If Not(Starter.starterStatus.IsInitialized) And starterStatus.IsInitialized Then Starter.starterStatus.Initialize Starter.starterStatus = nsStatus Else starterStatus.Initialize Starter.starterStatus.Initialize starterStatus.Put(Subs.fechaKMT(DateTime.now),"inicia") Starter.starterStatus.Put(Subs.fechaKMT(DateTime.now),"inicia") End If ' If starter.Logger Then Log($"starterStatus=${Starter.starterStatus}, nsStatus=${nsStatus}"$) If rp.HandleIntent(StartingIntent) Then Return cmd.Initialize cmd.Name = "select_soporte" 'Intentamos conectarnos al servido publico y si no responde cambiamos al interno. reqManager.ExecuteQuery(cmd , 0, "pruebaConexion", 750) 'request con timeout corto en ms. DBRChecked = False Do While Not(DBRChecked) ' Esperamos a que termine la prueba de conexion. Sleep(20) Loop End If End Sub Sub CreateNotification (Body As String) As Notification Dim notification As Notification notification.Initialize2(notification.IMPORTANCE_LOW) notification.Icon = "icon" notification.SetInfo("Esperando notificaciones.", Body, Main) Return notification End Sub Sub Service_Destroy nsStatus.Put(Subs.fechaKMT(DateTime.now),"termina") If Starter.notisMap2.IsInitialized Then Starter.notisMap2 = notisMap2 Else Starter.notisMap2.Initialize Starter.notisMap2 = notisMap2 End If If Starter.logger Then LogColor("NotificationService Destroyed, copied notimap2 to starter=" & Starter.notisMap2.Size , Colors.Red) End Sub Sub Bow2_NotificationPosted (SBN As StatusBarNotification) If status = "Servicio Activo" Then If Starter.logger Then LogColor(SBN.PackageName, Colors.Red) '==============================================================================================================' '============================================== Inicia Whatsapp =============================================' '==============================================================================================================' If SBN.PackageName = "com.whatsapp" Or SBN.PackageName = "com.whatsapp.w4b" Then #Region Variables de la notificación ' If starter.Logger Then LogColor("ObjetoNoti:"&SBN,Colors.Blue) ' If starter.Logger Then Log(SBN.Id) 'get Id Notification ' If starter.Logger Then Log("PackageName:" & SBN.PackageName) 'get PackageName Application posted Notification ' If starter.Logger Then LogColor("NotiObject:"&SBN.Notification, Colors.Blue) 'get Notification object ' If starter.Logger Then LogColor("NotiExtras:"&SBN.Extras, Colors.Blue) 'get extras Notification ' If starter.Logger Then Log("NotiIntent:"&SBN.ContentIntent) 'get ContentIntent not used ' If starter.Logger Then Log("NotiKey:"&SBN.Key) 'get Key ' If starter.Logger Then Log("Title:" & SBN.Title) ' If starter.Logger Then Log("Mensaje:"&SBN.Message) ' If starter.Logger Then Log("Ticker:" & SBN.TickerText) ' If starter.Logger Then Log("Numero:" & getNumberWA(SBN)) ' If starter.Logger Then Log("Nombre persona:" & getPersonFromGroup(SBN.Title)) #end region If SBN.PackageName == "com.whatsapp" Or SBN.PackageName = "com.whatsapp.w4b" Then If Starter.logger Then Log("Llega WA Notificacion = " & SBN.Title & " - " & SBN.Message) Dim whatsappkey As String = SBN.Key If Starter.logger Then Log(SBN.key) Dim ww() As String = Regex.Split("\|", whatsappkey) If ww(3) <> "null" Then Subs.guardaNotificacion(SBN)'Aqui guardamos en un mapa las notificaciones y posteriormente poder mandar notificacion a esos números. ' Starter.colaNotifs.ExecNonQuery($"insert into cola (numero, contestada, timestamp) values ('${getNumberWA(SBN)}', 0, ${DateTime.Now})"$) ' If starter.Logger Then Log(notisMap2) ' If starter.Logger Then Log(notificacionesPorContestar) #Region Grupo o persona ' If starter.Logger Then LogColor("isGroupWA: "&isGroupWA2(SBN.Title),Colors.Magenta) ' If starter.Logger Then LogColor("isGroupWA2: "&isGroupWA(SBN),Colors.Magenta) ' If starter.Logger Then LogColor("isPersonWA: "&isPersonWA(SBN),Colors.Magenta) ' If starter.Logger Then LogColor("isPersonWA2 :"&isPersonWA2(SBN),Colors.Magenta) ' If starter.Logger Then LogColor("getPersonFromGroup: "& getPersonFromGroup(SBN.Title) ,Colors.Magenta) ' If starter.Logger Then LogColor("groupName: "& getGroupName(SBN.Title) ,Colors.Magenta) ' If starter.Logger Then LogColor("groupName2: "& getGroupName2(SBN) ,Colors.Magenta) ' If starter.Logger Then LogColor("getNumberOrGroupWA: "& getNumberOrGroupWA(SBN) ,Colors.Magenta) ' If starter.Logger Then LogColor("getNumberWA: "& getNumberWA(SBN) ,Colors.Magenta) ' If starter.Logger Then LogColor("getShortcut: "& getShortcut(SBN) ,Colors.Magenta) ' If starter.Logger Then LogColor("mapReglas="&mapReglas, Colors.Magenta) #End Region Try 'A veces el sistema finaliza la aplicación, el servicio continua interceptando notificaciones, pero la lista de notificaciones recibidas ya no se actualiza. CallSubDelayed(B4XPages.MainPage, "llenaLV") 'Poblamos el listview con las notificaciones recibidas. Catch LogColor(LastException, Colors.red) End Try End If procesaColaDeNotificaciones End If #Region Codigo para Whatsapp Bussiness - Deshabilitado ' If SBN.PackageName == "com.whatsapp.w4b" Then ' Dim whatsappkey As String = SBN.Key ' Dim ww() As String = Regex.Split("\|", whatsappkey) ' If ww(3) <> "null" Then ' 'rp.ClearNotification(SBN) ' rp.reply(SBN.Notification, SBN.PackageName, "Reply HelloWorld WhatsApp-Business") ' Log("Reply Whatsapp Success") ' End If ' End If #end region End If End If End Sub 'Modo simple de regex que permite poner un * para significar cualquier cadena y // para significar OR. Sub regexSimple(cadenaOriginal As String) As String cadenaOriginal = Regex.Replace("\*", cadenaOriginal, "\.\*") cadenaOriginal = Regex.Replace("\/\/", cadenaOriginal, "\|") ' If starter.Logger Then Log(cadenaOriginal) Return cadenaOriginal End Sub 'Regresa "verdadero" si el el texto "aBuscar" existe en el texto "sbnMensaje", se pueden 'agregar * para significar cualquier cadena y // para significar OR. 'Ej. coincideRegexSimple("*hola*//*buenas*", "Hola, como estas") = verdadero ' coincideRegexSimple("*hola*//*buenas*", "Buenas tardes") = verdadero Sub coincideRegexSimple(aBuscar As String, sbnMensaje As String) As Boolean ' If starter.Logger Then Log(sbnMensaje) Private x As Boolean Dim sbnMensaje As String = Regex.Replace("[\r?\n|\r]",sbnMensaje," ") 'Sustituimos los "retornos" por un espacio porque si tiene retornos el mensaje la busqueda no va a coinicidir. ' If starter.Logger Then Log($"|${aBuscar}|${sbnMensaje}|"$) x = Regex.IsMatch2(regexSimple(aBuscar), Regex.CASE_INSENSITIVE, sbnMensaje) If aBuscar = "%solo_numeros%" Then x = Regex.IsMatch("\d+", sbnMensaje) 'Solo acepta numeros en la respuesta. If aBuscar = "%solo_correos%" Then x = Regex.IsMatch("([a-zA-Z0-9]+[_a-zA-Z0-9\.-]*[a-zA-Z0-9]+)@([a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*\.[a-zA-Z]{2,12})", sbnMensaje) 'Solo acepta direcciones de correo en la respuesta. If aBuscar = "%solo_urls%" Then x = Regex.IsMatch("^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \?=.-]*)\/?$", sbnMensaje) 'Solo acepta URLs en la respuesta. Return x End Sub 'Returns TRUE if the sender is a GROUP. 'Searches the provided sbn.title for the string ": " to know if the sender is a group. Sub isGroupWA2(sbnTitle As String) As Boolean 'ignore Private x As Boolean = Regex.ismatch(".*(: ).*", sbnTitle) Return x End Sub 'Returns TRUE if the sender is a GROUP. 'Searches the provided notification object for the string "@g.us" and if found returns TRUE. Sub isGroupWA(sbn As StatusBarNotification) As Boolean Private a As Boolean = False If sbn.As(String).IndexOf("@g.us") > -1 Then a = True 'ignore Return a End Sub 'Returns TRUE if the sender is a PERSON. 'Searches the provided notification object for the string "@s.whatsapp.net" and if found returns TRUE. Sub isPersonWA(sbn As StatusBarNotification) As Boolean 'ignore Private a As Boolean = False If sbn.As(String).IndexOf("@s.whatsapp.net") > -1 Then a = True 'ignore Return a End Sub 'Returns TRUE if the sender is a PERSON. 'Searches the provided notification object for the string "channel=individual" and if found returns TRUE. Sub isPersonWA2(sbn As StatusBarNotification) As Boolean 'ignore Private a As Boolean = False If sbn.As(String).IndexOf("channel=individual") > -1 Then a = True 'ignore Return a End Sub 'Returns the sender's number. 'Searches the provided notification object and gets the numbers between "shortcut=" and "@s.whatsapp.net". Sub getNumberWA(sbn As StatusBarNotification) As String Private a As Int = sbn.As(String).IndexOf("@s.whatsapp.net") 'ignore If a > -1 Then Private x As String = sbn.As(String) 'ignore Private y As Int = x.IndexOf("shortcut=") If (y+9) > 0 And a > (y+9) Then x = x.SubString2(y+9, a) Else x = "Not a person" Else 'It is probably is a group. x = "Not a person" End If Return x End Sub 'Returns the name of the group from the given text. 'If it is not a group, then returns the notification's title. Sub getGroupName(sbnTitle As String) As String 'ignore Private a As Int = sbnTitle.IndexOf(": ") Private x As String = sbnTitle If a > -1 Then Private b As String = sbnTitle.SubString2(0, a) x = Regex.Replace(" \(.+\)", b, "") End If Return x End Sub 'Returns the name of the group from the given notification object. 'Searches the provided notification for the string "hiddenConversationTitle" and if found, gets the name. 'If it is not a group,then it returns the notification's title. Sub getGroupName2(sbn As StatusBarNotification) As String Private inicio As Int = sbn.Extras.As(String).IndexOf("hiddenConversationTitle=") 'ignore If inicio > -1 And sbn.Extras.As(String).IndexOf("hiddenConversationTitle=null") = -1 Then 'ignore Private x As String = sbn.Extras.As(String) 'ignore Private fin As Int = x.IndexOf(", android.reduced.images=") x = x.SubString2(inicio+24, fin) x = Regex.Replace(" \(.+\)", x, "") 'Replace anything between () with "", this en the case that we have something like "MyGroupName (5 messages)" Else 'Is not from a group. Private x As String = sbn.Title End If Return x End Sub 'Returns the person's name (or the number) when the message comes from a group. 'Searches the provided sbn.title for the string ": " in the title and returns the string after that, 'if it does not find ": " then returns the complete string. Sub getPersonFromGroup(sbnTitle As String) As String 'ignore Private a As Int = sbnTitle.IndexOf(": ") If a = -1 Then a = -2 'Is not from a group. Private b As String = sbnTitle.SubString(a+2) Return b End Sub 'Returns the NUMBER of the sender and if NOT a person, then returns the name of the group. Sub getNumberOrGroupWA(sbn As StatusBarNotification) As String Private numRemitente As String = getNumberWA(sbn) If numRemitente = "Not a person" Then numRemitente = getGroupName(sbn.Title) Return numRemitente End Sub 'Desbloquea el usuario de Guna especificado usando JRDC. Sub desbloqueaUsuario(sbn As StatusBarNotification) 'ignore Private elNumero As String = getNumberWA(sbn) If elNumero = "Not a person" Then elNumero = getGroupName(sbn.Title) agregaNotiParaJobDone(sbn) cmd.Initialize cmd.Name = "update_usuario_guna_nobajas" Dim tempUsr As String = sbn.Message ' Dim tempUsr As String = "cdaza" If Starter.logger Then LogColor("Usuario a desbloquear="&tempUsr, Colors.Green) cmd.Parameters = Array As Object(tempUsr.ToUpperCase.Trim) 'Quitamos espacios de antes y despues y lo mandamos en mayúsculas. reqManager.ExecuteCommand(cmd , $"desbloqueaUsuario_${elNumero}"$) If Starter.logger Then Log("Mandamos DBRequest desbloqueo: " & tempUsr) End Sub 'Trae los datos del cliente especificado de Guna usando JRDC. Sub revisaCliente(sbn As StatusBarNotification) 'ignore Private elNumero As String = getNumberWA(sbn) ' If elNumero = "Not a person" Then elNumero = getGroupName(sbn.Title) agregaNotiParaJobDone(sbn) If Starter.logger Then Log("Buscamos cliente "&sbn.Message) cmd.Initialize cmd.Name = "select_cliente_GUNA" Dim tempUsr As String = sbn.Message If Starter.logger Then LogColor("Cliente="&tempUsr, Colors.Green) cmd.Parameters = Array As Object(tempUsr.ToUpperCase.Trim) 'Quitamos espacios de antes y despues y lo mandamos en mayúsculas. reqManager.ExecuteQuery(cmd, 0 , $"traeCliente_${elNumero}"$, 0) If Starter.logger Then Log("Mandamos DBRequest traeCliente: " & tempUsr) End Sub 'Revisa si el cliente especificado existe en Guna. Sub revisacliente2(sbn As StatusBarNotification) Private elNumero As String = getNumberWA(sbn) agregaNotiParaJobDone(sbn) If Starter.Logger Then Log("Buscamos cliente "&sbn.Message) cmd.Initialize cmd.Name = "select_revisacliente_GUNA" Dim tempUsr As String = sbn.Message If Starter.logger Then LogColor("Cliente="&tempUsr, Colors.Green) cmd.Parameters = Array As Object(tempUsr.ToUpperCase.Trim) 'Quitamos espacios de antes y despues y lo mandamos en mayúsculas. reqManager.ExecuteQuery(cmd, 0 , $"revisaCliente_${elNumero}"$, 0) If Starter.logger Then Log("Mandamos DBRequest revisaCliente: " & tempUsr) End Sub 'Guarda los datos de la promoción de la gallina en Guna. Sub guardaInfoGallina(sbn As StatusBarNotification) If Starter.logger Then LogColor("================= INFO GALLINA ============", Colors.Red) Private elNumero As String = getNumberWA(sbn) agregaNotiParaJobDone(sbn) Dim preventa As String = sbn.Message ' If starter.Logger Then Log(procesaRemplazos($"%msj_ant_03G.1_0%|%msj_ant_03G.1.1_0%"$, traeNotificacion(elNumero))) Private paramss() As String=Regex.Split("\|", procesaRemplazos($"%msj_ant_03G.1_0%|%msj_ant_03G.1.1_0%"$, traeNotificacion(elNumero))) If Starter.logger Then LogColor($"${elNumero}, ${paramss(0)}, ${paramss(0)}, ${preventa}"$, Colors.green) cmd.Initialize cmd.Name = "insert_registroGallina_GUNA" cmd.Parameters = Array As Object(elNumero, paramss(0), paramss(0), preventa) reqManager.ExecuteCommand(cmd, $"guardaInfoGallina_${elNumero}"$) If Starter.logger Then Log("Mandamos DBRequest guardaInfoGallina_: " & elNumero) End Sub 'Agregamos la notificacion a un mapa para una vez que tengamos el jobDone poder mandar un mensaje especificado. Sub agregaNotiParaJobDone(sbn As StatusBarNotification) Dim n As notificacionesGuardadasType n.Initialize n.numero = getNumberWA(sbn) n.notif = sbn Dim titulo As String = getNumberWA(sbn) If isGroupWA(sbn) Then titulo = getGroupName2(sbn) Private tmpMap As Map tmpMap.Initialize tmpMap.Put(titulo, n) tmpMap.Put("msg", sbn.Message) notificacionesGuardadas.Put(titulo, tmpMap) ' If starter.Logger Then Log($"Mapa notificacionesGuardadas=${notificacionesGuardadas}"$) End Sub Sub JobDone(Job As HttpJob) 'ignore If Starter.Logger Then LogColor("jobDone: " & Job.Tag, Colors.Magenta) If Job.Success = False Then If Starter.Logger Then LogColor("***** jobDone Error *****", Colors.Red) If Starter.Logger Then LogColor(Job.ErrorMessage, Colors.Red) If Job.Tag = "pruebaConexion" Then 'And Job.ErrorMessage.IndexOf("Failed to connect to ") = -1 B4XPages.MainPage.Timer1.Interval = (20 * 1000) Private cd1 As ColorDrawable cd1.Initialize(Colors.red, 10dip) B4XPages.MainPage.b_config.Background = cd1 B4XPages.MainPage.b_config.text = "Desconectado" If Starter.DBRServer == "http://10.0.0.205:1782" Then Starter.DBRServer = "http://keymon.lat:1782" Else Starter.DBRServer = "http://10.0.0.205:1782" End If ' DBRServer = "http://11.0.0.231:1783" 'Para pruebas locales reqManager.Initialize(Me, Starter.DBRServer) pruebaPaso = pruebaPaso + 1 ' Toast("Cambiando a servidor interno. 🕵🏼", 0) ' ToastMessageShow("Cambiando a servidor interno. 🕵🏼", False) If Starter.logger Then Log($"PruebaPaso = ${pruebaPaso}"$) If Starter.Logger Then LogColor("Reintentando conexion: " & Starter.DBRServer, Colors.RGB(255,123,0)) ToastMessageShow("Reintentando conexion: " & Starter.DBRServer, False) If pruebaPaso < 2 Then If Starter.Logger Then Log("Reintentamos conexión con servidor nuevo.") cmd.Initialize cmd.Name = "select_soporte" 'Reintentamos conexión. reqManager.ExecuteQuery(cmd , 0, "pruebaConexion", 0) End If If Starter.Logger Then LogColor("Servidor actual: " & Starter.DBRServer, Colors.Magenta) End If Else If Starter.Logger Then LogColor("JobDone: '" & reqManager.HandleJob(Job).tag & "' - Registros: " & reqManager.HandleJob(Job).Rows.Size, Colors.Green) 'Mod por CHV - 211027 If Job.JobName = "DBRequest" Then 'Para desbloquear un usuario Guna. Dim result As DBResult = reqManager.HandleJob(Job) If Starter.logger Then Log("******************************************************") If Starter.logger Then Log($"************ ${result.Tag} ***********"$) If Starter.logger Then Log("******************************************************") If result.Tag = "pruebaConexion" Then If Starter.logger Then Log($"${Starter.ultimoServidorConectado}+${Starter.DBRServer} "$) If Starter.logger Then LogColor("Servidor actual: " & Starter.DBRServer, Colors.Magenta) If Starter.ultimoServidorConectado <> Starter.DBRServer Then ToastMessageShow($"Conexión establecida${CRLF}${Starter.DBRServer}"$, False) Else ToastMessageShow($"OK"$, False) End If Starter.ultimoServidorConectado = Starter.DBRServer Private cd1 As ColorDrawable cd1.Initialize(Colors.RGB(109, 221, 101), 10dip) B4XPages.MainPage.b_config.Background = cd1 B4XPages.MainPage.b_config.text = "Conectado" B4XPages.MainPage.Timer1.Interval = (120 * 1000) ' For Each records() As Object In result.Rows ' If starter.Logger Then Log("========================= ") ' For Each k As String In result.Columns.Keys ' If starter.Logger Then LogColor(result.Tag & ": " & k & "=" & records(result.Columns.Get(k)), Colors.blue) ' Next ' Next End If If result.Tag.As(String).IndexOf("desbloqueaUsuario_") > -1 Then 'query tag For Each records() As Object In result.Rows Private num As String = result.Tag num = num.SubString(num.IndexOf("_")+1) Private usr As String = notificacionesGuardadas.Get(num).As(Map).Get("msg") If Starter.Logger Then Log("========================= "&usr) If records(result.Columns.Get("AffectedRows")) > 0 Then If Starter.Logger Then Log("Usuario desbloqueado! 🔓") mandaRespuesta(num, $"Usuario *${usr.ToUpperCase}* desbloqueado, por favor cerrar navegadores y reingresar."$) Else If Starter.Logger Then Log("Usuario no encontrado!!") mandaRespuesta(num, $"El usuario *${usr.ToUpperCase} no existe* o esta dado de *baja*, por favor revisarlo y volver a intentar."$) End If ' If starter.Logger Then Log( result.Tag & " | " & num) ' If starter.Logger Then Log(Starter.desbloqueoUsrs) ' For Each k As String In result.Columns.Keys ' If starter.Logger Then Log(result.Tag & ": " & k & ": " & records(result.Columns.Get(k))) ' Next Next End If If result.Tag.As(String).IndexOf("traeCliente_") > -1 Then 'query tag Private num As String = result.Tag num = num.SubString(num.IndexOf("_")+1) If Starter.Logger Then Log(num) For Each records() As Object In result.Rows If Starter.Logger Then Log("========================= "&usr) If Starter.Logger Then Log("Cliente encontrado!") For Each k As String In result.Columns.Keys If Starter.logger Then LogColor(result.Tag & ": " & k & ": " & records(result.Columns.Get(k)), Colors.blue) Next Private cod As String = records(result.Columns.Get("CAT_CL_CODIGO")) Private nombre As String = records(result.Columns.Get("CAT_CL_NOMBRE")) Private calle As String = records(result.Columns.Get("CAT_CL_CALLE")) Private noInt As String = records(result.Columns.Get("CAT_CL_NOINT")) Private noExt As String = records(result.Columns.Get("CAT_CL_NOEXT")) Private msj As String = $"*Cliente:* ${cod}${CRLF}*Tienda:* ${nombre}${CRLF}*Calle:* ${calle}${CRLF}*No. Int:* ${noInt}${CRLF}*No. Ext:* ${noExt}"$ mandaRespuesta(num, msj) mandaRespuesta(num, "Por favor dame el nombre del encargado de la tienda.") Next If starter.Logger Then Log(result.Rows.Size) If result.Rows.Size = 0 Then If Starter.Logger Then Log("Cliente no encontrado!!") mandaRespuesta(num, $"*No se encontró el cliente en nuestros registros*, por favor validar la información y volver a intentar."$) End If End If If result.Tag.As(String).IndexOf("revisaCliente_") > -1 Then 'query tag Private num As String = result.Tag num = num.SubString(num.IndexOf("_")+1) If Starter.Logger Then Log(num) For Each records() As Object In result.Rows If Starter.Logger Then Log("========================= "&usr) For Each k As String In result.Columns.Keys If Starter.logger Then LogColor(result.Tag & ": " & k & "=" & records(result.Columns.Get(k)), Colors.blue) Next Next If records(result.Columns.Get("CUANTOS")) = "0" Then If Starter.Logger Then Log("No existe el usuario") mandaRespuesta(num, $"*No existe* ese número de cliente, por favor ingresa el número correcto."$) Subs.vamosA(traeNotificacion(num), "03G") Else mandaRespuesta(num, "Gracias, ahora por favor el número del preventa.") ' Subs.vamosA(traeNotificacion(num), "03G.1") End If If Starter.Logger Then Log(result.Rows.Size) End If If result.Tag.As(String).IndexOf("guardaInfoGallina_") > -1 Then 'query tag Private num As String = result.Tag num = num.SubString(num.IndexOf("_")+1) If Starter.Logger Then Log(num) For Each records() As Object In result.Rows If Starter.Logger Then Log("========================= "&usr) For Each k As String In result.Columns.Keys If Starter.logger Then LogColor(result.Tag & ": " & k & "=" & records(result.Columns.Get(k)), Colors.blue) Next Next ' If starter.Logger Then Log("|"&records(result.Columns.Get("AffectedRows"))&"|") If records(result.Columns.Get("AffectedRows")) = 1 Then Private msj As String = procesaRemplazos($"Muchas gracias.${CRLF}Quedas registrado con:${CRLF}*Cliente:* %msj_ant_03G.1_0%${CRLF}*Preventa:* %msj%"$, traeNotificacion(num)) mandaRespuesta(num, msj) Else mandaRespuesta(num, "*¡Hubo un error, por favor intenta de nuevo!*") End If If Starter.Logger Then Log(result.Rows.Size) End If If result.Tag.As(String).IndexOf("procRecuperaClientes_") > -1 Then 'query tag Private num As String = result.Tag num = num.SubString(num.IndexOf("_")+1) If Starter.Logger Then Log(num) For Each records() As Object In result.Rows If Starter.Logger Then Log("========================= "&usr) For Each k As String In result.Columns.Keys If Starter.logger Then LogColor(result.Tag & ": " & k & "=" & records(result.Columns.Get(k)), Colors.blue) Next Next If records(result.Columns.Get("AffectedRows")) = 1 Then mandaRespuesta(num, procesaRemplazos("Listos, clientes de %msj% recuperados", traeNotificacion(num))) End If ' If starter.Logger Then Log("|"&records(result.Columns.Get("AffectedRows"))&"|") ' If records(result.Columns.Get("AffectedRows")) = 1 Then ' Private msj As String = procesaRemplazos($"Muchas gracias.${CRLF}Quedas registrado con:${CRLF}*Cliente:* %msj_ant_03G.1_0%${CRLF}*Preventa:* %msj%"$, traeNotificacion(num)) ' mandaRespuesta(num, msj) ' Else ' mandaRespuesta(num, "*¡Hubo un error, por favor intenta de nuevo!*") ' End If If Starter.Logger Then Log(result.Rows.Size) End If End If Job.Release End If End Sub 'Muestra un toast con texto y ancho dados, si el ancho es 0, entonces se queda el default. Sub Toast(texto As String, ancho As Int) 'ignore ' p_toast.BringToFront ' If ancho <> 0 Then p_toast.Width = ancho ' p_toast.left = (Activity.Width/2)-(p_toast.Width/2) 'Centramos el panel en la actividad. ' l_toast.Width = p_toast.Width ' p_toast.top = (Activity.Height * 0.8) 'Ponemos el toast a 3/4 de la pantalla. ' l_toast.Text = texto ' p_toast.SetVisibleAnimated(1000, True) ' Sleep(2000) ' p_toast.SetVisibleAnimated(1000, False) End Sub 'Manda un notificacion al numero indicado con el mensaje especificado. 'Nota: El número especificado debe de existir en el mapa de notificaciones guardadas (notificacionesGuardadas). Sub mandaRespuesta(numero As String, mensaje As String) If Starter.logger Then Log("Busco: "& numero & " hay: " & notificacionesGuardadas) If Starter.logger Then Log(notificacionesGuardadas) Private tm As Map = notificacionesGuardadas.Get(numero) If tm.IsInitialized Then Dim t1 As notificacionesGuardadasType = tm.Get(numero) Dim t2 As StatusBarNotification = t1.notif If Starter.logger Then LogColor("Mandamos respuesta", Colors.red) If t2.IsInitialized Then rp.reply(t2.Notification, t2.PackageName, mensaje) guardaMsjSalida(t2, mensaje) End If Else ' ToastMessageShow("No hay notificaciones de xxxxxxxx", False) If Starter.logger Then Log("No hay notificación para ese número.") End If End Sub 'Ejecuta la subrutina especificada. Sub correSub(comando As String, sbn As StatusBarNotification) Private c As String = comando c = c.SubString(c.IndexOf(" ")+1) If Starter.logger Then Log(c) If SubExists(Me, c) Then CallSubDelayed2(Me, c, sbn) End Sub Sub muestraHistorico(sbn As StatusBarNotification) 'ignore If Starter.logger Then Log("Corriendo muestraHistorico") Private tmpMap As Map Private tmpList As List Private n As String = getNumberWA(sbn) If n = "Not a person" Then n = getGroupName(sbn.Title) Private s As String = "" If Starter.logger Then Log(n) tmpMap = histReglas.Get(n) If Starter.logger Then Log(tmpMap) If tmpMap.ContainsKey("historico") Then tmpList = tmpMap.Get("historico") For i = tmpList.Size -1 To 0 Step -1 ' If starter.Logger Then Log(i & ".- " & tmpList.Get(i).As(Map).Get("mensaje")) s = s & CRLF s = s & tmpList.Get(i).As(Map).Get("mensaje") Next ' If starter.Logger Then Log(s) mandaRespuesta(n, s) End Sub 'Regresa verdadero si la regla es dependiente (subRegla) de otra regla. 'Recibe un mapa con las reglas. Sub esDependiente(m As Map)As Boolean Private d As Boolean = False If m.Get("nombre").As(String).IndexOf(".") > -1 Then d = True Return d End Sub 'Regresa el nombre de la regla superior. 'Recibe un mapa con las reglas. Sub traeSuperior(m As Map) As String Dim i As Int Dim s As String = "" If m.Get("nombre").As(String).LastIndexOf(".") > -1 Then i = m.Get("nombre").As(String).LastIndexOf(".") ' If starter.Logger Then Log(i) s = m.Get("nombre").As(String).SubString2(0, i) ' If starter.Logger Then Log(s) End If Return s End Sub 'Regresa el id de la ultima regla cumplida. Sub ultimaRegla As String Dim ultReg As String = "" If histReglas.get(numRemitente).As(Map).IsInitialized Then ultReg = histReglas.get(numRemitente).As(Map).Get("histReglas").As(List).Get(0) Return ultReg End Sub 'Regresa el mensaje especificado dentro de las reglas anteriores cumplidas. 'regla: El nombre de la regla de la que queremos el mensaje. 'reglasAtras: Que mensaje queremos traer, 0 para el último, 1 para el penúltimo, 2 para el antepenúltimo, etc. Sub mensajeAnterior(regla As String, reglasAtras As Int) As String Dim msjAnterior As String = "" If reglasAtras = 0 Then reglasAtras = 1 If histReglas.get(numRemitente).As(Map).IsInitialized And _ histReglas.get(numRemitente).As(Map).Get("historico").As(List).Size >= reglasAtras Then Private hist As List = histReglas.get(numRemitente).As(Map).Get("historico") ' If starter.Logger Then Log(hist) If regla <> "0" Then 'Si se especifica una regla, entonces filtramos y solo usamos el historico de esa regla. Private h As List h.Initialize For Each h2 As Map In hist If h2.Get("regla") = regla Then h.Add(h2) ' If starter.Logger Then Log(regla & "|" & h2) End If Next hist = h ' If starter.Logger Then Log(h) End If ' If starter.Logger Then Log($"size:${hist.Size}, reglaAtras:${reglasAtras}"$) If hist.Size >= reglasAtras Then msjAnterior = hist.Get(reglasAtras-1).As(Map).Get("mensaje") End If Return msjAnterior End Sub 'Regresa el "shortcut" del remitente. 'Si es de un grupo, es algo como "120363023512345678@g.us" 'Si es de una persona, entonces "5215512345678@s.whatsapp.net" Sub getShortcut(sbn As StatusBarNotification) As String 'ignore Private ap As Int = sbn.As(String).IndexOf("@s.whatsapp.net") 'ignore Private ag As Int = sbn.As(String).IndexOf("@g.us") 'ignore Private x As String = sbn.As(String) 'ignore Private y As Int = x.IndexOf("shortcut=") If ap > -1 Then Private x As String = sbn.As(String) 'ignore Private y As Int = x.IndexOf("shortcut=") x = x.SubString2(y+9, ap+15) Else if ag > -1 Then 'It is probably is a group. Private x As String = sbn.As(String) 'ignore Private y As Int = x.IndexOf("shortcut=") x = x.SubString2(y+9, ag+5) End If Return x End Sub 'Reemplaza texto en la respuesta con variables predefinidas. Sub procesaRemplazos(msjStr As String, sbn As StatusBarNotification) As String If Starter.logger Then Log("Procesamos reemplazos '"& msjStr & "'") Dim Matcher1 As Matcher Matcher1 = Regex.Matcher("%[a-z A-Z_0-9,\.\uD83C-\uDBFF\uDC00-\uDFFF\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff]]+%", msjStr) Do While Matcher1.Find If Starter.logger Then Log("Found: " &Matcher1.Match) If Matcher1.Match.IndexOf("msj_ant_") > -1 Then 'Reemplaza el texto "%msj_ant_0_1%" por mensajes anteriores segun el desplazamiento y la regla especificados. Private offs As String = Matcher1.Match.IndexOf("_") Dim offs2() As String = Regex.Split("_", Matcher1.Match) If Starter.logger Then Log(offs2.Length) If offs2.Length = 4 Then 'Solo procesamos el reemplazo si tiene 4 parametros. Private offs As String = offs2(offs2.Length-1) 'El desplazamiento para el mensaje (cuantos mensaje hacia atras vamos a traer) Private rulz As String = offs2(offs2.Length-2) 'La regla a usar para traer el mensaje. offs = offs.SubString2(0, offs.Length-1) If Starter.logger Then Log("################### "& rulz & "|" & offs) msjStr = msjStr.Replace(Matcher1.Match, mensajeAnterior(rulz, offs)) ' If starter.Logger Then Log(Matcher1.Match) ' If starter.Logger Then Log("==== msjAnt - " & msjStr) End If else If Matcher1.Match.IndexOf("%msj%") > -1 Then 'Reemplaza el texto "%msj%" con el mensaje recibido. msjStr = msjStr.Replace(Matcher1.Match, sbn.Message) else if Matcher1.Match.IndexOf("%nombre%") > -1 Then 'Reemplaza el texto "%nombre%" por el nombre completo (o numero si no esta en los contactos) del remitente. Private pn As String = sbn.Title If isGroupWA(sbn) Then pn = getPersonFromGroup(sbn.Title) msjStr = msjStr.Replace(Matcher1.Match, pn) else if Matcher1.Match.IndexOf("%primer_nombre%") > -1 Then 'Reemplaza el texto "%primerNombre%" por el nombre (hasta el primer espacio) o numero (si no esta en los contactos) del remitente. Private pn As String = sbn.Title If isGroupWA(sbn) Then pn = getPersonFromGroup(sbn.Title) If Starter.logger Then Log(pn) If Not(pn.StartsWith("+")) Then pn = Regex.Split(" ", pn)(0) msjStr = msjStr.Replace(Matcher1.Match, pn) else If Matcher1.Match.IndexOf("goto_") > -1 Then 'Manda el procesamiento de la siguiente regla a la regla especificada. Private offs As String = Matcher1.Match.IndexOf("_") offs = Matcher1.Match.SubString2(offs+1, Matcher1.Match.Length-1) Subs.vamosA(sbn, offs) msjStr = msjStr.Replace(Matcher1.Match, "") ' If starter.Logger Then Log(Matcher1.Match) ' If starter.Logger Then Log("==== goto: " & offs) else If Matcher1.Match.IndexOf("rnd_") > -1 Then 'Remplaza %rnd_1,b,A,5% por una opcion al azar de las especificadas. Private offs As String = Matcher1.Match.IndexOf("_") offs = Matcher1.Match.SubString2(offs+1, Matcher1.Match.Length-1) Private x() As String = Regex.Split(",", offs) Private rando As Int = 0 ' Por si solo hay un elemento en la lista. If x.Length > 1 Then rando = Rnd(0, x.Length) If Starter.logger Then LogColor($"Random: 0-${x.Length-1} ${x(rando)} "$, Colors.Magenta) msjStr = msjStr.Replace(Matcher1.Match, x(rando)) else If Matcher1.Match.IndexOf("espera2_") > -1 Then 'Genera el tiempo de espera especificado en ms antes de mandar la respuesta. Private offs As String = Matcher1.Match.IndexOf("_") offs = Matcher1.Match.SubString2(offs+1, Matcher1.Match.Length-1) espera = offs msjStr = msjStr.Replace(Matcher1.Match, "") else If Matcher1.Match.IndexOf("espera_") > -1 Then 'Genera el tiempo de espera al azar entre el minimo y maximo especificados en segundos antes de mandar la respuesta. ' Private offs As String = Matcher1.Match.IndexOf("_") Dim params() As String = Regex.Split("_", Matcher1.Match) If params.Length = 3 Then 'Solo procesamos el reemplazo si tiene 3 parametros. Private minS As String = params(params.Length-2) 'Los segundos minimos. Private maxS As String = params(params.Length-1) 'Los segundos maximos. maxS = maxS.SubString2(0, maxS.Length-1) 'Quitamos el "%" del final. Private espera2 As Int = Rnd(minS, maxS+1)*1000 If Starter.logger Then LogColor($"min=${minS}, max=${maxS}, espera=${espera2}"$, Colors.red) espera = espera2 msjStr = msjStr.Replace(Matcher1.Match, "") End If End If Loop If Starter.logger Then LogColor("Remplazos completados - " & msjStr, Colors.Green) Return msjStr End Sub 'Toma una lista de posibles respuestas (separadas por //) y regresa solo una al azar. Sub procesaMultiMensajeRandom(mensaje As String) As String Dim x() As String = Regex.Split("//", mensaje) ' For i = 0 To x.Length - 1 ' If starter.Logger Then Log($"len:${x.Length}, ${i}: ${x(i)}"$) ' Next Private rando As Int = 0 ' Por si solo hay un elemento en la lista. If x.Length > 1 Then rando = Rnd(0, x.Length) ' If starter.Logger Then LogColor($"Random: 0-${x.Length-1} ${x(rando).Trim} "$, Colors.Magenta) Return x(rando) End Sub 'Procesa la cola de notificaciones (lista notificacionesPorContestar). Sub procesaColaDeNotificaciones ' If starter.Logger Then LogColor("COLA = " & notificacionesPorContestar.Size, Colors.Green) ' If starter.Logger Then Log(notificacionesPorContestar) ' If starter.Logger Then Log($"${procesandoNotificaciones}, ${notificacionesPorContestar.size}"$) Private hayError As Boolean = False If Not(procesandoNotificaciones) And notificacionesPorContestar.Size > 0 Then If Starter.logger Then Log("iniciamos procesando") procesandoNotificaciones = True ' Private la As Int = 0 ' For i = 0 To notificacionesPorContestar.Size - 1 If notificacionesPorContestar.Get(0) <> "DONE" Then Try Private tempMap As Map = notificacionesPorContestar.Get(0) Private num As String = notificacionesPorContestar.Get(0).As(Map).GetKeyAt(0) Dim t1 As lasNotis = tempMap.Get(num) ' If starter.Logger Then LogColor($"${num} - ${t1.notif.Message}"$, Colors.Blue) ' If starter.Logger Then Log(t1) Dim t2 As StatusBarNotification = t1.notif ' If starter.Logger Then Log(t2) Catch Log(LastException) hayError = True End Try If Not(hayError) Then procesaNotificacion(t2) If Starter.logger Then Log($"${notificacionesPorContestar.Get(0)}, ${notificacionesPorContestar.size}"$) If Starter.logger Then Log("Ponemos 0 en DONE") notificacionesPorContestar.Set(0, "DONE") End If End If ' la = i ' Next ' If starter.Logger Then Log(notificacionesPorContestar.Size) End If If notificacionesPorContestar.Size > 0 Then For i=0 To notificacionesPorContestar.Size-1 'Borramos las notificaciones procesadas de la lista. If notificacionesPorContestar.get(i) = "DONE" Then notificacionesPorContestar.RemoveAt(i) If Starter.logger Then Log("Removemos posicion " & i) End If Next End If ' If starter.Logger Then Log(notificacionesPorContestar) ' If starter.Logger Then LogColor("COLA = " & notificacionesPorContestar.Size, Colors.red) procesandoNotificaciones = False Sleep(1) If notificacionesPorContestar.Size > 0 Then procesaColaDeNotificaciones End Sub 'Procesa la notificación y reglas correspondientes. 'Recibe un objecto SBN (statusBarNotification). Sub procesaNotificacion(sbn As StatusBarNotification) ' Try Private numRemitente As String = getNumberOrGroupWA(sbn) For Each m As Map In mapReglas.Values 'Revisamos si el mensaje dispara alguna regla. ' If starter.Logger Then Log(m) Private destinatarioOk As Boolean = False If m.Get("destinatario") = "Ambos" Then destinatarioOk = True If m.Get("destinatario") = "Grupos" And isGroupWA(sbn) Then destinatarioOk = True If m.Get("destinatario") = "Personas" And isPersonWA(sbn) Then destinatarioOk = True ' If starter.Logger Then Log(m.Get("destinatario") & "|" &"destinatarioOk="&destinatarioOk) ' If starter.Logger Then Log($"Regla: ${m.Get("nombre")}, activa:${m.Get("activa")}, recibe=${m.Get("recibe")}, contesta=${m.Get("contesta")}, mensaje: ${sbn.Message}"$) ' If starter.Logger Then LogColor(m.Get("contactoEspecifico"), Colors.Magenta) ' If starter.Logger Then LogColor($"================ Procesando regla ${m.Get("nombre")} ==========================="$, Colors.Magenta) Private cumpleContactosEspecificos As Boolean = revisaContactosEspecificos(getGroupName(sbn.Title), m.Get("contactoEspecifico")) ' If starter.Logger Then Log(cumpleContactosEspecificos) ' If starter.Logger Then Log("COINCIDE="&coincideRegexSimple(m.Get("recibe"), sbn.Message)) If m.Get("activa") = 1 And destinatarioOk And cumpleContactosEspecificos And coincideRegexSimple(m.Get("recibe"), sbn.Message) Then 'ignore ' If starter.Logger Then Log($"${m.Get("recibe")}, ${sbn.Message}"$) ' If starter.Logger Then LogColor("histReglas="&histReglas, Colors.Blue) Dim esDep As Boolean = esDependiente(m) Dim superior As String = traeSuperior(m) Dim anterior As String = ultimaRegla ' If starter.Logger Then Log("Msg="&sbn.Message&" - Es dependiente="& esDep) ' If starter.Logger Then Log("dep="&esDep&" - regla superior="& superior & " Ultima R=" & anterior) Private msjStr As String If Not(esDep) Or (superior = anterior) Then 'Si no es dependiente, O si es dependiente Y la anterior es de la que dependemos, entonces guardaMsjEntrada(sbn, m.Get("nombre")) ' If starter.Logger Then LogColor($"Regla:${m.Get("nombre")}"$, Colors.Blue) Subs.guardaUltimaRegla(sbn, m.Get("nombre")) ' If starter.Logger Then Log(msjStr) msjStr = procesaMultiMensajeRandom(m.Get("contesta")) ' If starter.Logger Then Log("===================== Mensaje ================="&CRLF& msjStr) If msjStr.IndexOf("&&") > -1 Then 'Si hay respuestas multiples. Private y() As String = Regex.Split("&&", msjStr) For j = 0 To y.Length - 1 espera = 10 msjStr = procesaRemplazos(y(j).Trim, sbn) ' If starter.Logger Then LogColor("ESPERA="&espera, Colors.red) ' If starter.Logger Then LogColor("Reply: " & msjStr, Colors.Blue) Sleep(espera) If y(j).IndexOf("/cmd") > -1 Then 'Si hay que correr un comando ... correSub(msjStr, sbn) Sleep(1500) Else if msjStr <> "" Then If Starter.logger Then LogColor($"Mandamos respuesta (${msjStr})"$, Colors.Blue) rp.reply(sbn.Notification, sbn.PackageName, msjStr) guardaMsjSalida(sbn, msjStr) End If Next Else 'Si SOLO es UNA respuesta ... espera = 10 msjStr = procesaRemplazos(msjStr.Trim, sbn) ' If starter.Logger Then LogColor("ESPERA="&espera, Colors.red) If msjStr.IndexOf("/cmd") > -1 Then 'Si hay que correr un comando ... correSub(msjStr, sbn) Sleep(1500) Else if msjStr <> "" Then Sleep(espera) If Starter.logger Then LogColor($"Mandamos respuesta (${msjStr})"$, Colors.Blue) rp.reply(sbn.Notification, sbn.PackageName, msjStr) guardaMsjSalida(sbn, msjStr) End If End If Private thisP As String = getGroupName(sbn.Title) If Not(notisIds.ContainsKey(thisP)) Then notisIds.Put(thisP, notisIds.Size+1) If Starter.logger Then Log(notisIds.Get(thisP)) If Starter.logger Then Log(notisIds) ' BigText_Notification(sbn, msjStr) 'Retiro temporal Exit 'Si ya encontramos una regla que se cumple, entonces salimos. Else if superior = anterior Then 'Si es regla dependiente y la anterior es de la que dependemos, entonces ... ' If starter.Logger Then LogColor($"Regla anterior=${anterior}${CRLF}Sup:${superior} = anterior:${anterior}${CRLF}Regla anterior es igual a superior - ${msjStr}"$, Colors.green) ' Subs.guardaUltimaRegla(sbn, m.Get("nombre")) ' If starter.Logger Then Log("****************************************************"&CRLF& msjStr) ' msjStr = procesaRemplazos(m.Get("contesta"), sbn) ' If msjStr.IndexOf("&&") > -1 Then 'Si hay respuestas multiples ... ' Private y() As String = Regex.Split("&&", msjStr) ' For j = 0 To y.Length - 1 ' If starter.Logger Then LogColor("Reply: " & y(j), Colors.Blue) ' If y(j).IndexOf("/cmd") > -1 Then 'Si hay que correr un comando ... ' correSub(y(j), sbn) ' Else ' 'LogColor("Mandamos respuesta", Colors.red) ' rp.reply(sbn.Notification, sbn.PackageName, y(j)) ' End If ' Sleep(1200) ' Next ' Else 'Si SOLO es una respuesta ... ' If msjStr.IndexOf("/cmd") > -1 Then 'Si hay que correr un comando ... ' correSub(msjStr, sbn) ' Else ' 'If starter.Logger Then LogColor("Mandamos respuesta", Colors.red) ' rp.reply(sbn.Notification, sbn.PackageName, msjStr) ' End If ' End If ' Exit 'Si ya encontramos una regla que se cumple, entonces salimos. End If End If Next ' Catch ' LogColor(LastException, Colors.red) ' End Try End Sub 'Regresa true o False dependiendo de: 'Si NO hay contactos especificados regresa TRUE. 'Si hay contactos especificados y el remitente esta dentro de ellos regresa TRUE 'Si hay contactos especificados y el remitente NO esta dentro de ellos regresa FALSE Sub revisaContactosEspecificos(contacto As String, contactos As String) As Boolean 'ignore Private result As Boolean = True If contactos <> Null And contactos <> "" And contactos.Length > 3 Then 'Si hay contactos especificados ... ' If starter.Logger Then LogColor("Hay contactos especificados.", Colors.blue) ' If starter.Logger Then Log($"Buscamos ${contacto} en |${contactos}|"$) result = False ' Private contEsp() As String = Regex.Split(",", contactos) ' Private l As List ' l.Initialize ' For i = 0 To contEsp.Length -1 ' l.Add(contEsp(i)) ' Next Private c() As String = Regex.Split(",", contactos) ' If starter.Logger Then Log(c.Length) For i = 0 To c.Length -1 ' Private x As String = c(i).Trim ' Log($"|${x}|"$) If c(i).trim.EqualsIgnoreCase(contacto) Then result = True Exit End If Next ' If contactos.IndexOf(contacto) = -1 Then result = False 'Si el remitente no esta en los contactos permitidos regresamos FALSE. End If ' If starter.Logger Then Log("Resultado = " & result) Return result End Sub 'Guarda en la base de datos en mensaje de entrada. Sub guardaMsjEntrada(sbn As StatusBarNotification, reglaCumplida As String) Private thisP As String = getGroupName(sbn.Title) Private thisN As String = getNumberWA(sbn) If Starter.logger Then LogColor($"Guardamos mensaje de entrada: "${sbn.Message}""$, Colors.Blue) Starter.historicoDB.ExecNonQuery2("insert into historico (numero, nombre, regla, mensaje, E_S, clic, fecha) values (?,?,?, ?, ?, ?, ?)", Array As Object (thisN, thisP, reglaCumplida, sbn.Message, "E", 0, Subs.fechaKMT(DateTime.now))) End Sub 'Guarda en la base de datos en mensaje de salida (respuesta). Sub guardaMsjSalida(sbn As StatusBarNotification, msjStr As String) Private thisP As String = getGroupName(sbn.Title) Private thisN As String = getNumberWA(sbn) If Starter.logger Then Log($"Guardamos "${msjStr}""$) Starter.historicoDB.ExecNonQuery2("insert into historico (numero, nombre, mensaje, E_S, clic, fecha) values (?,?, ?, ?, ?, ?)", Array As Object (thisN, thisP, msjStr, "S", 0, Subs.fechaKMT(DateTime.now))) End Sub Sub getHistNotis(remitente As String) As String Private text, ES As String = "" Private c As ResultSet = Starter.historicoDB.ExecQuery2("select mensaje, E_S from historico where nombre = ? and clic = 0", Array As String(remitente)) If c.RowCount > 0 Then Do While c.NextRow ES = c.GetString("E_S") If ES = "S" Then ES = "↗️ " Else ES = "↘️ " text = text & CRLF & ES & c.GetString("mensaje") Loop End If Return text End Sub 'Trae la notificacion de un numero dado, la notificacion debe estar previamente guardada en el mapa de notificaciones guardadas (notificacionesGuardadas). Sub traeNotificacion(n As String) As StatusBarNotification 'ignore Private tm As Map = notificacionesGuardadas.Get(n) Private tm0 As StatusBarNotification If tm.IsInitialized Then Dim t1 As notificacionesGuardadasType = tm.Get(n) Dim t2 As StatusBarNotification = t1.notif If t2.IsInitialized Then Return t2 Else If Starter.logger Then Log("No hay notificación para ese número.") Return tm0 End If Else If Starter.logger Then Log("No hay notificación para ese número.") Return tm0 End If End Sub Sub NotificationSimple(titulo As String, text As String, id As Int) 'ignore If Starter.logger Then Log($"Titulo=${titulo}, Texto=${text}, id=${id}"$) Dim n As NB6 n.Initialize(titulo, Application.LabelName, "DEFAULT").AutoCancel(True).SmallIcon(B4XPages.MainPage.notiIcon) n.Build(titulo, text, titulo, Main).Notify(id) 'It will be Main (or any other activity) instead of Me if called from a service. End Sub Sub BigText_Notification(sbn As StatusBarNotification, ultimoMsj As String) Dim n As NB6 Private titulo As String = getGroupName(sbn.Title) Private text As String = getHistNotis(titulo).Trim Private id As Int = notisIds.Get(titulo) Private shortcut As String = getShortcut(sbn) If Starter.logger Then Log($"Titulo=${titulo}, Texto=${text}, id=${id}"$) If Not(notisIds.ContainsKey(titulo)) Then notisIds.Put(titulo, notisIds.Size+1) n.Initialize("default", Application.LabelName, "LOW").AutoCancel(True).SmallIcon(B4XPages.MainPage.notiIcon) n.BigTextStyle(titulo, "Chat con " & titulo, text) n.Build(titulo, ultimoMsj, shortcut&"|"&titulo, Main).Notify(id) End Sub Sub revisaConexion If Starter.ultimoServidorConectado = "" Then Starter.ultimoServidorConectado = "http://keymon.lat:1782" reqManager.Initialize(Me, Starter.ultimoServidorConectado) If Starter.logger Then Log($"Intentamos con el servidor ${Starter.ultimoServidorConectado}"$) cmd.Initialize cmd.Name = "select_soporte" 'Intentamos conectarnos al servido publico y si no responde cambiamos al interno. reqManager.ExecuteQuery(cmd , 0, "pruebaConexion", 750) 'request con timeout corto en ms. DBRChecked = False Do While Not(DBRChecked) ' Esperamos a que termine la prueba de conexion. Sleep(20) Loop End Sub Sub recuperaClientes(sbn As StatusBarNotification) 'ignore Private elNumero As String = getNumberWA(sbn) agregaNotiParaJobDone(sbn) cmd.Name = "proc_recuperaClientesNuevos" cmd.Parameters = Array As Object("6","101","CHATBOT") reqManager.ExecuteCommand(cmd ,$"procRecuperaClientes_${elNumero}"$) If Starter.logger Then Log("Mandamos DBRequest procRecuperaClientes_: " & elNumero) End Sub